Version in base suite: 131.0.6778.139-1~deb12u1 Version in overlay suite: 134.0.6998.35-1~deb12u1 Base version: chromium_134.0.6998.35-1~deb12u1 Target version: chromium_134.0.6998.88-1~deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/c/chromium/chromium_134.0.6998.35-1~deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/c/chromium/chromium_134.0.6998.88-1~deb12u1.dsc /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android FYI Release (Pixel 6)/properties.json | 4 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android Release (Pixel 2)/properties.json | 2 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView O (dbg)/properties.json | 4 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView P (dbg)/properties.json | 4 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm Builder (dbg)/properties.json | 2 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder (dbg)/properties.json | 10 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder All Targets (dbg)/properties.json | 2 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x64 Builder All Targets (dbg)/properties.json | 2 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x86 Builder (dbg)/properties.json | 2 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.json | 4 /srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Oreo Phone Tester/properties.json | 4 chromium-134.0.6998.88/DEPS | 12 chromium-134.0.6998.88/ash/accessibility/a11y_feature_type.h | 1 chromium-134.0.6998.88/ash/accessibility/accessibility_controller.cc | 73 chromium-134.0.6998.88/ash/accessibility/accessibility_controller.h | 9 chromium-134.0.6998.88/ash/accessibility/accessibility_controller_unittest.cc | 29 chromium-134.0.6998.88/ash/birch/birch_coral_provider.cc | 19 chromium-134.0.6998.88/ash/constants/ash_pref_names.h | 5 chromium-134.0.6998.88/ash/strings/ash_strings_es.xtb | 2 chromium-134.0.6998.88/ash/strings/ash_strings_sr-Latn.xtb | 2 chromium-134.0.6998.88/ash/strings/ash_strings_sr.xtb | 2 chromium-134.0.6998.88/ash/strings/ash_strings_uk.xtb | 2 chromium-134.0.6998.88/ash/strings/ash_strings_vi.xtb | 2 chromium-134.0.6998.88/ash/style/tab_slider_button.cc | 23 chromium-134.0.6998.88/ash/style/tab_slider_button.h | 4 chromium-134.0.6998.88/ash/webui/camera_app_ui/resources/strings/camera_strings_vi.xtb | 2 chromium-134.0.6998.88/build/util/LASTCHANGE | 2 chromium-134.0.6998.88/build/util/LASTCHANGE.committime | 2 chromium-134.0.6998.88/chrome/VERSION | 2 chromium-134.0.6998.88/chrome/app/chrome_exe_main_mac.cc | 2 chromium-134.0.6998.88/chrome/app/resources/chromium_strings_ky.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_ar.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_ca.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_es.xtb | 4 chromium-134.0.6998.88/chrome/app/resources/generated_resources_et.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_fa.xtb | 100 chromium-134.0.6998.88/chrome/app/resources/generated_resources_fr-CA.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_hi.xtb | 6 chromium-134.0.6998.88/chrome/app/resources/generated_resources_id.xtb | 4 chromium-134.0.6998.88/chrome/app/resources/generated_resources_ky.xtb | 20 chromium-134.0.6998.88/chrome/app/resources/generated_resources_ne.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_pt-PT.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_ru.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_sl.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr-Latn.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_sv.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_sw.xtb | 4 chromium-134.0.6998.88/chrome/app/resources/generated_resources_uk.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_uz.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/generated_resources_vi.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_ky.xtb | 2 chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_vi.xtb | 2 chromium-134.0.6998.88/chrome/browser/about_flags.cc | 9 chromium-134.0.6998.88/chrome/browser/android/resource_id.h | 4 chromium-134.0.6998.88/chrome/browser/ash/accessibility/accessibility_manager.cc | 3 chromium-134.0.6998.88/chrome/browser/ash/crosapi/extension_info_private_ash.cc | 4 chromium-134.0.6998.88/chrome/browser/ash/extensions/accessibility_features_apitest.cc | 21 chromium-134.0.6998.88/chrome/browser/ash/login/demo_mode/demo_login_controller.cc | 12 chromium-134.0.6998.88/chrome/browser/ash/login/screens/pin_setup_screen.cc | 4 chromium-134.0.6998.88/chrome/browser/chromeos/extensions/info_private/info_private_apitest.cc | 2 chromium-134.0.6998.88/chrome/browser/extensions/api/settings_private/prefs_util.cc | 2 chromium-134.0.6998.88/chrome/browser/extensions/api/tabs/tabs_api.cc | 6 chromium-134.0.6998.88/chrome/browser/extensions/pref_mapping.cc | 3 chromium-134.0.6998.88/chrome/browser/flag-metadata.json | 5 chromium-134.0.6998.88/chrome/browser/flag_descriptions.cc | 8 chromium-134.0.6998.88/chrome/browser/flag_descriptions.h | 6 chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.cc | 141 chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/v2/calendar/outlook_calendar_page_handler.cc | 134 chromium-134.0.6998.88/chrome/browser/prefs/browser_prefs.cc | 4 chromium-134.0.6998.88/chrome/browser/prefs/pref_service_incognito_allowlist.cc | 1 chromium-134.0.6998.88/chrome/browser/resources/ash/settings/metrics_utils.ts | 4 chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.html | 1 chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.ts | 12 chromium-134.0.6998.88/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb | 2 chromium-134.0.6998.88/chrome/browser/resources/new_tab_page/modules/v2/authentication/microsoft_auth_module.ts | 4 chromium-134.0.6998.88/chrome/browser/resources/settings/people_page/sync_account_control.ts | 29 chromium-134.0.6998.88/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts | 6 chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/app.ts | 215 chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/common.ts | 5 chromium-134.0.6998.88/chrome/browser/resources/tab_search/app.ts | 8 chromium-134.0.6998.88/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc | 2 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb | 2 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb | 2 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb | 2 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb | 8 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb | 6 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb | 2 chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb | 2 chromium-134.0.6998.88/chrome/browser/ui/tabs/tab_strip_model.cc | 6 chromium-134.0.6998.88/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc | 8 chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler.cc | 13 chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler_unittest.cc | 30 chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_shared_ui.mojom | 7 chromium-134.0.6998.88/chromeos/CHROMEOS_LKGM | 2 chromium-134.0.6998.88/chromeos/strings/chromeos_strings_et.xtb | 2 chromium-134.0.6998.88/chromeos/strings/chromeos_strings_vi.xtb | 2 chromium-134.0.6998.88/chromeos/ui/frame/frame_header.cc | 9 chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator.cc | 1 chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator_unittest.cc | 27 chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb | 2 chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb | 2 chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb | 2 chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb | 2 chromium-134.0.6998.88/components/certificate_transparency/data/log_list.json | 4 chromium-134.0.6998.88/components/policy/resources/policy_templates_id.xtb | 2 chromium-134.0.6998.88/components/policy/resources/policy_templates_nl.xtb | 14 chromium-134.0.6998.88/components/policy/resources/policy_templates_zh-CN.xtb | 2 chromium-134.0.6998.88/components/strings/components_strings_ca.xtb | 2 chromium-134.0.6998.88/components/strings/components_strings_fa.xtb | 4 chromium-134.0.6998.88/components/strings/components_strings_ne.xtb | 2 chromium-134.0.6998.88/components/strings/components_strings_zh-CN.xtb | 2 chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ne.xtb | 43 chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ta.xtb | 12 chromium-134.0.6998.88/components/webapps/browser/android/translations/android_webapps_strings_ne.xtb | 2 chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler.cc | 6 chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler_unittest.cc | 2 chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.cc | 14 chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.h | 7 chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage.cc | 22 chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage_unittest.cc | 47 chromium-134.0.6998.88/content/browser/renderer_host/render_view_host_impl.cc | 16 chromium-134.0.6998.88/content/browser/webrtc/webrtc_audio_browsertest.cc | 18 chromium-134.0.6998.88/content/common/features.cc | 9 chromium-134.0.6998.88/content/common/features.h | 2 chromium-134.0.6998.88/debian/changelog | 26 chromium-134.0.6998.88/debian/control | 2 chromium-134.0.6998.88/debian/patches/fixes/pipewire14.patch | 45 chromium-134.0.6998.88/debian/patches/series | 1 chromium-134.0.6998.88/extensions/browser/api/web_request/web_request_api.cc | 42 chromium-134.0.6998.88/gin/v8_initializer.cc | 1 chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder.cc | 7 chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc | 16 chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc | 7 chromium-134.0.6998.88/gpu/config/gpu_lists_version.h | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12l-x64-rel-cq/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-13-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-tablet-landscape-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-15-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-mainline-clang-x86-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x64-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg-10-tests/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-official/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-oreo-x86-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-x86-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/ci/android-webview-13-x64-hostside-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-12-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-12l-x64-rel-cq/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-13-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-tablet-landscape-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-15-x64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm-compile-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm64-rel/properties.json | 6 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-mainline-clang-x86-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x64-dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/try/android-official/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-arm64-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-x86-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/builders/try/android-x64-rel/properties.json | 6 chromium-134.0.6998.88/infra/config/generated/builders/try/android-x86-rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x86_dbg/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.json | 2 chromium-134.0.6998.88/infra/config/generated/builders/try/gpu-fyi-cq-android-arm64/properties.json | 4 chromium-134.0.6998.88/infra/config/generated/luci/commit-queue.cfg | 2 chromium-134.0.6998.88/infra/config/lib/builder_config.star | 28 chromium-134.0.6998.88/infra/config/subprojects/chromium/try.star | 4 chromium-134.0.6998.88/infra/inclusive_language_presubmit_exempt_dirs.txt | 5 chromium-134.0.6998.88/net/http/transport_security_state_static.pins | 4 chromium-134.0.6998.88/net/http/transport_security_state_static_pins.json | 7 chromium-134.0.6998.88/remoting/resources/remoting_strings_fa.xtb | 2 chromium-134.0.6998.88/third_party/blink/renderer/core/css/invalidation/rule_invalidation_data_visitor.cc | 43 chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc | 19 chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h | 3 chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map_test.cc | 73 chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc | 14 chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h | 11 chromium-134.0.6998.88/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc | 15 chromium-134.0.6998.88/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc | 6 chromium-134.0.6998.88/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc | 14 chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.test.ts | 25 chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts | 9 chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/panels/sources/SourcesView.ts | 1 chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/components/text_editor/theme.ts | 4 chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/legacy/tabbedPane.css | 4 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.lock | 2 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.toml | 2 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/audits.toml | 6 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/config.toml | 2 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo-checksum.json | 1 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo_vcs_info.json | 6 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.lock | 237 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.toml | 88 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE | 67 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-MIT | 25 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/README.md | 62 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/generated/generated_autohint_styles.rs | 1440 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/scripts/gen_autohint_styles.py | 1476 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs | 277 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs | 510 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs | 352 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs | 597 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs | 535 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs | 166 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs | 753 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs | 403 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs | 214 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs | 3 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs | 201 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs | 69 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs | 584 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs | 949 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs | 119 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs | 661 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs | 181 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs | 952 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs | 480 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs | 429 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs | 205 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs | 19 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs | 768 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs | 781 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs | 558 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs | 823 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs | 246 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs | 1071 --- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs | 1502 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs | 852 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs | 86 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs | 387 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs | 97 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs | 157 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs | 34 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs | 265 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs | 244 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs | 319 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs | 163 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs | 288 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs | 522 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs | 195 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs | 243 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs | 1154 --- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs | 305 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs | 322 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs | 269 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs | 1418 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs | 76 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs | 224 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs | 110 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs | 120 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs | 316 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs | 275 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs | 324 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs | 47 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs | 163 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs | 177 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs | 240 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs | 29 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs | 359 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs | 835 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs | 271 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs | 1427 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs | 160 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs | 599 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs | 374 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs | 51 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs | 1462 ---- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs | 390 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs | 247 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs | 173 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs | 367 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs | 104 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs | 97 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs | 649 -- chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs | 519 - chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo-checksum.json | 1 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo_vcs_info.json | 6 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/Cargo.toml | 88 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE | 1 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-MIT | 1 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/README.md | 62 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/generated/generated_autohint_styles.rs | 1440 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/scripts/gen_autohint_styles.py | 1476 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs | 277 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs | 510 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs | 352 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs | 597 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs | 535 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs | 166 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs | 753 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs | 403 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs | 214 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs | 3 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs | 201 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs | 69 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs | 584 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs | 949 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs | 119 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs | 661 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs | 181 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs | 952 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs | 480 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs | 429 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs | 205 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs | 19 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs | 768 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs | 850 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs | 587 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs | 823 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs | 246 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs | 1071 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs | 1502 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs | 852 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs | 86 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs | 387 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs | 97 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs | 157 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs | 34 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs | 265 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs | 244 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs | 319 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs | 163 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs | 288 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs | 522 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs | 195 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs | 243 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs | 1154 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs | 305 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs | 322 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs | 269 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs | 1418 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs | 76 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs | 224 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs | 110 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs | 120 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs | 316 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs | 275 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs | 324 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs | 47 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs | 163 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs | 177 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs | 240 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs | 29 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs | 359 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs | 835 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs | 271 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs | 1427 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs | 160 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs | 599 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs | 374 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs | 25 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs | 51 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs | 1445 ++++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs | 390 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs | 247 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs | 173 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs | 367 + chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs | 104 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs | 97 chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs | 649 ++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs | 519 + chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/BUILD.gn | 161 chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/README.chromium | 6 chromium-134.0.6998.88/tools/metrics/histograms/enums.xml | 2 chromium-134.0.6998.88/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml | 2 chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/enums.xml | 11 chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/histograms.xml | 12 chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/enums.xml | 5 chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/histograms.xml | 14 chromium-134.0.6998.88/ui/strings/translations/ax_strings_vi.xtb | 2 chromium-134.0.6998.88/ui/views/controls/label.cc | 5 chromium-134.0.6998.88/v8/include/v8-version.h | 2 chromium-134.0.6998.88/v8/src/builtins/builtins-json.cc | 2 chromium-134.0.6998.88/v8/src/builtins/builtins-string.cc | 2 chromium-134.0.6998.88/v8/src/builtins/ia32/builtins-ia32.cc | 4 chromium-134.0.6998.88/v8/src/builtins/string-iswellformed.tq | 2 chromium-134.0.6998.88/v8/src/builtins/string-towellformed.tq | 2 chromium-134.0.6998.88/v8/src/builtins/x64/builtins-x64.cc | 4 chromium-134.0.6998.88/v8/src/compiler/node-properties.cc | 3 chromium-134.0.6998.88/v8/src/execution/frames.h | 5 chromium-134.0.6998.88/v8/src/json/json-stringifier.cc | 38 chromium-134.0.6998.88/v8/src/maglev/maglev-graph-builder.cc | 8 chromium-134.0.6998.88/v8/src/numbers/conversions.cc | 4 chromium-134.0.6998.88/v8/src/objects/js-raw-json.cc | 2 chromium-134.0.6998.88/v8/src/objects/js-regexp.cc | 2 chromium-134.0.6998.88/v8/src/objects/map.h | 3 chromium-134.0.6998.88/v8/src/objects/string-inl.h | 20 chromium-134.0.6998.88/v8/src/objects/string.h | 11 chromium-134.0.6998.88/v8/src/objects/string.tq | 27 chromium-134.0.6998.88/v8/src/objects/templates-inl.h | 1 chromium-134.0.6998.88/v8/src/profiler/tick-sample.cc | 13 chromium-134.0.6998.88/v8/src/regexp/experimental/experimental-interpreter.cc | 10 chromium-134.0.6998.88/v8/src/regexp/regexp-interpreter.cc | 7 chromium-134.0.6998.88/v8/src/regexp/regexp-macro-assembler.cc | 7 chromium-134.0.6998.88/v8/src/regexp/regexp.cc | 8 chromium-134.0.6998.88/v8/src/runtime/runtime-strings.cc | 2 chromium-134.0.6998.88/v8/src/strings/string-builder.cc | 2 chromium-134.0.6998.88/v8/src/strings/uri.cc | 4 chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/meta.json | 2 chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64-rl.profile | 2140 +++--- chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64.profile | 2489 +++---- chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86-rl.profile | 3231 ++++------ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86.profile | 2956 +++++---- 426 files changed, 42427 insertions(+), 41234 deletions(-) diff -Nru chromium-134.0.6998.35/DEPS chromium-134.0.6998.88/DEPS --- chromium-134.0.6998.35/DEPS 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/DEPS 2025-03-07 21:29:53.000000000 +0000 @@ -284,7 +284,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'debba63b78f8791411bff379835982cb2e8cabfa', + 'v8_revision': 'a57459aad9ec3ed5f78d9ded700d52e31029efd2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -372,7 +372,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '044764a564924c9aa0897ba8c50149acc7ddf364', + 'devtools_frontend_revision': '65b3f414b81ffe4df49202af6fc75bc26a3cb109', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -1168,8 +1168,8 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chrome_mac_universal_prod', - # 129.0.6651.0 - 'version': 'IrAigaqukp1GbaksroZcR3Jo0oOYKg9kzatjzNNbXKQC', + # 135.0.7023.0 + 'version': '-Ku_vv9W1rxG-W7I1lIenWsKHFcTIZCZ_qifqHbUvxQC', }, ], }, @@ -1448,7 +1448,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '6d95aa1fce7ca853818e818c4146c4f796c03559', + '539782278be6f930e63b910687795e6e4e09e321', 'condition': 'checkout_android and checkout_src_internal', }, @@ -4378,7 +4378,7 @@ # grepping. 'src/chrome/installer/mac/internal': { 'url': Var('chrome_git') + '/chrome/installer/mac/internal.git' + '@' + - 'bff19c50fa5c3177e594b9c5d07567b3ff5f4d65', + 'f5c2c8702a11e3bcc1aa24df3e0df8d38d231c3b', 'condition': 'checkout_src_internal', }, diff -Nru chromium-134.0.6998.35/ash/accessibility/a11y_feature_type.h chromium-134.0.6998.88/ash/accessibility/a11y_feature_type.h --- chromium-134.0.6998.35/ash/accessibility/a11y_feature_type.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/accessibility/a11y_feature_type.h 2025-03-07 21:29:53.000000000 +0000 @@ -16,6 +16,7 @@ kBounceKeys, kCaretHighlight, kColorCorrection, + kCursorColor, kCursorHighlight, kDictation, kDisableTouchpad, diff -Nru chromium-134.0.6998.35/ash/accessibility/accessibility_controller.cc chromium-134.0.6998.88/ash/accessibility/accessibility_controller.cc --- chromium-134.0.6998.35/ash/accessibility/accessibility_controller.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/accessibility/accessibility_controller.cc 2025-03-07 21:29:53.000000000 +0000 @@ -162,6 +162,8 @@ nullptr, IDS_ASH_STATUS_TRAY_ACCESSIBILITY_CARET_HIGHLIGHT}, {FeatureType::kCursorHighlight, prefs::kAccessibilityCursorHighlightEnabled, nullptr, IDS_ASH_STATUS_TRAY_ACCESSIBILITY_HIGHLIGHT_MOUSE_CURSOR}, + {FeatureType::kCursorColor, prefs::kAccessibilityCursorColorEnabled, + nullptr, 0, /*toggleable_in_quicksettings=*/false}, {FeatureType::kDictation, prefs::kAccessibilityDictationEnabled, &kDictationMenuIcon, IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION}, {FeatureType::kColorCorrection, prefs::kAccessibilityColorCorrectionEnabled, @@ -286,6 +288,7 @@ prefs::kAccessibilityChromeVoxVoiceName, prefs::kAccessibilityColorCorrectionEnabled, prefs::kAccessibilityCursorHighlightEnabled, + prefs::kAccessibilityCursorColorEnabled, prefs::kAccessibilityCursorColor, prefs::kAccessibilityDictationEnabled, prefs::kAccessibilityDictationLocale, @@ -462,16 +465,6 @@ } } -// Calculate the duration and record it into a histogram. -void RecordFeatureDurationMetric(const std::string& feature_duration_metric, - const base::Time& enabled_time) { - // Calculate the duration from the enabled time to now. - base::TimeDelta duration = base::Time::Now() - enabled_time; - // Log the duration into a histogram. - base::UmaHistogramCustomCounts(feature_duration_metric, duration.InSeconds(), - 1, base::Days(1) / base::Seconds(1), 100); -} - void ShowAccessibilityNotification( const AccessibilityController::A11yNotificationWrapper& wrapper) { A11yNotificationType type = wrapper.type; @@ -1028,6 +1021,9 @@ case FeatureType::kColorCorrection: feature_duration_metric += "CrosColorCorrection"; break; + case FeatureType::kCursorColor: + feature_duration_metric += "CrosCursorColor"; + break; case FeatureType::kCursorHighlight: feature_duration_metric += "CrosCursorHighlight"; break; @@ -1094,7 +1090,11 @@ feature_duration_metric += ".SessionDuration"; - RecordFeatureDurationMetric(feature_duration_metric, enabled_time_); + base::TimeDelta duration = base::Time::Now() - enabled_time_; + base::UmaHistogramCustomCounts(feature_duration_metric, duration.InSeconds(), + 1, base::Days(1) / base::Seconds(1), 100); + + // Reset enabled time as this duration is now logged and accounted for. enabled_time_ = base::Time(); } @@ -1223,6 +1223,7 @@ // not synced due to the impact they have on device interaction. registry->RegisterBooleanPref(prefs::kAccessibilityAutoclickEnabled, false); registry->RegisterBooleanPref(prefs::kAccessibilityBounceKeysEnabled, false); + registry->RegisterBooleanPref(prefs::kAccessibilityCursorColorEnabled, false); registry->RegisterBooleanPref(prefs::kAccessibilityCaretHighlightEnabled, false); registry->RegisterBooleanPref(prefs::kAccessibilityCursorHighlightEnabled, @@ -1683,6 +1684,11 @@ return GetFeature(FeatureType::kCursorHighlight); } +AccessibilityController::Feature& AccessibilityController::cursor_color() + const { + return GetFeature(FeatureType::kCursorColor); +} + AccessibilityController::Feature& AccessibilityController::dictation() const { return GetFeature(FeatureType::kDictation); } @@ -3011,48 +3017,18 @@ void AccessibilityController::UpdateCursorColorFromPrefs(bool notify) { DCHECK(active_user_prefs_); - int cursor_color = - active_user_prefs_->GetInteger(prefs::kAccessibilityCursorColor); - UpdateCursorColor(cursor_color, notify); - TrackCursorColorEnabledDuration(cursor_color); -} - -void AccessibilityController::UpdateCursorColor(SkColor cursor_color, - bool notify) { + const bool enabled = + active_user_prefs_->GetBoolean(prefs::kAccessibilityCursorColorEnabled); Shell* shell = Shell::Get(); - shell->SetCursorColor(cursor_color); - + shell->SetCursorColor( + enabled ? active_user_prefs_->GetInteger(prefs::kAccessibilityCursorColor) + : ui::kDefaultCursorColor); if (notify) { NotifyAccessibilityStatusChanged(); } shell->UpdateCursorCompositingEnabled(); } -void AccessibilityController::TrackCursorColorEnabledDuration( - SkColor cursor_color) { - // Check if a custom cursor color is currently enabled. - const bool is_custom_color_enabled = cursor_color != ui::kDefaultCursorColor; - - if (last_cursor_color_enabled_time_ == base::Time()) { - cursor_color_enabled_ = is_custom_color_enabled; - if (is_custom_color_enabled) { - last_cursor_color_enabled_time_ = base::Time::Now(); - } - } - - if (cursor_color_enabled_ == is_custom_color_enabled) { - return; - } - - if (!is_custom_color_enabled) { - RecordFeatureDurationMetric("Accessibility.CrosCursorColor.SessionDuration", - last_cursor_color_enabled_time_); - last_cursor_color_enabled_time_ = base::Time(); - } - - cursor_color_enabled_ = is_custom_color_enabled; -} - void AccessibilityController::UpdateFaceGazeFromPrefs() { if (!::features::IsAccessibilityFaceGazeEnabled()) { return; @@ -3964,6 +3940,11 @@ case FeatureType::kVirtualKeyboard: keyboard::SetAccessibilityKeyboardEnabled(enabled); break; + case FeatureType::kCursorColor: + // The notification will already come via UpdateFeatureFromPref + // so we don't need to run it twice. + UpdateCursorColorFromPrefs(/*notify=*/false); + break; case FeatureType::kColorCorrection: if (enabled && !active_user_prefs_->GetBoolean( prefs::kAccessibilityColorCorrectionHasBeenSetup)) { diff -Nru chromium-134.0.6998.35/ash/accessibility/accessibility_controller.h chromium-134.0.6998.88/ash/accessibility/accessibility_controller.h --- chromium-134.0.6998.35/ash/accessibility/accessibility_controller.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/accessibility/accessibility_controller.h 2025-03-07 21:29:53.000000000 +0000 @@ -806,10 +806,6 @@ void UpdateShortcutsEnabledFromPref(); void UpdateTabletModeShelfNavigationButtonsFromPref(); - // UpdateCursorColorFromPrefs helpers. - void UpdateCursorColor(SkColor cursor_color, bool notify); - void TrackCursorColorEnabledDuration(SkColor cursor_color); - void SwitchAccessDisableDialogClosed(bool disable_dialog_accepted); void MaybeCreateSelectToSpeakEventHandler(); void ActivateSwitchAccess(); @@ -855,14 +851,9 @@ int large_cursor_size_in_dip_ = kDefaultLargeCursorSize; bool dictation_active_ = false; - bool cursor_color_enabled_ = false; bool shortcuts_enabled_ = true; bool tablet_mode_shelf_navigation_buttons_enabled_ = false; - // The time at which the cursor color feature was last enabled. Used for - // metrics. - base::Time last_cursor_color_enabled_time_; - SelectToSpeakState select_to_speak_state_ = SelectToSpeakState::kSelectToSpeakStateInactive; std::unique_ptr select_to_speak_event_handler_; diff -Nru chromium-134.0.6998.35/ash/accessibility/accessibility_controller_unittest.cc chromium-134.0.6998.88/ash/accessibility/accessibility_controller_unittest.cc --- chromium-134.0.6998.35/ash/accessibility/accessibility_controller_unittest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/accessibility/accessibility_controller_unittest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -215,6 +215,7 @@ prefs()->FindPreference(prefs::kAccessibilityCaretHighlightEnabled)); EXPECT_TRUE( prefs()->FindPreference(prefs::kAccessibilityCursorHighlightEnabled)); + EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityCursorColorEnabled)); EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityDictationEnabled)); EXPECT_TRUE(prefs()->FindPreference(prefs::kAccessibilityDictationLocale)); EXPECT_TRUE( @@ -499,31 +500,22 @@ } TEST_F(AccessibilityControllerTest, SetCursorColorEnabled) { + EXPECT_FALSE(controller()->cursor_color().enabled()); + TestAccessibilityObserver observer; controller()->AddObserver(&observer); EXPECT_EQ(0, observer.status_changed_count_); - ExpectSessionDurationMetricCount("CrosCursorColor", 0); - prefs()->SetInteger(prefs::kAccessibilityCursorColor, 1); + controller()->cursor_color().SetEnabled(true); + EXPECT_TRUE(controller()->cursor_color().enabled()); EXPECT_EQ(1, observer.status_changed_count_); ExpectSessionDurationMetricCount("CrosCursorColor", 0); - prefs()->SetInteger(prefs::kAccessibilityCursorColor, - ui::kDefaultCursorColor); + controller()->cursor_color().SetEnabled(false); + EXPECT_FALSE(controller()->cursor_color().enabled()); EXPECT_EQ(2, observer.status_changed_count_); ExpectSessionDurationMetricCount("CrosCursorColor", 1); - // Set to custom color, and return back to default cursor color to ensure - // that second duration is still counted. - prefs()->SetInteger(prefs::kAccessibilityCursorColor, 1); - EXPECT_EQ(3, observer.status_changed_count_); - ExpectSessionDurationMetricCount("CrosCursorColor", 1); - - prefs()->SetInteger(prefs::kAccessibilityCursorColor, - ui::kDefaultCursorColor); - EXPECT_EQ(4, observer.status_changed_count_); - ExpectSessionDurationMetricCount("CrosCursorColor", 2); - controller()->RemoveObserver(&observer); } @@ -1385,6 +1377,7 @@ // Simulate using chrome settings webui to set cursor color, which also turns // on the cursor color enabled pref. prefs()->SetInteger(prefs::kAccessibilityCursorColor, SK_ColorBLUE); + prefs()->SetBoolean(prefs::kAccessibilityCursorColorEnabled, true); CursorWindowController* cursor_window_controller = Shell::Get()->window_tree_host_manager()->cursor_window_controller(); @@ -1401,11 +1394,11 @@ // Simulate using chrome settings webui to set cursor color to black, which // which also turns off the cursor color enabled pref. - prefs()->SetInteger(prefs::kAccessibilityCursorColor, - ui::kDefaultCursorColor); - + prefs()->SetInteger(prefs::kAccessibilityCursorColor, 0); + prefs()->SetBoolean(prefs::kAccessibilityCursorColorEnabled, false); EXPECT_EQ(ui::kDefaultCursorColor, cursor_window_controller->GetCursorColorForTest()); + ExpectSessionDurationMetricCount("CrosCursorColor", 1); } TEST_F(AccessibilityControllerTest, SetMonoAudioEnabled) { diff -Nru chromium-134.0.6998.35/ash/birch/birch_coral_provider.cc chromium-134.0.6998.88/ash/birch/birch_coral_provider.cc --- chromium-134.0.6998.35/ash/birch/birch_coral_provider.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/birch/birch_coral_provider.cc 2025-03-07 21:29:53.000000000 +0000 @@ -335,6 +335,17 @@ const coral::mojom::GroupPtr& BirchCoralProvider::GetGroupById( const base::Token& group_id) const { + // Add crash keys here to track the crash of crbug.com/395130742. + SCOPED_CRASH_KEY_BOOL("395130742", "response_", !!response_); + if (response_) { + SCOPED_CRASH_KEY_NUMBER("395130742", "group num", + response_->groups().size()); + if (!response_->groups().empty()) { + SCOPED_CRASH_KEY_BOOL("395130742", "first group", + !!(*response_->groups().begin())); + } + } + std::vector& groups = response_->groups(); auto iter = std::find_if( groups.begin(), groups.end(), @@ -859,7 +870,13 @@ } void BirchCoralProvider::Reset() { - response_.reset(); + // Clear the groups in observers before resetting the `response_`. + if (response_) { + for (const auto& group : response_->groups()) { + observers_.Notify(&Observer::OnCoralGroupRemoved, group->id); + } + response_.reset(); + } in_session_source_desk_ = nullptr; windows_observation_.RemoveAllObservations(); } diff -Nru chromium-134.0.6998.35/ash/constants/ash_pref_names.h chromium-134.0.6998.88/ash/constants/ash_pref_names.h --- chromium-134.0.6998.35/ash/constants/ash_pref_names.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/constants/ash_pref_names.h 2025-03-07 21:29:53.000000000 +0000 @@ -702,7 +702,10 @@ // A boolean pref which determines whether cursor highlighting is enabled. inline constexpr char kAccessibilityCursorHighlightEnabled[] = "settings.a11y.cursor_highlight"; -// An integer pref which determines the custom cursor color if any. +// A boolean pref which determines whether custom cursor color is enabled. +inline constexpr char kAccessibilityCursorColorEnabled[] = + "settings.a11y.cursor_color_enabled"; +// An integer pref which determines the custom cursor color. inline constexpr char kAccessibilityCursorColor[] = "settings.a11y.cursor_color"; // A boolean pref which determines whether flash screen for notifications is diff -Nru chromium-134.0.6998.35/ash/strings/ash_strings_es.xtb chromium-134.0.6998.88/ash/strings/ash_strings_es.xtb --- chromium-134.0.6998.35/ash/strings/ash_strings_es.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/strings/ash_strings_es.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2437,7 +2437,7 @@ Fin Buscar en el Portapapeles APLICACIONES SUGERIDAS -Hacerlo luego +En otro momento Se muestra 1 resultado de Esta función te permite acceder rápidamente a cualquier usuario que haya iniciado sesión sin tener que introducir una contraseña. Solo debes usar esta función con las cuentas de confianza. Lupa de pantalla completa diff -Nru chromium-134.0.6998.35/ash/strings/ash_strings_sr-Latn.xtb chromium-134.0.6998.88/ash/strings/ash_strings_sr-Latn.xtb --- chromium-134.0.6998.35/ash/strings/ash_strings_sr-Latn.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/strings/ash_strings_sr-Latn.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -101,7 +101,7 @@ Slab signal Premesti aplikaciju u folder . Uređaj sa USB priključkom tipa C (levi port) -Datoteke +Fajlovi Esc Otvori opciju Istražite Nazad na rezime diff -Nru chromium-134.0.6998.35/ash/strings/ash_strings_sr.xtb chromium-134.0.6998.88/ash/strings/ash_strings_sr.xtb --- chromium-134.0.6998.35/ash/strings/ash_strings_sr.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/strings/ash_strings_sr.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -101,7 +101,7 @@ Слаб сигнал Премести апликацију у фолдер . Уређај са USB прикључком типа C (леви порт) -Датотеке +Фајлови Esc Отвори опцију Истражите Назад на резиме diff -Nru chromium-134.0.6998.35/ash/strings/ash_strings_uk.xtb chromium-134.0.6998.88/ash/strings/ash_strings_uk.xtb --- chromium-134.0.6998.35/ash/strings/ash_strings_uk.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/strings/ash_strings_uk.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1299,7 +1299,7 @@ Переходити назад між вікнами Дбулювати зображення на моніторах Зберегти -Підключити новий пристрій +Зв’язати новий пристрій Не вдається знайти телефон Сховати назву робочого столу Ім’я diff -Nru chromium-134.0.6998.35/ash/strings/ash_strings_vi.xtb chromium-134.0.6998.88/ash/strings/ash_strings_vi.xtb --- chromium-134.0.6998.35/ash/strings/ash_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/strings/ash_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1465,7 +1465,7 @@ Điểm phát sóng đang bật, chưa có thiết bị nào kết nối Giữ để phóng to tối đa chưa được kích hoạt. -Tắt +Đang tắt Bật % pin Đang thu thập thông tin mạng diff -Nru chromium-134.0.6998.35/ash/style/tab_slider_button.cc chromium-134.0.6998.88/ash/style/tab_slider_button.cc --- chromium-134.0.6998.35/ash/style/tab_slider_button.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/style/tab_slider_button.cc 2025-03-07 21:29:53.000000000 +0000 @@ -281,6 +281,29 @@ IconLabelSliderButton::~IconLabelSliderButton() = default; +gfx::Size IconLabelSliderButton::CalculatePreferredSize( + const views::SizeBounds& available_size) const { + // TODO(crbug.com/400028865): this is a workaround for label preferred size + // calculation. This should be remove once the issue is fixed. + // + // Return 0 width to avoid overflow. + // + // View subtree: + // . SetValueEffectSlider (vertical BoxLayout, stretch cross axis) + // . Title + // . TabSlider (TableLayout) + // . IconLabelSliderButton + // . IconLabelSliderButton + // ... + // + // + // The button contains a single-line label that can be very long. + // When the available width is small than the full width, the + // label refuses to shrink (i.e., it still returns full width for the + // preferred width). This causes TabSlider to overflow. + return {0, GetMinimumSize().height()}; +} + void IconLabelSliderButton::UpdateColors() { label_->SetEnabledColorId(GetColorIdOnButtonState()); // `SchedulePaint()` will result in the `gfx::VectorIcon` for `image_view_` diff -Nru chromium-134.0.6998.35/ash/style/tab_slider_button.h chromium-134.0.6998.88/ash/style/tab_slider_button.h --- chromium-134.0.6998.35/ash/style/tab_slider_button.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/style/tab_slider_button.h 2025-03-07 21:29:53.000000000 +0000 @@ -143,6 +143,10 @@ ~IconLabelSliderButton() override; private: + // views::View: + gfx::Size CalculatePreferredSize( + const views::SizeBounds& available_size) const override; + // Update label color according to the current button state. void UpdateColors(); diff -Nru chromium-134.0.6998.35/ash/webui/camera_app_ui/resources/strings/camera_strings_vi.xtb chromium-134.0.6998.88/ash/webui/camera_app_ui/resources/strings/camera_strings_vi.xtb --- chromium-134.0.6998.35/ash/webui/camera_app_ui/resources/strings/camera_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ash/webui/camera_app_ui/resources/strings/camera_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -105,7 +105,7 @@ Bật chế độ chuyên gia Quét tài liệu Chế độ Chuyên gia -Tắt +Đang tắt Lưới Đang bật Thu nhỏ diff -Nru chromium-134.0.6998.35/build/util/LASTCHANGE chromium-134.0.6998.88/build/util/LASTCHANGE --- chromium-134.0.6998.35/build/util/LASTCHANGE 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/build/util/LASTCHANGE 2025-03-07 21:29:53.000000000 +0000 @@ -1,2 +1,2 @@ -LASTCHANGE=ea6ef4c2ac15ae95d2cfd65682da62c093415099-refs/branch-heads/6998@{#1472} +LASTCHANGE=7e3d5c978c6d3a6eda25692cfac7f893a2b20dd0-refs/branch-heads/6998@{#1898} LASTCHANGE_YEAR=2025 diff -Nru chromium-134.0.6998.35/build/util/LASTCHANGE.committime chromium-134.0.6998.88/build/util/LASTCHANGE.committime --- chromium-134.0.6998.35/build/util/LASTCHANGE.committime 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/build/util/LASTCHANGE.committime 2025-03-07 21:29:53.000000000 +0000 @@ -1 +1 @@ -1740513316 \ No newline at end of file +1741382993 \ No newline at end of file diff -Nru chromium-134.0.6998.35/chrome/VERSION chromium-134.0.6998.88/chrome/VERSION --- chromium-134.0.6998.35/chrome/VERSION 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/VERSION 2025-03-07 21:29:53.000000000 +0000 @@ -1,4 +1,4 @@ MAJOR=134 MINOR=0 BUILD=6998 -PATCH=35 +PATCH=88 diff -Nru chromium-134.0.6998.35/chrome/app/chrome_exe_main_mac.cc chromium-134.0.6998.88/chrome/app/chrome_exe_main_mac.cc --- chromium-134.0.6998.35/chrome/app/chrome_exe_main_mac.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/chrome_exe_main_mac.cc 2025-03-07 21:29:53.000000000 +0000 @@ -129,7 +129,7 @@ // revised. Hopefully a more elegant solution will become apparent before that's // required. #if !defined(DCHECK_ALWAYS_ON) -__attribute__((used)) const char kGrossPaddingForCrbug1300598[72 * 1024] = {}; +__attribute__((used)) const char kGrossPaddingForCrbug1300598[84 * 1024] = {}; #else // DCHECK builds are larger and therefore require less padding. See // https://crbug.com/1394196 for the calculations, and diff -Nru chromium-134.0.6998.35/chrome/app/resources/chromium_strings_ky.xtb chromium-134.0.6998.88/chrome/app/resources/chromium_strings_ky.xtb --- chromium-134.0.6998.35/chrome/app/resources/chromium_strings_ky.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/chromium_strings_ky.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -246,7 +246,7 @@ Chromium'га фондук режимде иштөөгө уруксат берүү {NUM_EXTENSIONS,plural, =1{Chromium аны өчүрүүнү сунуштайт. Колдоого алынган кеңейтүүлөр жөнүндө кеңири маалымат}other{Chromium аларды өчүрүүнү сунуштайт. Колдоого алынган кеңейтүүлөр жөнүндө кеңири маалымат}} Chromium'ду өзгөчөлөштүрүү жана көзөмөлдөө -Өркүндөтүлгөн коргоо параметри фишинг жана кесепеттүү программалардан жакшыраак коргойт +Күчөтүлгөн коргоо параметри фишинг жана кесепеттүү программалардан жакшыраак коргойт Орнотуу катасы: Chromium'ду тескейт Chromium профилин кошуу diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_ar.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_ar.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_ar.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_ar.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -3054,7 +3054,7 @@ مصغّر حذف الكل حجم التطبيق: -تمت إضافة علامة التبويب هذه +أضفتُ علامة التبويب هذه عدم السماح للمواقع الإلكترونية بتعديل الملفات أو المجلدات على جهازك تمّت إزالة تثبيت الزر في انتظار ذاكرة التخزين المؤقت ... diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_ca.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_ca.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_ca.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_ca.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -8507,7 +8507,7 @@ Afegeix un altre Compte de Google per a Accedir a dispositius USB del proveïdor Inici de sessió de targeta intel·ligent de Microsoft -Crea un Compte de Google per a un nen +Crea un Compte de Google per a un nen o nena El teu Chromebook ja no rep actualitzacions de seguretat. És hora de comprar-te'n un de nou per tenir el programari i les funcions de seguretat més recents. S'apliquen les condicions de l'oferta. Els permisos , i més s'han suprimit Té permís per desar dades al dispositiu diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_es.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_es.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_es.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_es.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -8742,7 +8742,7 @@ Esto permite que los servicios del sistema usen la precisión de la ubicación para determinar tu ubicación. La precisión de la ubicación usa información sobre las señales inalámbricas y los sensores para estimar la ubicación del dispositivo. Usar Windows Hello al rellenar contraseñas Falta el tipo de red. -Administrar uso compartido +Gestionar uso compartido Las aplicaciones que se indican abajo también pueden procesar enlaces de protocolo. Otras aplicaciones pedirán permiso. Para configurar la huella digital, pídele a tu hijo/a que toque el sensor de huellas digitales, que está en la esquina superior derecha del teclado. Los datos de la huella digital de tu hijo/a se almacenan de forma segura y nunca salen de este . Bloqueo de pantalla e inicio de sesión @@ -11524,7 +11524,7 @@ Mostrar lista de lectura No se admite el perfil cuentas -Hacerlo luego +En otro momento Más información sobre las pestañas Ver combinaciones de teclas ¿Por qué aparece esta sugerencia? diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_et.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_et.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_et.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_et.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2520,7 +2520,7 @@ See leht pääseb teie kaamera juurde. V8 optimeerija kasutamine ei ole lubatud A&va suletud aken uuesti -Oodake ... +Palun oodake ... Seadme järgmisel taaskäivitamisel teeb administraator ühekordse värskenduse, mille käigus kustutatakse teie kohalikud andmed. Lisasisu üksus -st Meeldivaks märkimine saadab tagasisidet, et need tulemused meeldivad teile. diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_fa.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_fa.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_fa.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_fa.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -42,7 +42,7 @@ گذرکلید به‌روز شد افزودن درگاه بارگیری تصویر -‏Windows Hello یا کلید ایمنی خارجی +‏Windows Hello یا کلید امنیتی خارجی ‏دلیل: LBS به‌طور پیش‌فرض در باقی می‌ماند. ‏برای ادامه استفاده از گذرواژه‌ها و موارد دیگر در «حساب Google» خود، هویتتان را به‌تأیید برسانید گذرکلید @@ -204,7 +204,7 @@ سه‌کلیک با موشواره ‏می‌توانید سابقه مرورتان را علاوه‌بر نشانی وب و عنوان صفحه، براساس محتوای کلی صفحه نیز جستجو کنید. فرقی نمی‌کند سابقه مرور را در نوار نشانی و بااستفاده از ‎@history یا از صفحه «سابقه» جستجو کنید، با این روش نتایج بهتری دریافت خواهید کرد. . از . -چون چندین‌بار پین اشتباه وارد شده، کلید ایمنی قفل شده است. برای باز کردن قفل کلید ایمنی، آن را بردارید و دوباره وارد کنید. +چون چندین‌بار پین اشتباه وارد شده، کلید امنیتی قفل شده است. برای باز کردن قفل کلید امنیتی، آن را بردارید و دوباره وارد کنید. داده‌های موقت باز کردن پیوند در {MUTED_NOTIFICATIONS_COUNT,plural, =1{اعلان جدید}one{# اعلان جدید}other{# اعلان جدید}} @@ -353,7 +353,7 @@ صفحه به نیست سایت‌ها می‌توانند برای ضبط کردن و استفاده از ورودی موشواره درخواست کنند بی‌عنوان -برای تکمیل درخواست، دوباره کلید ایمنی را لمس کنید. +برای تکمیل درخواست، دوباره کلید امنیتی را لمس کنید. زبان و کشور ایجاد رمزینه پاسخ‌سریع برای این تصویر کارمندان سرویس @@ -420,7 +420,7 @@ حذف نصب نشد پین جدیدی ایجاد کنید که با پین فعلی‌تان تفاوت داشته باشد جستجوی برای «» در «برگه جدید» -‏مرور برنامه‌ها و خدمات Google Play +‏بازبینی برنامه‌ها و سرویس‌های Google Play دستگاهی همین اطراف درحال هم‌رسانی است پنجره چفت‌شده ویرایش فایل‌ها @@ -501,7 +501,7 @@ ورودی ترجیحی دستگاهتان را ثبت‌نام کنید خواندن داده‌ها و اطلاعات دستگاه‌های جانبی مجهز به بلوتوث -کلید ایمنی شما قفل شده است زیرا اثر انگشتتان تشخیص داده نشد. برای باز کردن قفل آن، پین را وارد کنید. +کلید امنیتی شما قفل شده است زیرا اثر انگشتتان تشخیص داده نشد. برای باز کردن قفل آن، پین را وارد کنید. درحال جفت کردن… می‌خواهد این برنامه را باز کند. در حال حذف... @@ -744,7 +744,7 @@ سایت‌ها نمی‌توانند در دستگاه داده ذخیره کنند اگر از یک سرور پروکسی استفاده می‌کنید، تنظمیات پروکسی خود را بررسی کنید یا با سرپرست شبکه خود تماس بگیرید و اطمینان حاصل کنید که سرور پروکسی کار می‌کند. اگر فکر نمی‌کنید که در حال استفاده از سرور پروکسی باشید، تنظیمات پروکسی خود را تنظیم نمایید.  باز کردن در پنجره -این کلید ایمنی نمی‌تواند داده‌های ورود به سیستم را ذخیره کند +این کلید امنیتی نمی‌تواند داده‌های ورود به سیستم را ذخیره کند تنها راه برای واگرد این مورد، نصب مجدد است رمزگذاری شده است. از مالک بخواهید آن را رمزگشایی کند. ‏وارد شده از Safari @@ -905,7 +905,7 @@ ممکن است حجم مجاز داده دستگاه همراهتان را مصرف کرده باشید. برای خرید داده بیشتر، از پورتال فعال‌سازی بازدید کنید تلفن شناسایی نشد مرور جدا شود؟ -مدیریت داده‌های ورود به سیستم ذخیره‌شده در کلید ایمنی +مدیریت داده‌های ورود به سیستم ذخیره‌شده در کلید امنیتی این برنامه افزودنی به مجوز خاصی نیاز ندارد. نمی‌توان افزونه «» را وارد کرد زیرا مدول هم‌رسانی‌شده‌ای نیست. {NUM_FILES,plural, =0{درحال بررسی این داده‌ها با خط‌مشی‌های امنیتی سازمانتان…}=1{درحال بررسی این فایل با خط‌مشی‌های امنیتی سازمانتان…}one{درحال بررسی این فایل‌ها با خط‌مشی‌های امنیتی سازمانتان…}other{درحال بررسی این فایل‌ها با خط‌مشی‌های امنیتی سازمانتان…}} @@ -993,7 +993,7 @@ ذخیره در برای با پیشنهادها آشنا شوید پایه - می‌خواهد به ساخت و مدل «کلید ایمنی» شما دسترسی پیدا کند + می‌خواهد به ساخت و مدل «کلید امنیتی» شما دسترسی پیدا کند باز کردن همه ( مورد) در «پنجره ناشناس» نمی‌توان را اضافه کرد باقی‌مانده @@ -1099,7 +1099,7 @@ از گذرکلید برای ورود به سیستم استفاده کنید ‏می‌توانید این گذرواژه را در «حساب Google» خود یا فقط در این دستگاه ذخیره کنید گذرواژه الزامی است -کلید ایمنی نمی‌تواند اثر انگشت را ذخیره کند +کلید امنیتی نمی‌تواند اثر انگشت را ذخیره کند ‏همچنان از گذرواژه‌های ذخیره‌شده در «حساب Google» خود استفاده کنید ورود به سیستم و همگام‌سازی لازم است تا زمانی که همه برگه‌های را نبندید، این سایت می‌تواند فایل‌های موجود در را ویرایش کند @@ -2035,7 +2035,7 @@ پین ۴ رقمی را وارد کنید (۹۹۹۹-۰۰۰۰) ‏پس‌از Powerwash دستگاه، نمایه‌های سیم‌کارت داخلی برداشته نخواهد شد. برای برداشتن دستی این نمایه‌ها، به تنظیمات تلفن همراه بروید. اعلان‌ها روشن شد -داده‌های ورود به سیستم کلید ایمنی +داده‌های ورود به سیستم کلید امنیتی کنترل‌های رسانه به‌روزرسانی فوری الزامی است صداها @@ -2646,7 +2646,7 @@ ‏سیستم فایل رمزگذاری Microsoft برنامه‌ها ‏مقدار خط‌مشی ExtensionInstallForcelist نامعتبر است. لطفاً با سرپرست تماس بگیرید. -جزئیات دیگر +جزئیات اضافی دستگاهی که می‌خواهید با آن هم‌رسانی کنید درخواست را نپذیرفت میان‌بر از قبل وجود دارد فایل‌هایی که بارگیری می‌کنید اینجا نشان داده می‌شود @@ -3262,7 +3262,7 @@ {COUNT,plural, =1{فایل}one{# فایل}other{# فایل}} در حال بارگیری تفاوت خواندن، تغییر و حذف عکس‌ها، موسیقی و سایر رسانه‌ها از رایانه‌تان -کلید ایمنی توکار درحال‌حاضر امن نیست. لطفاً این کلید را از هرسرویسی که از آن با این کلید استفاده می‌کنید، بردارید. برای حل این مشکل، لطفاً کلید ایمنی را بازنشانی کنید. +کلید امنیتی توکار درحال‌حاضر امن نیست. لطفاً این کلید را از هرسرویسی که از آن با این کلید استفاده می‌کنید، بردارید. برای حل این مشکل، لطفاً کلید امنیتی را بازنشانی کنید. باز کردن به‌عنوان پنجره پیمایش با مکان‌نمای نوشتار (مرور با هشتک) سایه بزرگ @@ -3453,7 +3453,7 @@ برگه‌های جستجو ساعت نظامی نمی‌توانید با این حساب به سیستم وارد شوید -کلید ایمنی توکار باید بازنشانی شود +کلید امنیتی توکار باید بازنشانی شود کلید عمومی منحنی بیضوی توجه: ممکن است صدای مشابه یا صدای ضبط‌شده هم بتواند به نتایج شخصی یا «دستیار» شما دسترسی یابد. افزودن نمایه جدید @@ -3597,7 +3597,7 @@ کنترل بازی ‏از محافظت امنیتی استاندارد برخوردار هستید. برای محافظت بیشتر دربرابر وب‌سایت‌ها، بارگیری‌ها، و افزونه‌های خطرناک، «مرور ایمن پیشرفته» را در تنظیمات Chrome روشن کنید. این فایل بایگانی حاوی فایل‌های دیگری است که ممکن است بدافزار پنهان داشته باشد -برای تأیید بازنشانی، کلید ایمنی‌تان را لمس کنید. همه اطلاعات ذخیره‌شده در کلید ایمنی (ازجمله پین) پاک می‌شود. +برای تأیید بازنشانی، کلید امنیتی‌تان را لمس کنید. همه اطلاعات ذخیره‌شده در کلید امنیتی (ازجمله پین) پاک می‌شود. برای چیزهایی که می‌خواهید بعداً سراغ آن‌ها بیایید نشانک بگذارید سرویس پایانه چاپ ذخیره صفحه به‌عنوان… @@ -3660,7 +3660,7 @@ برنامه کیوسک بارگیری نشد. درحال پیکربندی محتوای قابل‌بارگیری. ‏احتمالاً شبکه‌ Wi-Fi مورد استفاده‌تان () نیاز دارد که به یک صفحه ورود به سیستم بروید. -‏کلید ایمنی USB +‏کلید امنیتی USB نمایش میزان استفاده برگه از حافظه از این دستگاه سایتی اضافه نشده است @@ -3884,7 +3884,7 @@ پنجره‌ای برای این سمت انتخاب کنید ذخیره صفحه &بعنوان... عقب/جلو -این کلید ایمنی هیچ داده ورود به سیستمی ندارد +این کلید امنیتی هیچ داده ورود به سیستمی ندارد به‌روزرسانی‌های خودکار روشن هستند. میکروفون جلو این دستگاه نمایشی در وضعیت لغو مجوز دسترسی قرار داده شده است. @@ -3993,7 +3993,7 @@ ‏این افزونه حریم خصوصی «نت‌بازار Chrome» را نقض می‌کند. دستگاه تلفن همراه فعال نشد شما را از سیستم اکثر سایت‌ها خارج می‌کند -چون چندین‌بار پین اشتباه وارد شده، کلید ایمنی قفل شده است. باید کلید ایمنی‌ را بازنشانی کنید. +چون چندین‌بار پین اشتباه وارد شده، کلید امنیتی قفل شده است. باید کلید امنیتی‌ را بازنشانی کنید. ابزارهای &برنامه نویس ‏از آن سؤال بپرسید. بگویید کاری انجام دهد. این Google شخصی شما است و همیشه برای کمک آماده است. استفاده از حساب دیگر @@ -4276,7 +4276,7 @@ مالک ONC کنش‌های بیشتر برای -استفاده از تلفن، رایانه لوحی، یا کلید ایمنی دیگر +استفاده از تلفن، رایانه لوحی، یا کلید امنیتی دیگر خاموش کردن شبکه تلفن همراه خارج شدن از ‏اعلان‌ها، Google Play @@ -4286,7 +4286,7 @@ کانا شناسه در حال محاسبه… -اثر انگشت‌ها در این کلید ایمنی +اثر انگشت‌ها در این کلید امنیتی کاربر مجاز نیست درحال بررسی کردن گذرواژه‌ها ( از )… سایت‌ها می‌توانند درخواست کنند از اطلاعاتی که درباره شما ذخیره کرده‌اند استفاده کنند @@ -4503,9 +4503,9 @@ باز کردن دوباره بازخورد لمسی صفحه لمسی لطفاً دستگاه را راه‌اندازی مجدد کنید و دوباره امتحان کنید. -نمی‌توان این کلید ایمنی را بازنشانی کرد +نمی‌توان این کلید امنیتی را بازنشانی کرد مسیر بیش از حد طولانی است -کلید ایمنی بازنشانی شد +کلید امنیتی بازنشانی شد تک‌شاخ خاموش کردن قهرمان @@ -4620,7 +4620,7 @@ {NUM_TABS,plural, =0{بدون برگه غیرفعال}=1{مرور ۱ برگه غیرفعال}one{مرور # برگه غیرفعال}other{مرور # برگه غیرفعال}} املا برای بی‌صدا کردن این برگه، روی نماد بلندگو کلیک کنید -استفاده از کلید ایمنی خارجی +استفاده از کلید امنیتی خارجی خطایی درحین فعال‌سازی روی داد. پیگیری قیمت فعال است. قیمت است. میکروفون مجاز نیست @@ -5110,11 +5110,11 @@ گزینه ورود به سیستم اشتباه است؟ بعد از راه‌اندازی، هرزمان خواستید می‌توانید افراد بیشتری را اضافه کنید. هر فرد می‌تواند حسابش را شخصی‌سازی کند و داده‌ها را خصوصی نگه دارد. افزودن واژه -کلید ایمنی درخواست شده است +کلید امنیتی درخواست شده است ‏متأسفیم، حساب‌های Google در این دستگاه مجاز نیستند. وقتی دستگاه فعالیتی ندارد هم‌ترازی دوطرفه برای درخواست این افزونه: -پین را برای کلید ایمنی وارد کنید +پین را برای کلید امنیتی وارد کنید حتماً درخواست پخش را در بپذیرید بیشتر... @@ -5396,7 +5396,7 @@ • ۱ برگه تکراری ذخیره صفحه به‌عنوان... برای کار -شما از کلید ایمنی استفاده می‌کنید که در این وب‌سایت ثبت نشده است +شما از کلید امنیتی استفاده می‌کنید که در این وب‌سایت ثبت نشده است لغو برش ویرایش گذرکلید برای نام کاربری: لطفاً اتصال شبکه‌تان را بررسی کنید و دوباره امتحان کنید. @@ -5545,7 +5545,7 @@ بازرسی عناصر ‏آیا می‌خواهید ChromeVox را که صفحه‌خوان داخلی ChromeOS Flex است فعال کنید؟ اگر پاسختان مثبت است، هر دو کلید میزان صدا را فشار دهید و پنج ثانیه نگه دارید. بازخورد ارسال نمی‌شود. لطفاً بعداً دوباره امتحان کنید. -اثر انگشت به این کلید ایمنی اضافه نشد +اثر انگشت به این کلید امنیتی اضافه نشد خودکار (پیش‌فرض) ‏به‌روزرسانی‌های امنیتی به‌زودی به‌اتمام می‌رسد. به Chromebook جدید ارتقا دهید. سابقه جستجو @@ -5686,7 +5686,7 @@ این افزونه بدافزار دارد. ‏گذرواژه شما هم‌رسانی نشد. اتصال اینترنت را بررسی کنید و مطمئن شوید که به سیستم Chrome وارد شده باشید. سپس، دوباره امتحان کنید. ‏هرزمان بخواهید می‌توانید موارد مدنظرتان را برای همگام‌سازی در تنظیمات انتخاب کنید. Google ممکن است «جستجو» و سرویس‌های دیگر را براساس سابقه‌تان شخصی‌سازی کند. -با این کار، همه داده‌های موجود در کلید ایمنی، ازجمله پین آن، پاک می‌شود +با این کار، همه داده‌های موجود در کلید امنیتی، ازجمله پین آن، پاک می‌شود ‏به‌محض کامل شدن بارگیری، Chromebook شما بازراه‌اندازی خواهد شد و می‌توانید راه‌اندازی را ادامه دهید. صفحات می‌توانید سابقه مرورتان را علاوه‌بر نشانی وب و عنوان صفحه، براساس محتوای کلی صفحه نیز جستجو کنید و نتایج بهتری مشاهده کنید @@ -5862,7 +5862,7 @@ ابزارهای &برنامه نویس {NUM_OF_FILES,plural, =1{یک فایل منتقل شد}one{{NUM_OF_FILES} فایل منتقل شد}other{{NUM_OF_FILES} فایل منتقل شد}} روشن کردن «جفت‌سازی سریع» -کلید ایمنی را وارد و لمس کنید +کلید امنیتی را وارد و لمس کنید لطفاً خود را به منبع نیرو وصل کنید. SSO «رأی موافق» بازخوردی با این معنا ارسال می‌کند که شما این پیشنهاد برگه گروه را می‌پسندید @@ -5897,7 +5897,7 @@ «نقطه اتصال فوری» متصل نشد نمایش کمتر ، جستجوی -پین کلید ایمنی را وارد کنید. اگر پین را نمی‌دانید، باید کلید ایمنی را بازنشانی کنید. +پین کلید امنیتی را وارد کنید. اگر پین را نمی‌دانید، باید کلید امنیتی را بازنشانی کنید. &بازکردن کلید مورداستفاده حساب اصلی @@ -5944,7 +5944,7 @@ جستجو یا تایپ نشانی وب حافظه جابجاشده ۱ چاپگر مدیریت‌شده وجود دارد. -اثرانگشت به کلید ایمنی اضافه کنید یا اثرهای انگشت ذخیره‌شده در آن را حذف کنید +اثرانگشت به کلید امنیتی اضافه کنید یا اثرهای انگشت ذخیره‌شده در آن را حذف کنید گذرواژه در بریده‌دان کپی شد ادامه مسدود کردن دسترسی به دوربین و میکروفن از داده تلفن همراه استفاده می‌کنید @@ -7003,7 +7003,7 @@ صفحه برگه جدیدتان را مدیریت می‌کند ممکن است خطرناک باشد. برای اسکن کردن به «مرور ایمن Google» ارسال شود؟ غیرفعال کردن صفحه لمسی -کلید ایمنی شما نمی‌تواند اثر انگشت دیگری ذخیره کند. برای افزودن مورد جدید، ابتدا یکی از اثر انگشت‌های موجود را حذف کنید. +کلید امنیتی شما نمی‌تواند اثر انگشت دیگری ذخیره کند. برای افزودن مورد جدید، ابتدا یکی از اثر انگشت‌های موجود را حذف کنید. شناسه گزارش دوکلیک با موشواره لغو وارد کردن @@ -7411,7 +7411,7 @@ دسترسی به اطلاعات دستگاه‌های بلوتوث مرتبط شده با سیستم شما و کشف دستگاه‌های بلوتوث در این نزدیکی. نیازی به دسترسی نیست درحال بررسی بارگیری با خط‌مشی‌های امنیتی سازمانتان. -بازنشانی کلید ایمنی +بازنشانی کلید امنیتی مرورگر و نمایه شما تحت‌مدیریت است متمرکز کردن این برگه سرور در دسترس نیست @@ -8157,13 +8157,13 @@ پین می‌تواند ۴ نویسه یا بیشتر داشته باشد در بریده‌دان کپی شد -‏اگر گذرکلید در کلید ایمنی USB قرار دارد، همین‌حالا آن را وارد و لمس کنید +‏اگر گذرکلید در کلید امنیتی USB قرار دارد، همین‌حالا آن را وارد و لمس کنید ‏برای ورود به سیستم این سایت با گذرکلید، باید Windows Hello را در تنظیمات روشن کنید. سپس به این سایت برگردید و دوباره امتحان کنید. اسکن خودکار به شما اجازه می‌دهد به‌طور خودکار بین موارد موجود در صفحه جابه‌جا شوید. وقتی موردی برجسته می‌شود، با فشار دادن «انتخاب» آن را فعال کنید. پاندا پرداز زدن اوه، مشکلی روی داد. -چون چندین‌بار پین اشتباه وارد شده، کلید ایمنی قفل شده است. باید کلید ایمنی را بازنشانی کنید. +چون چندین‌بار پین اشتباه وارد شده، کلید امنیتی قفل شده است. باید کلید امنیتی را بازنشانی کنید. نمایش «فهرست خواندن» ‏برای به پایان رساندن وارد کردن، همه پنجره‌های Firefox را ببندید. ‏caps lock روشن @@ -8182,7 +8182,7 @@ اجازه داده نشود اما بعداً سؤال شود ‏محافظت بی‌وقفه و پیش‌نگر دربرابر سایت‌ها، بارگیری‌ها، و افزونه‌های خطرناک که براساس داده‌های مرور ارسالی به Google است ‏فقط مخاطبینی که «حساب Google» دارند. مشاهده مخاطبین -برای ادامه، کلید ایمنی را وارد کنید و لمس کنید +برای ادامه، کلید امنیتی را وارد کنید و لمس کنید ‏ایجادکننده تصویر سیستم ChromeOS Flex روباه باز کردن در پنجره «حالت ناشناس» @@ -8394,7 +8394,7 @@ این تنظیم در مرورگرهای مدیریت‌شده غیرفعال است ‏درحال فعال کردن ویژگی‌های اشکال‌زدایی ChromeOS هستید؛ با این کار، sshd daemon راه‌اندازی خواهد شد و راه‌اندازی ازطریق درایوهای USB فعال خواهد شد. اختصاص دادن ۱ کلید دیگر -این کلید ایمنی از پین‌ها پشتیبانی نمی‌کند +این کلید امنیتی از پین‌ها پشتیبانی نمی‌کند آستانه تشخیص اشاره بازدید بدون تیکت گروه برگه را انتخاب کنید و منوِ زمینه‌ای را برای ویرایش فعال کنید @@ -8465,7 +8465,7 @@ ‏باید شامل Ctrl،‏ Alt یا Search‌ باشد ‏پشتیبان‌گیری از برنامه‌ها و فایل‌های Linux برای چاپ با ، تأیید هویت لازم است. لطفاً با سرپرست تماس بگیرید. -استفاده از تلفن، رایانه لوحی، یا کلید ایمنی +استفاده از تلفن، رایانه لوحی، یا کلید امنیتی جستجو و پیشنهادها پایگاه‌های داده وب {COUNT,plural, =1{{COUNT} فایل}one{{COUNT} فایل}other{{COUNT} فایل}} @@ -8740,7 +8740,7 @@ حرکت دادن موارد با تک‌ضرب و کشیدن چاپگرهای افزونه هنوز کلیدی تخصیص داده نشده است -پین کنونی‌تان را برای تغییر پین وارد کنید. اگر پین‌ خود را نمی‌دانید، باید کلید ایمنی را بازنشانی کنید و سپس پین جدیدی ایجاد کنید. +پین کنونی‌تان را برای تغییر پین وارد کنید. اگر پین‌ خود را نمی‌دانید، باید کلید امنیتی را بازنشانی کنید و سپس پین جدیدی ایجاد کنید. مجاز است – . دسترسی دوربین سیستم را روشن کنید. درون‌بردن گذرواژه‌ها بخش انتخاب‌شده به نیست @@ -8783,7 +8783,7 @@ کیفیت مرور و جستجو را انتخاب کنید گذرکلید حذف شود؟ × (بهترین) -کلید ایمنی را مجدداً وارد کنید و دوباره امتحان کنید +کلید امنیتی را مجدداً وارد کنید و دوباره امتحان کنید غیرفعال کردن برگه‌ها این تنظیم را در نوار نشانی تغییر دهید. هنگام باز کردن فایل‌ها این برنامه به‌عنوان یکی از گزینه‌ها ارائه شود @@ -9150,7 +9150,7 @@ باز کردن پوشه بارگیری‌ها ‏گفتن «cap» (حرف بزرگ) قبل از حرف راه‌اندازی شبکه جدید -برای استفاده از کلید ایمنی جدید، پین جدیدی تنظیم کنید +برای استفاده از کلید امنیتی جدید، پین جدیدی تنظیم کنید شما باموفقیت برای مدیریت شرکت ثبت شد. به خط‌مشی رازداری این ارائه‌دهنده بروید ‫«» حذف شود؟ @@ -9414,7 +9414,7 @@ انتخاب از فهرست افزودن &پوشه... ‏cryptohome برای برنامه کیوسک نشانده نشد. -نمی‌توان این کلید ایمنی را بازنشانی کرد. خطای . +نمی‌توان این کلید امنیتی را بازنشانی کرد. خطای . «Ok Google» ‏ارتقا دادن Crostini سابقه مرورتان را بااستفاده از زبان روزمره جستجو کنید و سایت‌هایی را که بازدید کرده‌اید پیدا کنید. همچنین می‌توانید سؤال بپرسید و براساس سابقه مرورتان پاسخ دریافت کنید @@ -9616,7 +9616,7 @@ کلمات سفارشی ذخیره‌شده در اینجا نشان داده خواهند شد فهرست موضوعاتی که مسدود کرده‌اید و نمی‌خواهید با سایت‌ها هم‌رسانی شود -دوباره کلید ایمنی خود را لمس کنید +دوباره کلید امنیتی خود را لمس کنید «» از ذخیره نشد {COUNT,plural, =1{ به ارسال شد}one{ به ارسال شد}other{ به ارسال شد}} مشاهده/پشتیبان‌گیری رسانه @@ -9798,7 +9798,7 @@ هیچ صدایی به زبان در دستگاهتان وجود ندارد. به اینترنت متصل شوید و دوباره امتحان کنید. دیدن اطلاعات دستگاه، مانند شماره سریال یا شناسه دارایی آن افزایش اندازه قلم -‏اگر می‌خواهید گذرکلیدی برای در کلید ایمنی USB ایجاد کنید، آن را اکنون وارد و لمس کنید +‏اگر می‌خواهید گذرکلیدی برای در کلید امنیتی USB ایجاد کنید، آن را اکنون وارد و لمس کنید این فایل دارای چندین مجوز است، برخی از آن‌ها وارد نشده‌اند: برگه ناشناس جدید باز کردن نمای کلی پنجره‌ها @@ -10209,7 +10209,7 @@ ممکن است کیفیت رسانه کاهش پیدا کند ‏دکمه اطلاعات بیشتر درباره تصحیح خودکار. به صفحه تنظیمات تصحیح خودکار می‌روید. برای فعال کردن، کلید Enter و برای رد کردن، کلید «گریز» را فشار دهید. به‌زودی وقت خواب است -محافظت از کلید ایمنی بااستفاده از پین (شماره شناسایی شخصی) +محافظت از کلید امنیتی بااستفاده از پین (شماره شناسایی شخصی) بارگیری فایل ناامن &جای‌گذاری دسترسی به میکروفون شما و تجزیه‌وتحلیل گفتار شما @@ -10411,9 +10411,9 @@ کپی آدرس &ایمیل این مراحل عیب‌یابی را دنبال کنید: - مطمئن شوید دستگاهتان حافظه داخلی فعالی داشته باشد، مانند حافظه HDD، ‏SSD، یا eMMC - بررسی کنید حجم دستگاه حافظه داخلی بیشتر از ۱۶ گیگابایت باشد - اگر حافظه داخلی به‌صورت فیزیکی دردسترس است، اتصال آن را بررسی کنید + مطمئن شوید دستگاهتان فضای ذخیره‌سازی داخلی فعالی داشته باشد، مانند حافظه HDD، ‏SSD، یا eMMC + بررسی کنید حجم دستگاه فضای ذخیره‌سازی داخلی بیشتر از ۱۶ گیگابایت باشد + اگر فضای ذخیره‌سازی داخلی به‌صورت فیزیکی دردسترس است، اتصال آن را بررسی کنید مطمئن شوید از مدل تأییدشده‌ای استفاده می‌کنید و نکات نصب را بررسی کنید @@ -10593,7 +10593,7 @@ همیشه مجاز باشد تصاویر را نشان دهد چرخش خودکار ‏برای وارد کردن گذرواژه‌های به ، فایل CSV موردنظر را انتخاب کنید. -کلید ایمنی دیگری را امتحان کنید +کلید امنیتی دیگری را امتحان کنید کیک چوبی سایت‌ها اجازه ندارند در دستگاه داده ذخیره کنند (توصیه نمی‌شود) درصورت ادامه دادن، به اشخاص ثالث اجازه می‌دهید اطلاعاتی را که هویت این دستگاه را در شبکه مشخص می‌کند تأیید کنند. اگر نمی‌خواهید به اشخاص ثالث اجازه دسترسی به اطلاعات دستگاه را بدهید، می‌توانید نمایه سیم‌کارت داخلی را به‌صورت دستی راه‌اندازی کنید. @@ -10650,7 +10650,7 @@ زبانی موجود نیست زمان‌بندی خودکار غروب ‏به برنامه‌های Android اجازه دهید به دستگاه‌های USB در این Chromebook دسترسی داشته باشند. هربار دستگاه USB را وصل کنید، اجازه درخواست خواهد شد. هرکدام از برنامه‌های Android به‌صورت جداگانه اجازه‌های جانبی درخواست خواهند کرد. -کلید ایمنی را تازمانی‌که اثرانگشت ثبت شود، لمس کنید +کلید امنیتی را تازمانی‌که اثرانگشت ثبت شود، لمس کنید ‏برای ادامه دادن، از Touch ID استفاده کنید بارگیری بعدی در تاریخ انجام می‌شود. گذرکلیدها @@ -10761,7 +10761,7 @@ حذف گروه ‏ممکن است خطرناک باشد. برای اسکن کردن به «محافظت پیشرفته Google» ارسال شود؟ دستگاه‌های ذخیره‌شده در حسابتان -نمی‌توان این کلید ایمنی را بازنشانی کرد. بازنشانی این کلید را بلافاصله پس از وارد کردنش امتحان کنید. +نمی‌توان این کلید امنیتی را بازنشانی کرد. بازنشانی این کلید را بلافاصله پس از وارد کردنش امتحان کنید. دسترسی به حسگر همچنان مجاز باشد رویدادهای خطرناک را پیش از اینکه اتفاق بیفتند پیش‌بینی می‌کند و درباره آن‌ها به شما هشدار می‌دهد غیر فعال کردن همگام‌سازی diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_fr-CA.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_fr-CA.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_fr-CA.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_fr-CA.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -4773,7 +4773,7 @@ Menu Extensions Eau glacée Ne jamais traduire les pages rédigées en -Configurer les Contrôles parentaux +Configurer les contrôles parentaux PKCS n° 1 SHA-1 avec chiffrement RSA Vous ne verrez plus La navigation sécurisée est désactivée diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_hi.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_hi.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_hi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_hi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2162,7 +2162,7 @@ {NUM_TABS,plural, =1{ - 1 टैब}one{ - # टैब}other{ - # टैब}} वीएम की स्थिति आपके पास सेव किया गया कोई भी प्रिंटर नहीं है. -'स्पेल चेक' को पसंद के मुताबिक बनाएं +स्पेल चेक को पसंद के मुताबिक बनाएं फ़ाइल शेयर यूआरएल काला (डिफ़ॉल्ट) जगह की जानकारी का ऐक्सेस दिया गया है @@ -2437,7 +2437,7 @@ हे भगवान! फ़ॉर्मेटिंग के दौरान गड़बड़ी आई. बाएं वायरलेस बड में % बैटरी बची है. अन्य ऐप्लिकेशन, की तरह उन लिंक को खोलने के लिए तैयार हैं. यह और को सहायता लिंक खोलने से रोकता है. -'स्पेल चेक' को मैनेज करें +स्पेल चेक को मैनेज करें इस एक्सटेंशन को हटाएं या इसे Chrome Web Store पर मौजूद मिलते-जुलते एक्सटेंशन से बदलें नहीं खोला जा सका इस डिवाइस का इस्तेमाल करने वाले लोग, गुप्त मोड में डाउनलोड की गई फ़ाइलें देख सकते हैं @@ -3146,7 +3146,7 @@ जबड़े को बाईं ओर ले जाएं सिंक सुविधा चालू करें सुरक्षित ब्राउज़िंग (आपकी और आपके डिवाइस की खतरनाक साइट से सुरक्षा करती है) -स्पेलिंग जांच +स्पेल चेक प्रोफ़ाइल आयातकर्ता मोबाइल डेटा नेटवर्क स्कैनर सॉफ़्टवेयर इंस्टॉल नहीं किया जा सका diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_id.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_id.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_id.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_id.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1164,7 +1164,7 @@ Gambar pengguna Cabut akses Terinstal -Tampilan yang diperluas +Layar ekstensi Sembunyikan sandi untuk Kirim masukan untuk membantu kami menyelesaikan masalah ini. Gunakan Klasik @@ -4467,7 +4467,7 @@ Buka UI Aktivasi Seluler Penjelajahan dan penelusuran lebih cepat Buat grup tab baru -Tampilan utama +Layar utama Menghubungkan ke hotspot ponsel Anda secara otomatis. Dilihat dalam seminggu terakhir Aplikasi dan ekstensi diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_ky.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_ky.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_ky.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_ky.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -229,7 +229,7 @@ Күндөн калкалоочу көз айнек сайты түзмөктүн сенсорлорун ар дайым колдоно берсин Аккаунтуңузду ырастоо үчүн сырсөзүңүздү кайрадан киргизиңиз. -Google'дун Өркүндөтүлгөн коргоо программасы +Google'дун Күчөтүлгөн коргоо программасы Телефонуңузга туташууда Google Издөөнүн капталдагы тилкесин жабыңыз Баш тамга менен жазуу @@ -468,7 +468,7 @@ Жарнамаларды жекелештирүүгө таасирин тийгизе турган маалымат өчүрүлдү Өтмөктү тышкы экранга чыгарып жатасыз. Тышкы экранга чыгарууну каалаган убакта тындырып же токтото аласыз. Жүктөлүп алынган файлдар үчүн Chrome'дун эң жогорку коопсуздук деңгээлин пайдалануу максатында мыктылап коргоону караңыз -Өркүндөтүлгөн коргоо күйүк +Күчөтүлгөн коргоо күйүк Камдык көчүрмөсү сакталган Ansible Playbook же Crostini файлынан түзүү Сакталган сырсөздөр бул жерде көрүнөт. Бул түзмөктө сырсөздөрдү кызматына өткөрүп алуу үчүн CSV файлын тандаңыз. , , өчүрүлдү @@ -668,7 +668,7 @@ Байланыш үзүлдү. Интернет байланышын текшерип, дагы аракет кылып көрүңүз. Сайттарды кол менен кошуу Cүрөтчөгө киргизилген өзгөртүүнү карап көрүү - Өркүндөтүлгөн коргоо тарабынан бөгөттөлдү. + Күчөтүлгөн коргоо тарабынан бөгөттөлдү. Сайттарга түзмөктү активдүү колдонуп жатканыңыз тууралуу маалыматты алууга тыюу салуу Каттоо эсептериңиз Байланыштарыңызда болбогон Chromebook менен бөлүшүп жатсаңыз, андагы "Nearby'да көрүнүү" параметрин күйгүзүү керек. Ал үчүн төмөнкү оң бурчту басып, ал параметрди тандаңыз. Кеңири маалымат @@ -1539,7 +1539,7 @@ Портрет Сырсөздөрдү башкаргыч бул вебсайт үчүн татаал сырсөздү түздү Байланыш түйүнүн автоматтык түрдө өчүрүү -HTTPS кеңейтүүсүн мүмкүн болгон учурларда колдонуп, аны колдоого албаган сайттарды жүктөөдөн мурда эскертүү алыңыз. Өркүндөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. +HTTPS кеңейтүүсүн мүмкүн болгон учурларда колдонуп, аны колдоого албаган сайттарды жүктөөдөн мурда эскертүү алыңыз. Күчөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. Башка түзмөктөрүңүздө орнотулган Сенек абалындагы дайындар Google Жардамчынын логотиби @@ -2674,7 +2674,7 @@ Linux'тун камдык көчүрмөсүн сактоо катасы администраторуңуздун прокси параметрлерин колдонуп жатат Теманын коомдук ачкычы -Коопсуз байланышты колдонбогон сайттарга өтүүдөн мурда эскертүү алыңыз. Өркүндөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. +Коопсуз байланышты колдонбогон сайттарга өтүүдөн мурда эскертүү алыңыз. Күчөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. Аккаунтка кирүү барагынан кайтуу Wi-Fi тармагына туташуу бошотулду @@ -6193,7 +6193,7 @@ Chrome'дон сырсөздөрдү экспорттоо Жигерсиз кылуу үчүн өтмөктөр тизмесинен сайтын өчүрүңүз Жардамчыга билдирмелерди көрсөтүүгө уруксат берүү -Өркүндөтүлгөн коргоо күйүк +Күчөтүлгөн коргоо күйүк “Borealis Enabled” белгилөөсүн күйгүзүү керек Корпоративдик түзмөктү каттоо Администраторуңуз бул жаңыртууну аткаргандан кийин уюмуңуздун колдонмолору тезирээк ачылып калат. Бир нече мүнөткө созулушу мүмкүн. @@ -7218,7 +7218,7 @@ сайтына түзмөктөрүн көзөмөлдөөгө жана кайра программалоого ар дайым уруксат берилсин Баштоо менюсу Жаңы колдонмо кошулду () -Бул файлды Өркүндөтүлгөн коргоо бөгөттөдү. +Бул файлды Күчөтүлгөн коргоо бөгөттөдү. Эскертүү: иштеп чыгуучунун нугуна которулуп жатасыз Жанаша турган эки терезени топтоштуруу Google аккаунттары @@ -7524,7 +7524,7 @@ Принтер аныкталган жок. Принтердин дарегин кайра киргизиңиз. Бардык шайкештирилген түзмөктөрүңүздөгү жана Google аккаунтуңуздагы серептөө дайындарын өчүрүү үчүн шайкештирүү параметрлерине өтүңүз. Манжаңыздын изи менен кулпусун тезирээк ачыңыз -Бул файл көп жүктөлүп алынбайт жана Өркүндөтүлгөн коргоо тарабынан бөгөттөлгөн +Бул файл көп жүктөлүп алынбайт жана Күчөтүлгөн коргоо тарабынан бөгөттөлгөн Кыска жолду түзөтүү Авто-ишке киргизүүнү өчүрүп коюу Терезелердин өлчөмү ылдый жакка карай өзгөрдү @@ -10468,7 +10468,7 @@ Ыкчам коштомо жазуулар (англис тилинде гана) IMEI Такта ордунда эмес -Өркүндөтүлгөн коргоо тарабынан бөгөттөлгөн +Күчөтүлгөн коргоо тарабынан бөгөттөлгөн Өзгөртүү Тапшырмалар тактасына кадоо Түзмөгүңүздүн кулпусун ачуу үчүн PIN кодуңузду колдосоңуз болот. @@ -10759,7 +10759,7 @@ 2 секунд Текстти чоңураак кылуу Топту өчүрүү - кооптуу болушу мүмкүн. Google'дун Өркүндөтүлгөн коргоо программасына текшерүү үчүн жөнөтүлсүнбү? + кооптуу болушу мүмкүн. Google'дун Күчөтүлгөн коргоо программасына текшерүү үчүн жөнөтүлсүнбү? Аккаунтуңузда сакталган түзмөктөр Бул коопсуздук ачкычы баштапкы абалга келтирилбей жатат. Ачкычты киргизериңиз менен, баштапкы абалына келтирип көрүңүз. Сенсорду колдонуу мүмкүнчүлүгүнө уруксат бериле берсин diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_ne.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_ne.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_ne.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_ne.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -3997,7 +3997,7 @@ kiosk एप सुरु गर्न सकिएन। यसले सक्छ: SharePoint र OneDrive मा भएका फाइलहरू -स्थापना गर्नुहोस् +इन्स्टल गर्नुहोस् कुनै समस्या आयो। पछि फेरि प्रयास गर्नुहोस् तपाईंको कार्डको म्याद सकियो वटा एक्स्टेन्सन diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_pt-PT.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_pt-PT.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_pt-PT.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_pt-PT.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2572,7 +2572,7 @@ Claro Introduza o PIN para os controlos parentais Co&lar e ir -Pedir ao pai/mãe +Pede aos teus pais Afixar automaticamente novos grupos de separadores criados em qualquer dispositivo à barra de marcadores Não foi possível atualizar o seu Chromebook. Tente mais tarde. poderá editar o ficheiro até fechar todos os separadores deste site. diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_ru.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_ru.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_ru.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_ru.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -4887,7 +4887,7 @@ Удалить данные и разрешения сайта и всех связанных с ним сайтов? Мы переходим к использованию современных веб-приложений вместо приложений Chrome. Это приложение было установлено в браузер вашей организацией. Чтобы открыть современное веб-приложение, попросите администратора удалить приложение Chrome. Пока вы можете открыть расширение "" в браузере, перейдя по адресу . Справочный центр -Разрешить использование сторонних файлов cookie +Принимать сторонние файлы cookie Чтение сведений об устройстве с ChromeOS Flex и данных на нем Зачитать текст естественным голосом Когда вы совершаете жест для клика, скорость указателя мыши снижается, чтобы вам было проще контролировать его положение. Чтобы выполнить клик, используйте жест снова. diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_sl.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_sl.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_sl.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_sl.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -8046,7 +8046,7 @@ &Uredi ... Če želite uporabljati funkcijo , vklopite Bluetooth in Wi-Fi , -Obnovi varnostno kopijo +Obnovi iz varnostne kopije Ta datoteka lahko škoduje vašim osebnim računom in računom v družbenih omrežjih, vključno s tem: Izvajanje diagnostičnih preizkusov za ChromeOS. Potrdilo odjemalca SSL diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_sr-Latn.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr-Latn.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_sr-Latn.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr-Latn.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -445,7 +445,7 @@ Umetnite pametnu karticu da biste ostali prijavljeni Uređaj sa USB priključkom tipa C (levi port) može da se preklapa sa pokretima , i . Probajte da izaberete drugi pokret ako je to moguće. -Datoteke +Fajlovi Ovaj proces može da potraje par minuta. Pokreće se menadžer kontejnera. Organizacija upravlja nalogom Ne prikazuj Google kalendar diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_sr.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_sr.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_sr.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -445,7 +445,7 @@ Уметните паметну картицу да бисте остали пријављени Уређај са USB прикључком типа C (леви порт) може да се преклапа са покретима , и . Пробајте да изаберете други покрет ако је то могуће. -Датотеке +Фајлови Овај процес може да потраје пар минута. Покреће се менаџер контејнера. Организација управља налогом Не приказуј Google календар diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_sv.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_sv.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_sv.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_sv.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -9691,7 +9691,7 @@ Läser in kontouppgifter … {COUNT,plural, =1{ett objekt}other{# objekt}} eSIM -Få en guidad rundtur av viktiga integritets- och säkerhetskontroller. Öppna den enskilda inställningarna för att se fler alternativ. +Få en guidad rundtur av viktiga integritets- och säkerhetskontroller. Öppna de enskilda inställningarna för att se fler alternativ. Duplicera Bluetooth-musen har kopplats Ändra dikteringsspråk diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_sw.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_sw.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_sw.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_sw.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2807,7 +2807,7 @@ haiwezi kutumika. Mandhari yamesasishwa hadi picha iliyopakiwa Hifadhi ya Akiba -Chaguo limehifadhiwa. Chaguo lako litatumika unapoingia kwenye huduma nyingine za Google. +Chaguo limehifadhiwa. Chaguo lako litatumika ukiingia kwenye huduma nyingine za Google. Zinazoruhusiwa kufuatilia mkao wa kamera yako {NUM_SITES,plural, =1{Chrome imeondoa ruhusa kwenye tovuti 1}other{Chrome imeondoa ruhusa kwenye tovuti {NUM_SITES}}} Ilingane na eneo la kuchapishwa @@ -10418,7 +10418,7 @@ Kwa usaidizi zaidi, tembelea: g.co/flex/InstallErrors. Muhtasari wa Makaribisho Imeshindwa kupata sera. -Chrome inaweza kusasisha akaunti yako kwenye tovuti hii kwa kuweka nenosiri thabiti. Hutahitaji kukumbuka nenosiri kwa sababu linahifadhiwa kwa niaba yako kwenye Kidhibiti cha Manenosiri cha Google kwa ajili ya . Maelezo zaidi kuhusu . +Chrome inaweza kusasisha akaunti yako kwenye tovuti hii kwa kuweka nenosiri thabiti. Hutahitaji kukumbuka nenosiri kwa sababu linahifadhiwa kwa niaba yako kwenye Kidhibiti cha Manenosiri cha Google cha . Maelezo zaidi kuhusu . Zisizoruhusiwa kuona mahali ulipo Thibitisha kuwa ni wewe Wasifu wa ziada hauwezi kutumika diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_uk.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_uk.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_uk.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_uk.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -6153,7 +6153,7 @@ Додати сайт Зайва фігурна дужка: Зберегти -Підключити новий пристрій +Зв’язати новий пристрій Нова назва пристрою Видалити групу зі збережених Можливо, сервер недоступний. Спробуйте пізніше. diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_uz.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_uz.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_uz.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_uz.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -4526,7 +4526,7 @@ Ilk sozlamalarni tiklash va zararli fayllarni tozalash Brayl jadvalini tanlang Qaytadan urining. Muammo qaytarilsa, mijozlar xizmatiga murojaat qiling. -saytni sezishingizda shaxsiy maʼlumotlaringizdan foydalanishi mumkin +saytni kezishingizda shaxsiy maʼlumotlaringizdan foydalanishi mumkin Ayrim foydalanuvchilar kirishini cheklash mumkin. Bunda kirish ekranidan “Foydalanuvchi kiritish” tugmasi olib tashlanadi. Shuningdek, joriy foydalanuvchilarni olib tashlash mumkin. O‘rnatilmoqda.. Hammasi saranjom! diff -Nru chromium-134.0.6998.35/chrome/app/resources/generated_resources_vi.xtb chromium-134.0.6998.88/chrome/app/resources/generated_resources_vi.xtb --- chromium-134.0.6998.35/chrome/app/resources/generated_resources_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/generated_resources_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -6883,7 +6883,7 @@ Nâng cấp lên Chromebook mới ngay hôm nay để tiết kiệm 50 USD trở lên Thiết bị đầu cuối Meta bên ngoài -Tắt +Đang tắt Hiện thanh tiêu đề tìm kiếm + ctrl + shift + Bật diff -Nru chromium-134.0.6998.35/chrome/app/resources/google_chrome_strings_ky.xtb chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_ky.xtb --- chromium-134.0.6998.35/chrome/app/resources/google_chrome_strings_ky.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_ky.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -276,7 +276,7 @@ Бул файл жеке жана социалдык тармак аккаунттарыңызга зыян келтириши мүмкүн болгондуктан, Chrome бул жүктөп алууну бөгөттөдү Оңой колдонуу үчүн Google Lens функциясын кадап койсоңуз болот; капталдагы тилкенин жогору жагындагы Кадап коюу баскычын басыңыз Жашыруун режимде серептеп жатканда, Chrome сиз кооптуу туташуу аркылуу сайтты жүктөөдөн мурун эскертет -Өркүндөтүлгөн коргоо параметри фишинг жана кесепеттүү программалардан жакшыраак коргойт +Күчөтүлгөн коргоо параметри фишинг жана кесепеттүү программалардан жакшыраак коргойт Орнотуу катасы: Chrome – Тармакка кирүү – Google Chrome'до башка операция жүрүп жатат. Кийинчерээк дагы аракет кылып көрүңүз. diff -Nru chromium-134.0.6998.35/chrome/app/resources/google_chrome_strings_vi.xtb chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_vi.xtb --- chromium-134.0.6998.35/chrome/app/resources/google_chrome_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/app/resources/google_chrome_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -11,7 +11,7 @@ Tìm kiếm bằng Google Ống kính trước đó đã sử dụng Chrome Đây là Chrome của bạn -Ai đang sử dụng Chrome? +Ai sẽ sử dụng Chrome? Không thể cập nhật Chrome Giới thiệu về ChromeOS &Mở trong Chrome diff -Nru chromium-134.0.6998.35/chrome/browser/about_flags.cc chromium-134.0.6998.88/chrome/browser/about_flags.cc --- chromium-134.0.6998.35/chrome/browser/about_flags.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/about_flags.cc 2025-03-07 21:29:53.000000000 +0000 @@ -96,7 +96,9 @@ #include "components/dom_distiller/core/dom_distiller_features.h" #include "components/dom_distiller/core/dom_distiller_switches.h" #include "components/download/public/common/download_features.h" +#include "components/enterprise/buildflags/buildflags.h" #include "components/enterprise/data_controls/core/browser/features.h" +#include "components/enterprise/obfuscation/core/utils.h" #include "components/error_page/common/error_page_switches.h" #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/feature_list.h" @@ -11811,6 +11813,13 @@ password_manager::features::kMarkAllCredentialsAsLeaked)}, #endif // !BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) + {"enterprise-file-obfuscation", + flag_descriptions::kEnterpriseFileObfuscationName, + flag_descriptions::kEnterpriseFileObfuscationDescription, kOsDesktop, + FEATURE_VALUE_TYPE(enterprise_obfuscation::kEnterpriseFileObfuscation)}, +#endif // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) + // NOTE: Adding a new flag requires adding a corresponding entry to enum // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag // Histograms" in tools/metrics/histograms/README.md (run the diff -Nru chromium-134.0.6998.35/chrome/browser/android/resource_id.h chromium-134.0.6998.88/chrome/browser/android/resource_id.h --- chromium-134.0.6998.35/chrome/browser/android/resource_id.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/android/resource_id.h 2025-03-07 21:29:53.000000000 +0000 @@ -89,6 +89,10 @@ LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_BACK, R.drawable.cvc_icon) LINK_RESOURCE_ID(IDR_CREDIT_CARD_CVC_HINT_FRONT_AMEX, R.drawable.cvc_icon_amex) +// A generic info outline icon. +DECLARE_RESOURCE_ID(IDR_ANDROID_INFO_OUTLINE_LOGO_24DP, + R.drawable.ic_info_outline_grey_24dp) + // About this site resources // Page insights logo is used for Google branded builds only. #if BUILDFLAG(PAGE_INFO_USE_INTERNAL_ANDROID_RESOURCES) diff -Nru chromium-134.0.6998.35/chrome/browser/ash/accessibility/accessibility_manager.cc chromium-134.0.6998.88/chrome/browser/ash/accessibility/accessibility_manager.cc --- chromium-134.0.6998.35/chrome/browser/ash/accessibility/accessibility_manager.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ash/accessibility/accessibility_manager.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1950,8 +1950,7 @@ base::UmaHistogramBoolean( "Accessibility.CrosCursorColor", - prefs->GetInteger(prefs::kAccessibilityCursorColor) != - static_cast(ui::kDefaultCursorColor)); + prefs->GetBoolean(prefs::kAccessibilityCursorColorEnabled)); bool color_correction_enabled = IsColorCorrectionEnabled(); base::UmaHistogramBoolean("Accessibility.CrosColorCorrection", diff -Nru chromium-134.0.6998.35/chrome/browser/ash/crosapi/extension_info_private_ash.cc chromium-134.0.6998.88/chrome/browser/ash/crosapi/extension_info_private_ash.cc --- chromium-134.0.6998.35/chrome/browser/ash/crosapi/extension_info_private_ash.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ash/crosapi/extension_info_private_ash.cc 2025-03-07 21:29:53.000000000 +0000 @@ -117,6 +117,9 @@ // Key which corresponds to the Switch Access A11Y property in JS. const char kPropertySwitchAccessEnabled[] = "a11ySwitchAccessEnabled"; +// Key which corresponds to the cursor color A11Y property in JS. +const char kPropertyCursorColorEnabled[] = "a11yCursorColorEnabled"; + // Key which corresponds to the docked magnifier property in JS. const char kPropertyDockedMagnifierEnabled[] = "a11yDockedMagnifierEnabled"; @@ -228,6 +231,7 @@ ash::prefs::kAccessibilitySelectToSpeakEnabled}, {kPropertySwitchAccessEnabled, ash::prefs::kAccessibilitySwitchAccessEnabled}, + {kPropertyCursorColorEnabled, ash::prefs::kAccessibilityCursorColorEnabled}, {kPropertyDockedMagnifierEnabled, ash::prefs::kDockedMagnifierEnabled}, {kPropertySendFunctionsKeys, ash::prefs::kSendFunctionKeys}}; diff -Nru chromium-134.0.6998.35/chrome/browser/ash/extensions/accessibility_features_apitest.cc chromium-134.0.6998.88/chrome/browser/ash/extensions/accessibility_features_apitest.cc --- chromium-134.0.6998.35/chrome/browser/ash/extensions/accessibility_features_apitest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ash/extensions/accessibility_features_apitest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -135,6 +135,8 @@ return ash::prefs::kAccessibilitySelectToSpeakEnabled; if (feature == "switchAccess") return ash::prefs::kAccessibilitySwitchAccessEnabled; + if (feature == "cursorColor") + return ash::prefs::kAccessibilityCursorColorEnabled; if (feature == "dockedMagnifier") return ash::prefs::kDockedMagnifierEnabled; if (feature == "dictation") @@ -245,10 +247,8 @@ // WARNING: Make sure that features which load Chrome extension are not among // enabled_features (see |Set| test for the reason). std::vector enabled_features = { - "cursorHighlight", - "highContrast", - "largeCursor", - "stickyKeys", + "cursorColor", "cursorHighlight", "highContrast", + "largeCursor", "stickyKeys", }; std::vector disabled_features = { @@ -302,14 +302,9 @@ }; std::vector disabled_features = { - "autoclick", - "caretHighlight", - "focusHighlight", - "screenMagnifier", - "selectToSpeak", - "spokenFeedback", - "switchAccess", - "virtualKeyboard", + "autoclick", "caretHighlight", "cursorColor", + "focusHighlight", "screenMagnifier", "selectToSpeak", + "spokenFeedback", "switchAccess", "virtualKeyboard", }; ASSERT_TRUE( @@ -341,6 +336,7 @@ // would induce loading of Chrome extension. std::vector enabled_features = { "caretHighlight", + "cursorColor", "focusHighlight", "stickyKeys", }; @@ -386,6 +382,7 @@ // enabled_features (see |Set| test for the reason). std::vector enabled_features = { "caretHighlight", + "cursorColor", "focusHighlight", "stickyKeys", }; diff -Nru chromium-134.0.6998.35/chrome/browser/ash/login/demo_mode/demo_login_controller.cc chromium-134.0.6998.88/chrome/browser/ash/login/demo_mode/demo_login_controller.cc --- chromium-134.0.6998.35/chrome/browser/ash/login/demo_mode/demo_login_controller.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ash/login/demo_mode/demo_login_controller.cc 2025-03-07 21:29:53.000000000 +0000 @@ -236,7 +236,7 @@ kMaxResponseSize); } -void LogServerResponseError(std::string error_response, bool is_setup) { +void LogServerResponseError(const std::string& error_response, bool is_setup) { if (error_response.empty()) { return; } @@ -431,7 +431,10 @@ std::move(response_body)); } else { OnSetupDemoAccountError(result); - LogServerResponseError(*response_body, /*is_setup*/ true); + // `response_body` could be nullptr when network is not connected. + if (response_body) { + LogServerResponseError(*response_body, /*is_setup*/ true); + } } } @@ -566,7 +569,10 @@ // Report success to the metrics. DemoSessionMetricsRecorder::Get()->ReportDemoAccountCleanupResult(result); } else { - LogServerResponseError(*response_body, /*is_setup*/ false); + // `response_body` could be nullptr when network is not connected. + if (response_body) { + LogServerResponseError(*response_body, /*is_setup*/ false); + } OnCleanUpDemoAccountError(result); } url_loader_.reset(); diff -Nru chromium-134.0.6998.35/chrome/browser/ash/login/screens/pin_setup_screen.cc chromium-134.0.6998.88/chrome/browser/ash/login/screens/pin_setup_screen.cc --- chromium-134.0.6998.35/chrome/browser/ash/login/screens/pin_setup_screen.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ash/login/screens/pin_setup_screen.cc 2025-03-07 21:29:53.000000000 +0000 @@ -308,10 +308,6 @@ void PinSetupScreen::OnHasLoginSupport(bool login_available) { if (hardware_support_.has_value()) { LOG(WARNING) << "Hardware support for login determined too late."; - // Generate a crash report to investigate this edge case. This is unlikely - // to happen nowadays. - // TODO(b/369749485): Remove once no longer necessary. - base::debug::DumpWithoutCrashing(); return; } diff -Nru chromium-134.0.6998.35/chrome/browser/chromeos/extensions/info_private/info_private_apitest.cc chromium-134.0.6998.88/chrome/browser/chromeos/extensions/info_private/info_private_apitest.cc --- chromium-134.0.6998.35/chrome/browser/chromeos/extensions/info_private/info_private_apitest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/chromeos/extensions/info_private/info_private_apitest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -65,6 +65,7 @@ ASSERT_FALSE( prefs->GetBoolean(ash::prefs::kAccessibilityHighContrastEnabled)); ASSERT_FALSE(prefs->GetBoolean(ash::prefs::kAccessibilityAutoclickEnabled)); + ASSERT_FALSE(prefs->GetBoolean(ash::prefs::kAccessibilityCursorColorEnabled)); ASSERT_FALSE( profile()->GetPrefs()->GetBoolean(ash::prefs::kSendFunctionKeys)); @@ -80,6 +81,7 @@ prefs->GetBoolean(ash::prefs::kAccessibilitySpokenFeedbackEnabled)); ASSERT_TRUE(prefs->GetBoolean(ash::prefs::kAccessibilityHighContrastEnabled)); ASSERT_TRUE(prefs->GetBoolean(ash::prefs::kAccessibilityAutoclickEnabled)); + ASSERT_TRUE(prefs->GetBoolean(ash::prefs::kAccessibilityCursorColorEnabled)); ASSERT_TRUE(prefs->GetBoolean(ash::prefs::kSendFunctionKeys)); } diff -Nru chromium-134.0.6998.35/chrome/browser/extensions/api/settings_private/prefs_util.cc chromium-134.0.6998.88/chrome/browser/extensions/api/settings_private/prefs_util.cc --- chromium-134.0.6998.35/chrome/browser/extensions/api/settings_private/prefs_util.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/extensions/api/settings_private/prefs_util.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1161,6 +1161,8 @@ settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kAccessibilityCaretHighlightEnabled] = settings_api::PrefType::kBoolean; + (*s_allowlist)[ash::prefs::kAccessibilityCursorColorEnabled] = + settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kAccessibilityCursorHighlightEnabled] = settings_api::PrefType::kBoolean; (*s_allowlist)[ash::prefs::kAccessibilityDictationEnabled] = diff -Nru chromium-134.0.6998.35/chrome/browser/extensions/api/tabs/tabs_api.cc chromium-134.0.6998.88/chrome/browser/extensions/api/tabs/tabs_api.cc --- chromium-134.0.6998.35/chrome/browser/extensions/api/tabs/tabs_api.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/extensions/api/tabs/tabs_api.cc 2025-03-07 21:29:53.000000000 +0000 @@ -426,6 +426,12 @@ // Returns whether the given `bounds` intersect with at least 50% of all the // displays. bool WindowBoundsIntersectDisplays(const gfx::Rect& bounds) { + // Bail if `bounds` has an overflown area. + auto checked_area = bounds.size().GetCheckedArea(); + if (!checked_area.IsValid()) { + return false; + } + int intersect_area = 0; for (const auto& display : display::Screen::GetScreen()->GetAllDisplays()) { gfx::Rect display_bounds = display.bounds(); diff -Nru chromium-134.0.6998.35/chrome/browser/extensions/pref_mapping.cc chromium-134.0.6998.88/chrome/browser/extensions/pref_mapping.cc --- chromium-134.0.6998.35/chrome/browser/extensions/pref_mapping.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/extensions/pref_mapping.cc 2025-03-07 21:29:53.000000000 +0000 @@ -109,6 +109,9 @@ {"caretHighlight", ash::prefs::kAccessibilityCaretHighlightEnabled, APIPermissionID::kAccessibilityFeaturesRead, APIPermissionID::kAccessibilityFeaturesModify}, + {"cursorColor", ash::prefs::kAccessibilityCursorColorEnabled, + APIPermissionID::kAccessibilityFeaturesRead, + APIPermissionID::kAccessibilityFeaturesModify}, {"cursorHighlight", ash::prefs::kAccessibilityCursorHighlightEnabled, APIPermissionID::kAccessibilityFeaturesRead, APIPermissionID::kAccessibilityFeaturesModify}, diff -Nru chromium-134.0.6998.35/chrome/browser/flag-metadata.json chromium-134.0.6998.88/chrome/browser/flag-metadata.json --- chromium-134.0.6998.35/chrome/browser/flag-metadata.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/flag-metadata.json 2025-03-07 21:29:53.000000000 +0000 @@ -4280,6 +4280,11 @@ "expiry_milestone": 133 }, { + "name": "enterprise-file-obfuscation", + "owners": ["haihan@google.com", "cbe-cep-eng@google.com" ], + "expiry_milestone": 140 + }, + { "name": "enterprise-real-time-url-check-on-android", "owners": ["thefrog@chromium.org", "chrome-counter-abuse-alerts@google.com" ], "expiry_milestone": 138 diff -Nru chromium-134.0.6998.35/chrome/browser/flag_descriptions.cc chromium-134.0.6998.88/chrome/browser/flag_descriptions.cc --- chromium-134.0.6998.35/chrome/browser/flag_descriptions.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/flag_descriptions.cc 2025-03-07 21:29:53.000000000 +0000 @@ -8207,6 +8207,14 @@ "signed in to Chrome to instead use account capabilities."; #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) +const char kEnterpriseFileObfuscationName[] = "Enterprise File Obfuscation"; +const char kEnterpriseFileObfuscationDescription[] = + "Enables temporary file obfuscation during download for enterprise users. " + "Downloaded files remain obfuscated on disk while WebProtect performs deep " + "scanning, preventing access before verification is complete."; +#endif // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) + // ============================================================================ // Don't just add flags to the end, put them in the right section in // alphabetical order just like the header file. diff -Nru chromium-134.0.6998.35/chrome/browser/flag_descriptions.h chromium-134.0.6998.88/chrome/browser/flag_descriptions.h --- chromium-134.0.6998.35/chrome/browser/flag_descriptions.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/flag_descriptions.h 2025-03-07 21:29:53.000000000 +0000 @@ -12,6 +12,7 @@ #include "build/buildflag.h" #include "chrome/common/buildflags.h" #include "components/compose/buildflags.h" +#include "components/enterprise/buildflags/buildflags.h" #include "components/flags_ui/feature_entry.h" #include "components/nacl/common/buildflags.h" #include "components/paint_preview/buildflags/buildflags.h" @@ -4831,6 +4832,11 @@ extern const char kSupervisedUserForceSigninWithCapabilitiesDescription[]; #endif // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) +extern const char kEnterpriseFileObfuscationName[]; +extern const char kEnterpriseFileObfuscationDescription[]; +#endif // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS) + // ============================================================================ // Don't just add flags to the end, put them in the right section in // alphabetical order. See top instructions for more. diff -Nru chromium-134.0.6998.35/chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.cc chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.cc --- chromium-134.0.6998.35/chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.cc 2025-03-07 21:29:53.000000000 +0000 @@ -4,6 +4,7 @@ #include "chrome/browser/new_tab_page/modules/file_suggestion/microsoft_files_page_handler.h" +#include "base/containers/fixed_flat_map.h" #include "base/files/file_path.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -287,6 +288,22 @@ ] })"; +// The following are used to create file icon urls. +constexpr char kAudioIconPartialPath[] = "audio"; +constexpr char kImagesIconPartialPath[] = "photo"; +constexpr char kVideoIconPartialPath[] = "video"; +constexpr char kCodeIconPartialPath[] = "code"; +constexpr char kVectorIconPartialPath[] = "vector"; +constexpr char kXmlDocumentIconPartialPath[] = "docx"; +constexpr char kXmlPresentationIconPartialPath[] = "pptx"; +constexpr char kXmlSpreadsheetIconPartialPath[] = "xlsx"; +constexpr char kPlainTextIconPartialPath[] = "txt"; +constexpr char kCsvIconPartialPath[] = "csv"; +constexpr char kPdfIconPartialPath[] = "pdf"; +constexpr char kRichTextPartialPath[] = "rtf"; +constexpr char kZipPartialPath[] = "zip"; +constexpr char kXmlPartialPath[] = "xml"; + std::string GetFileExtension(std::string mime_type) { base::FilePath::StringType extension; net::GetPreferredExtensionForMimeType(mime_type, &extension); @@ -304,9 +321,115 @@ return result; } -GURL GetFileIconUrl(std::string extension) { - std::string path = extension + ".png"; - return GURL(kBaseIconUrl).Resolve(path); +// Maps files to their icon url. These are simplified mappings derived from +// https://github.com/microsoft/fluentui/blob/master/packages/react-file-type-icons/src/FileTypeIconMap.ts. +// TODO(crbug.com/397728601): Investigate a better solution for getting file +// icon urls and move solution to a helper file to eliminate duplication of url +// retrieval. +GURL GetFileIconUrl(std::string mime_type) { + const auto kIconMap = + base::MakeFixedFlatMap({ + // Audio files. Copied from `kStandardAudioTypes` in + // net/base/mime_util.cc. + {"audio/aac", kAudioIconPartialPath}, + {"audio/aiff", kAudioIconPartialPath}, + {"audio/amr", kAudioIconPartialPath}, + {"audio/basic", kAudioIconPartialPath}, + {"audio/flac", kAudioIconPartialPath}, + {"audio/midi", kAudioIconPartialPath}, + {"audio/mp3", kAudioIconPartialPath}, + {"audio/mp4", kAudioIconPartialPath}, + {"audio/mpeg", kAudioIconPartialPath}, + {"audio/mpeg3", kAudioIconPartialPath}, + {"audio/ogg", kAudioIconPartialPath}, + {"audio/vorbis", kAudioIconPartialPath}, + {"audio/wav", kAudioIconPartialPath}, + {"audio/webm", kAudioIconPartialPath}, + {"audio/x-m4a", kAudioIconPartialPath}, + {"audio/x-ms-wma", kAudioIconPartialPath}, + {"audio/vnd.rn-realaudio", kAudioIconPartialPath}, + {"audio/vnd.wave", kAudioIconPartialPath}, + // Image files. Copied from `kStandardImageTypes` in + // net/base/mime_util.cc. + {"image/avif", kImagesIconPartialPath}, + {"image/bmp", kImagesIconPartialPath}, + {"image/cis-cod", kImagesIconPartialPath}, + {"image/gif", kImagesIconPartialPath}, + {"image/heic", kImagesIconPartialPath}, + {"image/heif", kImagesIconPartialPath}, + {"image/ief", kImagesIconPartialPath}, + {"image/jpeg", kImagesIconPartialPath}, + {"image/pict", kImagesIconPartialPath}, + {"image/pipeg", kImagesIconPartialPath}, + {"image/png", kImagesIconPartialPath}, + {"image/webp", kImagesIconPartialPath}, + {"image/tiff", kImagesIconPartialPath}, + {"image/vnd.microsoft.icon", kImagesIconPartialPath}, + {"image/x-cmu-raster", kImagesIconPartialPath}, + {"image/x-cmx", kImagesIconPartialPath}, + {"image/x-icon", kImagesIconPartialPath}, + {"image/x-portable-anymap", kImagesIconPartialPath}, + {"image/x-portable-bitmap", kImagesIconPartialPath}, + {"image/x-portable-graymap", kImagesIconPartialPath}, + {"image/x-portable-pixmap", kImagesIconPartialPath}, + {"image/x-rgb", kImagesIconPartialPath}, + {"image/x-xbitmap", kImagesIconPartialPath}, + {"image/x-xpixmap", kImagesIconPartialPath}, + {"image/x-xwindowdump", kImagesIconPartialPath}, + // Video files. Copied from `kStandardVideoTypes` in + // net/base/mime_util.cc. + {"video/avi", kVideoIconPartialPath}, + {"video/divx", kVideoIconPartialPath}, + {"video/flc", kVideoIconPartialPath}, + {"video/mp4", kVideoIconPartialPath}, + {"video/mpeg", kVideoIconPartialPath}, + {"video/ogg", kVideoIconPartialPath}, + {"video/quicktime", kVideoIconPartialPath}, + {"video/sd-video", kVideoIconPartialPath}, + {"video/webm", kVideoIconPartialPath}, + {"video/x-dv", kVideoIconPartialPath}, + {"video/x-m4v", kVideoIconPartialPath}, + {"video/x-mpeg", kVideoIconPartialPath}, + {"video/x-ms-asf", kVideoIconPartialPath}, + {"video/x-ms-wmv", kVideoIconPartialPath}, + // Older versions of Microsoft Office files. + {"application/msword", kXmlDocumentIconPartialPath}, + {"application/vnd.ms-excel", kXmlSpreadsheetIconPartialPath}, + {"application/vnd.ms-powerpoint", kXmlPresentationIconPartialPath}, + // OpenXML files. + {"application/" + "vnd.openxmlformats-officedocument.presentationml.presentation", + kXmlPresentationIconPartialPath}, + {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + kXmlSpreadsheetIconPartialPath}, + {"application/" + "vnd.openxmlformats-officedocument.wordprocessingml.document", + kXmlDocumentIconPartialPath}, + // Other file types. + {"text/plain", kPlainTextIconPartialPath}, + {"application/csv", kCsvIconPartialPath}, + {"text/csv", kCsvIconPartialPath}, + {"application/pdf", kPdfIconPartialPath}, + {"application/rtf", kRichTextPartialPath}, + {"application/epub+zip", kRichTextPartialPath}, + {"application/zip", kZipPartialPath}, + {"text/xml", kXmlPartialPath}, + {"text/css", kCodeIconPartialPath}, + {"text/javascript", kCodeIconPartialPath}, + {"application/json", kCodeIconPartialPath}, + {"application/rdf+xml", kCodeIconPartialPath}, + {"application/rss+xml", kCodeIconPartialPath}, + {"text/x-sh", kCodeIconPartialPath}, + {"application/xhtml+xml", kCodeIconPartialPath}, + {"application/postscript", kVectorIconPartialPath}, + {"image/svg+xml", kVectorIconPartialPath}, + }); + + const auto it = kIconMap.find(mime_type); + if (it != kIconMap.end()) { + return GURL(kBaseIconUrl).Resolve(std::string(it->second) + ".png"); + } + return GURL(); } // Remove the file extension that is appended to the file name. @@ -564,7 +687,11 @@ created_file->id = *id; created_file->justification_text = l10n_util::GetStringUTF8( IDS_NTP_MODULES_MICROSOFT_FILES_TRENDING_JUSTIFICATION_TEXT); - created_file->icon_url = GetFileIconUrl(file_extension); + GURL icon_url = GetFileIconUrl(*mime_type); + if (!icon_url.is_valid()) { + continue; + } + created_file->icon_url = icon_url; created_file->title = *title; created_file->item_url = GURL(*url); created_suggestions.push_back(std::move(created_file)); @@ -686,7 +813,11 @@ created_file->id = *id; // TODO(386385623): Create justification text for file type. created_file->justification_text = "Recently shared or used"; - created_file->icon_url = GetFileIconUrl(file_extension); + GURL icon_url = GetFileIconUrl(*mime_type); + if (!icon_url.is_valid()) { + continue; + } + created_file->icon_url = icon_url; created_file->title = GetFileName(*title, file_extension); created_file->item_url = GURL(*item_url); if (*response_id == "recent") { diff -Nru chromium-134.0.6998.35/chrome/browser/new_tab_page/modules/v2/calendar/outlook_calendar_page_handler.cc chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/v2/calendar/outlook_calendar_page_handler.cc --- chromium-134.0.6998.35/chrome/browser/new_tab_page/modules/v2/calendar/outlook_calendar_page_handler.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/new_tab_page/modules/v2/calendar/outlook_calendar_page_handler.cc 2025-03-07 21:29:53.000000000 +0000 @@ -7,6 +7,7 @@ #include #include +#include "base/containers/fixed_flat_map.h" #include "base/files/file_path.h" #include "base/i18n/time_formatting.h" #include "base/metrics/histogram_functions.h" @@ -149,6 +150,22 @@ constexpr int kMaxResponseSize = 1024 * 1024; +// The following are used to create file icon urls. +constexpr char kAudioIconPartialPath[] = "audio"; +constexpr char kImagesIconPartialPath[] = "photo"; +constexpr char kVideoIconPartialPath[] = "video"; +constexpr char kCodeIconPartialPath[] = "code"; +constexpr char kVectorIconPartialPath[] = "vector"; +constexpr char kXmlDocumentIconPartialPath[] = "docx"; +constexpr char kXmlPresentationIconPartialPath[] = "pptx"; +constexpr char kXmlSpreadsheetIconPartialPath[] = "xlsx"; +constexpr char kPlainTextIconPartialPath[] = "txt"; +constexpr char kCsvIconPartialPath[] = "csv"; +constexpr char kPdfIconPartialPath[] = "pdf"; +constexpr char kRichTextPartialPath[] = "rtf"; +constexpr char kZipPartialPath[] = "zip"; +constexpr char kXmlPartialPath[] = "xml"; + std::string GetFileExtension(std::string mime_type) { base::FilePath::StringType extension; net::GetPreferredExtensionForMimeType(mime_type, &extension); @@ -166,8 +183,115 @@ return result; } -GURL GetIconUrl(std::string extension) { - return GURL(kBaseIconUrl + extension + ".png"); +// Maps files to their icon url. These are simplified mappings derived from +// https://github.com/microsoft/fluentui/blob/master/packages/react-file-type-icons/src/FileTypeIconMap.ts. +// TODO(crbug.com/397728601): Investigate a better solution for getting file +// icon urls and move solution to a helper file to eliminate duplication of url +// retrieval. +GURL GetIconUrl(std::string mime_type) { + const auto kIconMap = + base::MakeFixedFlatMap({ + // Audio files. Copied from `kStandardAudioTypes` in + // net/base/mime_util.cc. + {"audio/aac", kAudioIconPartialPath}, + {"audio/aiff", kAudioIconPartialPath}, + {"audio/amr", kAudioIconPartialPath}, + {"audio/basic", kAudioIconPartialPath}, + {"audio/flac", kAudioIconPartialPath}, + {"audio/midi", kAudioIconPartialPath}, + {"audio/mp3", kAudioIconPartialPath}, + {"audio/mp4", kAudioIconPartialPath}, + {"audio/mpeg", kAudioIconPartialPath}, + {"audio/mpeg3", kAudioIconPartialPath}, + {"audio/ogg", kAudioIconPartialPath}, + {"audio/vorbis", kAudioIconPartialPath}, + {"audio/wav", kAudioIconPartialPath}, + {"audio/webm", kAudioIconPartialPath}, + {"audio/x-m4a", kAudioIconPartialPath}, + {"audio/x-ms-wma", kAudioIconPartialPath}, + {"audio/vnd.rn-realaudio", kAudioIconPartialPath}, + {"audio/vnd.wave", kAudioIconPartialPath}, + // Image files. Copied from `kStandardImageTypes` in + // net/base/mime_util.cc. + {"image/avif", kImagesIconPartialPath}, + {"image/bmp", kImagesIconPartialPath}, + {"image/cis-cod", kImagesIconPartialPath}, + {"image/gif", kImagesIconPartialPath}, + {"image/heic", kImagesIconPartialPath}, + {"image/heif", kImagesIconPartialPath}, + {"image/ief", kImagesIconPartialPath}, + {"image/jpeg", kImagesIconPartialPath}, + {"image/pict", kImagesIconPartialPath}, + {"image/pipeg", kImagesIconPartialPath}, + {"image/png", kImagesIconPartialPath}, + {"image/webp", kImagesIconPartialPath}, + {"image/tiff", kImagesIconPartialPath}, + {"image/vnd.microsoft.icon", kImagesIconPartialPath}, + {"image/x-cmu-raster", kImagesIconPartialPath}, + {"image/x-cmx", kImagesIconPartialPath}, + {"image/x-icon", kImagesIconPartialPath}, + {"image/x-portable-anymap", kImagesIconPartialPath}, + {"image/x-portable-bitmap", kImagesIconPartialPath}, + {"image/x-portable-graymap", kImagesIconPartialPath}, + {"image/x-portable-pixmap", kImagesIconPartialPath}, + {"image/x-rgb", kImagesIconPartialPath}, + {"image/x-xbitmap", kImagesIconPartialPath}, + {"image/x-xpixmap", kImagesIconPartialPath}, + {"image/x-xwindowdump", kImagesIconPartialPath}, + // Video files. Copied from `kStandardVideoTypes` in + // net/base/mime_util.cc. + {"video/avi", kVideoIconPartialPath}, + {"video/divx", kVideoIconPartialPath}, + {"video/flc", kVideoIconPartialPath}, + {"video/mp4", kVideoIconPartialPath}, + {"video/mpeg", kVideoIconPartialPath}, + {"video/ogg", kVideoIconPartialPath}, + {"video/quicktime", kVideoIconPartialPath}, + {"video/sd-video", kVideoIconPartialPath}, + {"video/webm", kVideoIconPartialPath}, + {"video/x-dv", kVideoIconPartialPath}, + {"video/x-m4v", kVideoIconPartialPath}, + {"video/x-mpeg", kVideoIconPartialPath}, + {"video/x-ms-asf", kVideoIconPartialPath}, + {"video/x-ms-wmv", kVideoIconPartialPath}, + // Older versions of Microsoft Office files. + {"application/msword", kXmlDocumentIconPartialPath}, + {"application/vnd.ms-excel", kXmlSpreadsheetIconPartialPath}, + {"pplication/vnd.ms-powerpoint", kXmlPresentationIconPartialPath}, + // OpenXML files. + {"application/" + "vnd.openxmlformats-officedocument.presentationml.presentation", + kXmlPresentationIconPartialPath}, + {"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + kXmlSpreadsheetIconPartialPath}, + {"application/" + "vnd.openxmlformats-officedocument.wordprocessingml.document", + kXmlDocumentIconPartialPath}, + // Other file types. + {"text/plain", kPlainTextIconPartialPath}, + {"application/csv", kCsvIconPartialPath}, + {"text/csv", kCsvIconPartialPath}, + {"application/pdf", kPdfIconPartialPath}, + {"application/rtf", kRichTextPartialPath}, + {"application/epub+zip", kRichTextPartialPath}, + {"application/zip", kZipPartialPath}, + {"text/xml", kXmlPartialPath}, + {"text/css", kCodeIconPartialPath}, + {"text/javascript", kCodeIconPartialPath}, + {"application/json", kCodeIconPartialPath}, + {"application/rdf+xml", kCodeIconPartialPath}, + {"application/rss+xml", kCodeIconPartialPath}, + {"text/x-sh", kCodeIconPartialPath}, + {"application/xhtml+xml", kCodeIconPartialPath}, + {"application/postscript", kVectorIconPartialPath}, + {"image/svg+xml", kVectorIconPartialPath}, + }); + + const auto it = kIconMap.find(mime_type); + if (it != kIconMap.end()) { + return GURL(kBaseIconUrl).Resolve(std::string(it->second) + ".png"); + } + return GURL(); } // The file names in the response are formatted as "name.extension" we @@ -462,7 +586,11 @@ } created_attachment->title = GetFileName(*name, file_extension); - created_attachment->icon_url = GetIconUrl(file_extension); + GURL icon_url = GetIconUrl(*content_type); + if (!icon_url.is_valid()) { + continue; + } + created_attachment->icon_url = icon_url; std::string attachment_url = kBaseAttachmentResourceUrl + *event_id + "/" + *id; // Set `resource_url` prematurely because the request to check whether the diff -Nru chromium-134.0.6998.35/chrome/browser/prefs/browser_prefs.cc chromium-134.0.6998.88/chrome/browser/prefs/browser_prefs.cc --- chromium-134.0.6998.35/chrome/browser/prefs/browser_prefs.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/prefs/browser_prefs.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1116,8 +1116,6 @@ inline const char kLacrosLaunchOnLogin[] = "lacros.launch_on_login"; inline const char kLacrosLaunchSwitch[] = "lacros_launch_switch"; inline const char kLacrosSelection[] = "lacros_selection"; -inline constexpr char kAccessibilityCursorColorEnabled[] = - "settings.a11y.cursor_color_enabled"; #endif // Deprecated 12/2024. @@ -1594,7 +1592,6 @@ registry->RegisterStringPref(kCryptAuthEnrollmentUserPrivateKey, std::string()); registry->RegisterBooleanPref(kLacrosLaunchOnLogin, false); - registry->RegisterBooleanPref(kAccessibilityCursorColorEnabled, false); #endif // Deprecated 12/2024. @@ -2898,7 +2895,6 @@ profile_prefs->ClearPref(kCryptAuthEnrollmentUserPublicKey); profile_prefs->ClearPref(kCryptAuthEnrollmentUserPrivateKey); profile_prefs->ClearPref(kLacrosLaunchOnLogin); - profile_prefs->ClearPref(kAccessibilityCursorColorEnabled); #endif // Added 12/2024. diff -Nru chromium-134.0.6998.35/chrome/browser/prefs/pref_service_incognito_allowlist.cc chromium-134.0.6998.88/chrome/browser/prefs/pref_service_incognito_allowlist.cc --- chromium-134.0.6998.35/chrome/browser/prefs/pref_service_incognito_allowlist.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/prefs/pref_service_incognito_allowlist.cc 2025-03-07 21:29:53.000000000 +0000 @@ -116,6 +116,7 @@ ash::prefs::kAccessibilityCaretHighlightEnabled, ash::prefs::kAccessibilityCaretBlinkInterval, ash::prefs::kAccessibilityCursorHighlightEnabled, + ash::prefs::kAccessibilityCursorColorEnabled, ash::prefs::kAccessibilityCursorColor, ash::prefs::kAccessibilityFocusHighlightEnabled, ash::prefs::kAccessibilitySelectToSpeakEnabled, diff -Nru chromium-134.0.6998.35/chrome/browser/resources/ash/settings/metrics_utils.ts chromium-134.0.6998.88/chrome/browser/resources/ash/settings/metrics_utils.ts --- chromium-134.0.6998.35/chrome/browser/resources/ash/settings/metrics_utils.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/ash/settings/metrics_utils.ts 2025-03-07 21:29:53.000000000 +0000 @@ -121,6 +121,10 @@ setting: Setting.kHighlightCursorWhileMoving, type: PrefType.BOOLEAN, }, + 'settings.a11y.cursor_color_enabled': { + setting: Setting.kEnableCursorColor, + type: PrefType.BOOLEAN, + }, 'settings.a11y.face_gaze.enabled': { setting: Setting.kFaceGaze, type: PrefType.BOOLEAN, diff -Nru chromium-134.0.6998.35/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.html chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.html --- chromium-134.0.6998.35/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.html 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.html 2025-03-07 21:29:53.000000000 +0000 @@ -162,6 +162,7 @@ aria-labelledby="cursorColorOptionsLabel" pref="{{prefs.settings.a11y.cursor_color}}" menu-options="[[cursorColorOptions_]]" + on-settings-control-change="onA11yCursorColorChange_" deep-link-focus-id$="[[Setting.kEnableCursorColor]]"> diff -Nru chromium-134.0.6998.35/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.ts chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.ts --- chromium-134.0.6998.35/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/ash/settings/os_a11y_page/cursor_and_touchpad_page.ts 2025-03-07 21:29:53.000000000 +0000 @@ -40,6 +40,7 @@ import {CursorAndTouchpadPageBrowserProxyImpl} from './cursor_and_touchpad_page_browser_proxy.js'; import {DisableTouchpadMode} from './disable_touchpad_constants.js'; +const DEFAULT_BLACK_CURSOR_COLOR = 0; interface Option { name: string; value: number; @@ -139,7 +140,7 @@ value() { return [ { - value: -0x1000000, // Black + value: DEFAULT_BLACK_CURSOR_COLOR, name: loadTimeData.getString('cursorColorBlack'), }, { @@ -512,6 +513,15 @@ .recordSelectedShowShelfNavigationButtonValue(enabled); } + private onA11yCursorColorChange_(): void { + // Custom cursor color is enabled when the color is not set to black. + const a11yCursorColorOn = + this.getPref('settings.a11y.cursor_color').value !== + DEFAULT_BLACK_CURSOR_COLOR; + this.set( + 'prefs.settings.a11y.cursor_color_enabled.value', a11yCursorColorOn); + } + private showTouchpadEnableMessage_(trackpadMode: number): boolean { return trackpadMode !== DisableTouchpadMode.NEVER; } diff -Nru chromium-134.0.6998.35/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb chromium-134.0.6998.88/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb --- chromium-134.0.6998.35/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -462,7 +462,7 @@ Нема сидро за покажувач Кратенка Се отвора страница со опции -Само за читање +Само за преглед Среднотиркизна Нема претходен наслов на ниво 3 Основни копчиња diff -Nru chromium-134.0.6998.35/chrome/browser/resources/new_tab_page/modules/v2/authentication/microsoft_auth_module.ts chromium-134.0.6998.88/chrome/browser/resources/new_tab_page/modules/v2/authentication/microsoft_auth_module.ts --- chromium-134.0.6998.35/chrome/browser/resources/new_tab_page/modules/v2/authentication/microsoft_auth_module.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/new_tab_page/modules/v2/authentication/microsoft_auth_module.ts 2025-03-07 21:29:53.000000000 +0000 @@ -8,6 +8,7 @@ import {I18nMixinLit, loadTimeData} from '../../../i18n_setup.js'; import type {MicrosoftAuthPageHandlerRemote} from '../../../microsoft_auth.mojom-webui.js'; +import {AuthType} from '../../../ntp_microsoft_auth_shared_ui.mojom-webui.js'; import {ParentTrustedDocumentProxy} from '../../microsoft_auth_frame_connector.js'; import {ModuleDescriptor} from '../../module_descriptor.js'; import type {MenuItem, ModuleHeaderElement} from '../module_header.js'; @@ -106,6 +107,9 @@ const proxyInstance = ParentTrustedDocumentProxy.getInstance(); if (proxyInstance) { proxyInstance.getChildDocument().acquireTokenPopup(); + chrome.metricsPrivate.recordEnumerationValue( + `NewTabPage.MicrosoftAuth.AuthStarted`, AuthType.kPopup, + AuthType.MAX_VALUE + 1); } } } diff -Nru chromium-134.0.6998.35/chrome/browser/resources/settings/people_page/sync_account_control.ts chromium-134.0.6998.88/chrome/browser/resources/settings/people_page/sync_account_control.ts --- chromium-134.0.6998.35/chrome/browser/resources/settings/people_page/sync_account_control.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/settings/people_page/sync_account_control.ts 2025-03-07 21:29:53.000000000 +0000 @@ -247,6 +247,12 @@ return false; } + if (this.hideButtons) { + // When buttons are hidden, only show basic account information. Avoid + // showing the full subtitle because it references the buttons. + return false; + } + if (this.syncStatus.signedInState === SignedInState.SIGNED_IN_PAUSED) { return true; } @@ -426,8 +432,12 @@ * has sync enabled or if the property to hide the banner was explicitly set. */ private shouldHideBanner_(): boolean { + if (this.hideBanner) { + return true; + } + if (!loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled')) { - return this.hideBanner || !!this.syncStatus && this.isSyncing_(); + return !!this.syncStatus && this.isSyncing_(); } if (this.syncStatus && this.syncStatus.hasError && @@ -472,12 +482,16 @@ } private shouldShowTurnOffButton_(): boolean { + if (this.hideButtons) { + return false; + } + if (loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled') && this.syncStatus.statusAction !== StatusAction.NO_ACTION) { return true; } - return !this.hideButtons && !this.showSetupButtons_ && this.isSyncing_(); + return !this.showSetupButtons_ && this.isSyncing_(); } private getTurnOffSyncLabel_(turnOffSync: string): string { @@ -504,6 +518,10 @@ } private shouldShowErrorActionButton_(): boolean { + if (this.hideButtons) { + return false; + } + if (this.embeddedInSubpage && this.syncStatus.statusAction === StatusAction.ENTER_PASSPHRASE) { // In a subpage the passphrase button is not required. @@ -515,14 +533,15 @@ return true; } - return !this.hideButtons && !this.showSetupButtons_ && this.isSyncing_() && + return !this.showSetupButtons_ && this.isSyncing_() && !!this.syncStatus.hasError && this.syncStatus.statusAction !== StatusAction.NO_ACTION; } private shouldShowAccountAwareSigninButton_(): boolean { // Only show the button when user is in sync paused state - return loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled') && + return !this.hideButtons && + loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled') && this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN; } @@ -724,7 +743,7 @@ } private shouldShowSigninPausedButtons_() { - return !!this.syncStatus && + return !this.hideButtons && !!this.syncStatus && this.syncStatus.signedInState === SignedInState.SIGNED_IN_PAUSED; } diff -Nru chromium-134.0.6998.35/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts chromium-134.0.6998.88/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts --- chromium-134.0.6998.35/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts 2025-03-07 21:29:53.000000000 +0000 @@ -402,8 +402,10 @@ event.preventDefault(); event.stopPropagation(); const inputElement = - this.shadowRoot!.querySelector('#input')!; - this.dispatchEvent(this.createInputChangeEvent_(inputElement.value)); + this.shadowRoot!.querySelector('#input'); + if (inputElement) { + this.dispatchEvent(this.createInputChangeEvent_(inputElement.value)); + } } protected onInputBlur_(event: Event) { diff -Nru chromium-134.0.6998.35/chrome/browser/resources/side_panel/read_anything/app.ts chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/app.ts --- chromium-134.0.6998.35/chrome/browser/resources/side_panel/read_anything/app.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/app.ts 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ import {getHtml} from './app.html.js'; import {AppStyleUpdater} from './app_style_updater.js'; import type {SettingsPrefs} from './common.js'; -import {getCurrentSpeechRate, minOverflowLengthToScroll, playFromSelectionTimeout} from './common.js'; +import {getCurrentSpeechRate, isWhitespace, minOverflowLengthToScroll, playFromSelectionTimeout} from './common.js'; import type {LanguageToastElement} from './language_toast.js'; import {ReadAnythingLogger, TimeFrom, TimeTo} from './read_anything_logger.js'; import type {ReadAnythingToolbarElement} from './read_anything_toolbar.js'; @@ -127,6 +127,10 @@ // just the correct index within the current string. // Default is 0. speechUtteranceStartIndex: number; + // If we have to break a string because the text is too long, we need to + // offset future word boundaries within this utterance by this offset so + // that they appear in the correct locations. + tooLongTextOffset: number; } export interface AppElement { @@ -295,12 +299,16 @@ private imagesEnabled: boolean = false; - maxSpeechLength: number = 175; + maxSpeechLengthForRemoteVoices: number = 175; + // This corresponds to what would be more than a 2 second delay between + // sentences. + maxSpeechLengthForWordBoundaries: number = 250; wordBoundaryState: WordBoundaryState = { mode: WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED, speechUtteranceStartIndex: 0, previouslySpokenIndex: 0, + tooLongTextOffset: 0, }; // If the node id of the first text node that should be used by Read Aloud @@ -309,6 +317,10 @@ speechSynthesisLanguage: string; + // Punctuation that is reasonable to splice audio on if text is too long. + private spliceablePunctuationArray = [',', '(', ')', '-', '[', ']', '{', '}']; + + override willUpdate(changedProperties: PropertyValues) { super.willUpdate(changedProperties); @@ -1697,19 +1709,41 @@ // Gets the accessible text boundary for the given string. getAccessibleTextLength(utteranceText: string): number { - // Splicing on commas won't work for all locales, but since this is a - // simple strategy for splicing text in languages that do use commas - // that reduces the need for calling getAccessibleBoundary. + const maxSpeechLength = this.selectedVoice_?.localService ? + this.maxSpeechLengthForWordBoundaries : + this.maxSpeechLengthForRemoteVoices; + + // Splicing on punctuation won't work for all locales, but since this is a + // simple strategy for splicing text in languages that do use these + // characters that reduces the need for calling getAccessibleBoundary. + // Since these characters will be searched for in-order, they should + // be listed in priority order for most likely to be a reasonable splice. // TODO(crub.com/1474951): Investigate if we can utilize comma splices - // directly in the utils methods called by #getAccessibleBoundary. - const lastCommaIndex = - utteranceText.substring(0, this.maxSpeechLength).lastIndexOf(','); - - // To prevent infinite looping, only use the lastCommaIndex if it's not the - // first character. Otherwise, use getAccessibleBoundary to prevent - // repeatedly splicing on the first comma of the same substring. - if (lastCommaIndex > 0) { - return lastCommaIndex; + // and splices on other punctuation directly in the utils methods called by + // #getAccessibleBoundary. + for (let i = 0; i < this.spliceablePunctuationArray.length; i++) { + const punctuationString = this.spliceablePunctuationArray[i]; + let utteranceSubstring = utteranceText.substring(0, maxSpeechLength); + let lastPunctuationIndex = + utteranceSubstring.lastIndexOf(punctuationString); + + // If we're not in a valid splicing position, try to find another + // instance of the current punctuation in the string before moving + // on to the next punctuation. + while (!this.isValidSplicePosition( + lastPunctuationIndex, punctuationString, utteranceSubstring, + maxSpeechLength)) { + utteranceSubstring = utteranceText.substring(0, lastPunctuationIndex); + lastPunctuationIndex = + utteranceSubstring.lastIndexOf(punctuationString); + } + + // To prevent infinite looping, only use the lastCommaIndex if it's not + // the first character. Otherwise, use getAccessibleBoundary to prevent + // repeatedly splicing on the first comma of the same substring. + if (lastPunctuationIndex > 0) { + return lastPunctuationIndex; + } } // TODO(crbug.com/40927698): getAccessibleBoundary breaks on the nearest @@ -1717,19 +1751,49 @@ // it would be preferable to break on the punctuation so the pause in // speech sounds more natural. return chrome.readingMode.getAccessibleBoundary( - utteranceText, this.maxSpeechLength); + utteranceText, maxSpeechLength); + } + + // crbug.com/400786507- If we can't find a better permanent solution for + // long delays between sentences, we should look into using + // phrase highlighting and / or other i18n libraries here to reduce + // duplication and make this more robust. + private isValidSplicePosition( + splicePosition: number, spliceCharacter: string, utteranceText: string, + maxSpeechLength: number): boolean { + if (spliceCharacter !== ',' && spliceCharacter !== '-') { + return true; + } + + if (splicePosition > 0 && splicePosition < maxSpeechLength) { + const previousChar = utteranceText.charAt(splicePosition - 1); + const nextChar = utteranceText.charAt(splicePosition + 1); + // We shouldn't splice on hyphens between two non-whitespace characters. + // e.g. twenty-five or 10-4 + if (spliceCharacter === '-' && !isWhitespace(previousChar) && + !isWhitespace(nextChar)) { + return false; + } + + // If the previous and next characters are both numbers, don't splice + // here to avoid splicing on numbers like 10,000. + if (!isNaN(parseInt(previousChar)) && !isNaN(parseInt(nextChar))) { + return false; + } + } + return true; } private playText(utteranceText: string) { // This check is needed due limits of TTS audio for remote voices. See // crbug.com/1176078 for more details. + // This check is also needed for local voices on Windows, Linux, and Mac + // to reduce the delay between sentences. See crbug.com/395909372. // Since the TTS bug only impacts remote voices, no need to check for // maximum text length if we're using a local voice. If we do somehow // attempt to speak text that's too long, this will be able to be handled // by listening for a text-too-long error in message.onerror. - const isTextTooLong = this.selectedVoice_?.localService ? - false : - utteranceText.length > this.maxSpeechLength; + const isTextTooLong = this.isTextTooLong(utteranceText.length); const endBoundary = isTextTooLong ? this.getAccessibleTextLength(utteranceText) : utteranceText.length; @@ -1781,8 +1845,8 @@ // we can enable the Read Aloud buttons. this.speechEngineLoaded_ = true; - // Reset the isSpeechBeingRepositioned property after speech starts after - // a next / previous button. + // Reset the isSpeechBeingRepositioned property after speech starts + // after a next / previous button. if (this.speechPlayingState.isSpeechBeingRepositioned) { this.speechPlayingState = { ...this.speechPlayingState, @@ -1800,18 +1864,22 @@ message.onend = () => { if (isTextTooLong) { + this.wordBoundaryState = { + ...this.wordBoundaryState, + tooLongTextOffset: + this.wordBoundaryState.tooLongTextOffset + endBoundary, + }; // Since our previous utterance was too long, continue speaking pieces - // of the current utterance until the utterance is complete. The entire - // utterance is highlighted, so there's no need to update highlighting - // until the utterance substring is an acceptable size. + // of the current utterance until the utterance is complete. The + // entire utterance is highlighted, so there's no need to update + // highlighting until the utterance substring is an acceptable size. this.playText(utteranceText.substring(endBoundary)); return; } - // Now that we've finiished reading this utterance, update the Granularity - // state to point to the next one - // Reset the word boundary index whenever we move the granularity - // position. + // Now that we've finiished reading this utterance, update the + // Granularity state to point to the next one Reset the word boundary + // index whenever we move the granularity position. this.resetToDefaultWordBoundaryState(); chrome.readingMode.movePositionToNextGranularity(); // Continue speaking with the next block of text. @@ -1929,7 +1997,8 @@ } updateBoundary(charIndex: number) { - this.wordBoundaryState.previouslySpokenIndex = charIndex; + this.wordBoundaryState.previouslySpokenIndex = + charIndex + this.wordBoundaryState.tooLongTextOffset; this.wordBoundaryState.mode = WordBoundaryMode.BOUNDARY_DETECTED; } @@ -1938,23 +2007,39 @@ this.wordBoundaryState = { previouslySpokenIndex: 0, // If a boundary has been detected, the mode should be reset to - // NO_BOUNDARIES instead of BOUNDARIES_NOT_SUPPORTED because we know word - // boundaries are supported- we just need to clear the current boundary - // state. This allows us to highlight the next word at the start of a - // sentence when playback state changes. - // However, if there's been a change that potentially impacts if word - // boundaries are supported (such as changing the voice), we should - // reset to BOUNDARIES_NOT_SUPPORTED because we don't know yet if word - // boundaries are supported for this voice. + // NO_BOUNDARIES instead of BOUNDARIES_NOT_SUPPORTED because we know + // word boundaries are supported- we just need to clear the current + // boundary state. This allows us to highlight the next word at the + // start of a sentence when playback state changes. However, if there's + // been a change that potentially impacts if word boundaries are + // supported (such as changing the voice), we should reset to + // BOUNDARIES_NOT_SUPPORTED because we don't know yet if word boundaries + // are supported for this voice. mode: ((this.wordBoundaryState.mode === WordBoundaryMode.BOUNDARY_DETECTED) && !possibleWordBoundarySupportChange) ? WordBoundaryMode.NO_BOUNDARIES : WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED, speechUtteranceStartIndex: 0, + tooLongTextOffset: 0, }; } + + private isTextTooLong(textLength: number): boolean { + const maxSpeechLength = this.selectedVoice_?.localService ? + this.maxSpeechLengthForWordBoundaries : + this.maxSpeechLengthForRemoteVoices; + + if (!chrome.readingMode.isChromeOsAsh && this.selectedVoice_ && + isNatural(this.selectedVoice_)) { + return textLength > maxSpeechLength; + } + + return this.selectedVoice_?.localService ? false : + textLength > maxSpeechLength; + } + private extractTextOf(axNodeIds: number[]): string { let utteranceText: string = ''; for (let i = 0; i < axNodeIds.length; i++) { @@ -2050,10 +2135,11 @@ private scrollHighlightIntoView() { // Ensure all the current highlights are in view. - // TODO: b/40927698 - Handle if the highlight is longer than the full height - // of the window (e.g. when font size is very large). Possibly using word - // boundaries to know when we've reached the bottom of the window and need - // to scroll so the rest of the current highlight is showing. + // TODO: crbug.com/40927698 - Handle if the highlight is longer than the + // full height of the window (e.g. when font size is very large). Possibly + // using word boundaries to know when we've reached the bottom of the + // window and need to scroll so the rest of the current highlight is + // showing. assert(this.shadowRoot); const currentHighlights = this.shadowRoot!.querySelectorAll( '.' + currentReadHighlightClass); @@ -2070,7 +2156,8 @@ // scroll the first highlight to the top instead of centering it. firstHighlight.scrollIntoView({block: 'start'}); } else if ((highlightBottom > window.innerHeight) || (highlightTop < 0)) { - // Otherwise center the current highlight if part of it would be cut off. + // Otherwise center the current highlight if part of it would be cut + // off. firstHighlight.scrollIntoView({block: 'center'}); } } @@ -2100,8 +2187,8 @@ const parentOfHighlight = document.createElement('span'); parentOfHighlight.classList.add(parentOfHighlightClass); - // First pull out any text within this node before the highlighted section. - // Since it's already been highlighted, we fade it out. + // First pull out any text within this node before the highlighted + // section. Since it's already been highlighted, we fade it out. const highlightPrefix = currentNode.textContent!.substring(0, highlightStart); if (highlightPrefix.length > 0) { @@ -2177,8 +2264,8 @@ WordBoundaryMode.BOUNDARIES_NOT_SUPPORTED || isEspeak(this.selectedVoice_)) { // Fall back where word highlighting is not possible. Since espeak - // boundaries are different than Google TTS word boundaries, fall back to - // sentence boundaries in that case too. + // boundaries are different than Google TTS word boundaries, fall back + // to sentence boundaries in that case too. return chrome.readingMode.sentenceHighlighting; } @@ -2250,8 +2337,8 @@ toggledLanguage, /* onlyInstallExactGoogleLocaleMatch=*/ true, /* retryIfPreviousInstallFailed= */ true); } else { - // If the language has been deselected, remove the language from the list - // of language packs to download + // If the language has been deselected, remove the language from the + // list of language packs to download const langCodeForVoicePackManager = convertLangOrLocaleForVoicePackManager(toggledLanguage); if (langCodeForVoicePackManager) { @@ -2269,8 +2356,8 @@ chrome.readingMode.onLanguagePrefChange(toggledLanguage, !currentlyEnabled); if (!currentlyEnabled && !this.selectedVoice_) { - // If there were no enabled languages (and thus no selected voice), select - // a voice. + // If there were no enabled languages (and thus no selected voice), + // select a voice. this.getSpeechSynthesisVoice(); } } @@ -2288,7 +2375,8 @@ // Cancel the queued up Utterance using the old speech settings this.stopSpeech(PauseActionSource.VOICE_SETTINGS_CHANGE); - // If speech was playing when a setting was changed, continue playing speech + // If speech was playing when a setting was changed, continue playing + // speech if (playSpeechOnChange) { this.playSpeech(); } @@ -2305,8 +2393,8 @@ // Resets formatting on the current highlight, including previous highlight // formatting. private removeCurrentHighlight() { - // The most recent highlight could have been spread across multiple segments - // so clear the formatting for all of the segments. + // The most recent highlight could have been spread across multiple + // segments so clear the formatting for all of the segments. for (let i = 0; i < chrome.readingMode.getCurrentText().length; i++) { const lastElement = this.previousHighlights_.pop(); if (lastElement) { @@ -2370,9 +2458,9 @@ browserOrPageBaseLang, storedLanguagesPref, this.availableLangs_, this.defaultVoice()?.lang); - // Only update the unavailable languages in prefs if there are any available - // languages. Otherwise, we should wait until the available languages are - // updated to do this. + // Only update the unavailable languages in prefs if there are any + // available languages. Otherwise, we should wait until the available + // languages are updated to do this. if (this.availableLangs_ && this.availableLangs_.length) { this.alignPreferencesWithEnabledLangs_(storedLanguagesPref); } @@ -2390,10 +2478,10 @@ // unavailable between reading mode sessions, we may enable a different // locale instead, and the now unavailable locale can never be removed // by the user, so remove it here and save the newly enabled locale. For - // example if the user previously enabled 'pt-pt' and now it is unavailable, - // createInitialListOfEnabledLanguages above will enable 'pt-br' instead if - // it is available. Thus we should remove 'pt-pt' from preferences here and - // add 'pt-br' below. + // example if the user previously enabled 'pt-pt' and now it is + // unavailable, createInitialListOfEnabledLanguages above will enable + // 'pt-br' instead if it is available. Thus we should remove 'pt-pt' from + // preferences here and add 'pt-br' below. languagesInPref.forEach(storedLanguage => { if (!this.enabledLangs.includes(storedLanguage)) { chrome.readingMode.onLanguagePrefChange(storedLanguage, false); @@ -2560,15 +2648,14 @@ } // Kicks off a workflow to install a voice pack. - // 1) Checks if Language Pack Manager supports a version of this voice/locale - // 2) If so, adds voice to installVoicePackIfPossible set - // 3) Kicks off request GetVoicePackInfo to see if the voice is installed - // 4) Upon response, if we see the voice is not installed and that it's in + // 1) Checks if Language Pack Manager supports a version of this + // voice/locale 2) If so, adds voice to installVoicePackIfPossible set 3) + // Kicks off request GetVoicePackInfo to see if the voice is installed 4) + // Upon response, if we see the voice is not installed and that it's in // installVoicePackIfPossible, then we trigger an install request private installVoicePackIfPossible( langOrLocale: string, onlyInstallExactGoogleLocaleMatch: boolean, retryIfPreviousInstallFailed: boolean) { - // Don't attempt to install a language if it's not a Google TTS language // available for downloading. It's possible for other non-Google TTS // voices to have a valid language code from diff -Nru chromium-134.0.6998.35/chrome/browser/resources/side_panel/read_anything/common.ts chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/common.ts --- chromium-134.0.6998.35/chrome/browser/resources/side_panel/read_anything/common.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/side_panel/read_anything/common.ts 2025-03-07 21:29:53.000000000 +0000 @@ -91,3 +91,8 @@ }); }); } + +// Returns true is the given string can be considered whitespace. +export function isWhitespace(s: string): boolean { + return /\s+/g.test(s); +} diff -Nru chromium-134.0.6998.35/chrome/browser/resources/tab_search/app.ts chromium-134.0.6998.88/chrome/browser/resources/tab_search/app.ts --- chromium-134.0.6998.35/chrome/browser/resources/tab_search/app.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/resources/tab_search/app.ts 2025-03-07 21:29:53.000000000 +0000 @@ -9,7 +9,7 @@ import 'chrome://resources/cr_elements/cr_tabs/cr_tabs.js'; import 'chrome://resources/cr_elements/cr_page_selector/cr_page_selector.js'; -import {assertNotReached} from 'chrome://resources/js/assert.js'; +import {assert, assertNotReached} from 'chrome://resources/js/assert.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js'; @@ -93,14 +93,14 @@ this.apiProxy_.getProfileData().then(({profileData}) => { // In rare cases there is no browser window. I suspect this happens during // browser shutdown. - if (!profileData.windows) { + if (!profileData.windows || profileData.windows.length === 0) { return; } // TODO(crbug.com/40855872): Determine why no active window is reported // in some cases on ChromeOS and Linux. const activeWindow = profileData.windows.find((t) => t.active); - this.availableHeight_ = - activeWindow ? activeWindow!.height : profileData.windows[0]!.height; + assert(profileData.windows[0]); + this.availableHeight_ = (activeWindow ?? profileData.windows[0]).height; }); } diff -Nru chromium-134.0.6998.35/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc chromium-134.0.6998.88/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc --- chromium-134.0.6998.35/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/safe_browsing/tailored_security/consented_message_android.cc 2025-03-07 21:29:53.000000000 +0000 @@ -105,7 +105,7 @@ icon_resource_id = base::FeatureList::IsEnabled(safe_browsing::kEsbAsASyncedSetting) ? ResourceMapper::MapToJavaDrawableId( - IDR_ANDROID_ABOUT_THIS_SITE_LOGO_24DP) + IDR_ANDROID_INFO_OUTLINE_LOGO_24DP) : ResourceMapper::MapToJavaDrawableId( IDR_ANDROID_MESSAGE_SHIELD_GRAY); message_->DisableIconTint(); diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_en-GB.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1827,7 +1827,7 @@ Navigation history is half-opened Chrome Beta You’ll have your history on all your synced devices so that you can continue what you were doing -You can also view and manage these items in your bookmarks, reading list or Password Manager +You can also view and manage these items in your bookmarks, reading list or password manager {NUM_MINS,plural, =1{Checked 1 minute ago}other{Checked # minutes ago}} Deleting 1 file left diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_es.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1222,7 +1222,7 @@ Usar DNS seguro Ahorra hasta un 60 % de datos La contraseña que guardes debe coincidir con tu contraseña de -Vista ordenador +Sitio para ordenadores Orden y visualización Las imágenes se envían a Google para mejorar las descripciones que recibes. Si inicias sesión en Chrome, las contraseñas que guardes se añadirán a tu cuenta de Google. Para desactivar este ajuste, ve a la configuración. diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_et.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1443,7 +1443,7 @@ Voo sisu värskendamiseks tõmmake leht alla Google Lens pole selles seadmes saadaval (värskendati ) -Oodake ... +Palun oodake… Värskendusi pole saadaval Vaadake selle teenusepakkuja privaatsuseeskirju Saate säilitada selle grupi, et lisada vahelehed hiljem, või lahkuda sellest, kui te ei soovi sellele enam juurde pääseda diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_fa.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -556,7 +556,7 @@ محتوای بریده‌دان نشان داده شد به‌روزرسانی تنظیمات گذرواژه لورفته‌ای وجود ندارد -تلفن به‌عنوان کلید ایمنی +تلفن به‌عنوان کلید امنیتی مشکلی پیش آمد. دوباره امتحان کنید. مدیریت علایق و اولویت‌ها همه @@ -736,7 +736,7 @@ بستن برگه در نشانک گذاشته شد {ITEMS_COUNT,plural, =1{‫۱ نشانک}one{‫# نشانک}other{‫# نشانک}} -وقتی دستگاه دیگری را با رمزینه پاسخ‌سریع پیوند دهید، آن دستگاه می‌تواند از این تلفن به‌عنوان کلید ایمنی استفاده کند. اگر دستگاه را بردارید، باید رمزینه پاسخ‌سریع را اسکن کنید تا دوباره پیوند داده شود. +وقتی دستگاه دیگری را با رمزینه پاسخ‌سریع پیوند دهید، آن دستگاه می‌تواند از این تلفن به‌عنوان کلید امنیتی استفاده کند. اگر دستگاه را بردارید، باید رمزینه پاسخ‌سریع را اسکن کنید تا دوباره پیوند داده شود. می‌توانید از حساب در این سایت استفاده کنید. برای ادامه دادن، به وارد شوید. ‏درحال نصب برای Chrome… {BOOKMARK_COUNT,plural, =1{نشانک در «» ذخیره شد. این نشانک فقط در این دستگاه ذخیره شده است.}one{نشانک در «» ذخیره شد. این نشانک فقط در این دستگاه ذخیره شده است.}other{نشانک در «» ذخیره شد. این نشانک فقط در این دستگاه ذخیره شده است.}} @@ -856,7 +856,7 @@ ‏از آنجایی‌که درحال خروج از سیستم حساب مدیریت‌شده توسط هستید، داده‌های Chrome شما از این دستگاه حذف می‌شود. این مورد در حساب Google شما باقی می‌ماند. واقعیت مجازی نتیجه‌ای پیدا نشد -‏اگر به سیستم «حساب Google» یکسانی وارد شده باشید، دستگاه‌های دیگر می‌توانند از این تلفن به‌عنوان کلید ایمنی استفاده کنند. +‏اگر به سیستم «حساب Google» یکسانی وارد شده باشید، دستگاه‌های دیگر می‌توانند از این تلفن به‌عنوان کلید امنیتی استفاده کنند. گروه برگه «» دیگر دردسترس نیست اطلاعات بیشتر... ترجمه این صفحه به زبان‌های دیگر @@ -1235,7 +1235,7 @@ ‏برای کمک به بهبود برنامه، Chrome داده‌های استفاده و ازکارافتادگی را به Google ارسال می‌کند. مدیریت همیشه مسدود شود برداشتن -کنترل کنید کدام دستگاه‌ها می‌توانند بااستفاده از این دستگاه به‌عنوان کلید ایمنی به سیستم وارد شوند. +کنترل کنید کدام دستگاه‌ها می‌توانند بااستفاده از این دستگاه به‌عنوان کلید امنیتی به سیستم وارد شوند. ‏نشانی‌های وبی که بازدید می‌کنید به Google ارسال می‌شود تا پیش‌بینی شود ممکن است بعداً از چه سایت‌هایی بازدید کنید {CONTACT,plural, =1{‏\u2026 و گزینه تماس دیگر}one{‏\u2026 و گزینه تماس دیگر}other{‏\u2026 و گزینه تماس دیگر}} پیش‌نمایش تصویر جدید diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_ky.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -228,7 +228,7 @@ колдонмосунун дайындары Chrome'до дагы бар Жашыруун режимден чыгуу үчүн коё бербей басып туруңуз -HTTPS кеңейтүүсүн мүмкүн болгон учурларда колдонуп, аны колдоого албаган сайттарды жүктөөдөн мурда эскертүү алыңыз. Өркүндөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. +HTTPS кеңейтүүсүн мүмкүн болгон учурларда колдонуп, аны колдоого албаган сайттарды жүктөөдөн мурда эскертүү алыңыз. Күчөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. Сайт тындырылды Уюмуңуз Өркүндөтүлгөн коопсуз серептөөнү күйгүздү {FILE_COUNT,plural, =1{1 файл жүктөлүп алынбай калды}other{# файл жүктөлүп алынбай калды}} @@ -391,7 +391,7 @@ Колдонмолор Google аккаунтуңузда сакталган сырсөздөрдү көрүп, башкарыңыз Бардык жазылуулардан баш тартуу -Коопсуз байланышты колдонбогон сайттарга өтүүдөн мурда эскертүү алыңыз. Өркүндөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. +Коопсуз байланышты колдонбогон сайттарга өтүүдөн мурда эскертүү алыңыз. Күчөтүлгөн коргоо иштетилгендиктен, бул параметрди өзгөртө албайсыз. Түрмөктөгү меню экрандын жарымына чейин ачылды Алмашуу буфериндеги мазмундар жашырылган Параметрлер, Google аккаунтундагы ката @@ -937,7 +937,7 @@ менен пайдалануу Уруксат сурамдары бери сайтар ачылган жок -Өркүндөтүлгөн коргоо күйүк +Күчөтүлгөн коргоо күйүк Пикириңизди билдирип жаткан сайттын URL дареги Google'га жөнөтүлүп, функцияны жакшыртуу үчүн адистер тарабынан каралышы мүмкүн Сиз дароо "" өтмөктөр тобуна кирүү мүмкүнчүлүгүн жоготуп, ал бардык түзмөктөрүңүздөн жок кылынат Google Lens аркылуу издөө Жаңы diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_sv.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1532,7 +1532,7 @@ Skapa ett e-postmeddelande Ta bort alla Körs i Chrome -Få en guidad rundtur av viktiga integritets- och säkerhetskontroller. Öppna den enskilda inställningarna för att se fler alternativ. +Få en guidad rundtur av viktiga integritets- och säkerhetskontroller. Öppna de enskilda inställningarna för att se fler alternativ. Lorem ipsum {FILE_COUNT,plural, =1{1 har blockerats av organisationen}other{# har blockerats av organisationen}} Appen har installerats diff -Nru chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb --- chromium-134.0.6998.35/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/android/strings/translations/android_chrome_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1048,7 +1048,7 @@ Tinh chỉnh: Đã xảy ra lỗi. Không thể cập nhật tính năng Theo dõi giá. Bạn có thể bật hoặc tắt chế độ này trong phần cài đặt. -Tắt +Đang tắt Bật Đang chờ đến lần tải xuống tiếp theo… Tự động gửi số liệu thống kê sử dụng và báo cáo sự cố cho Google diff -Nru chromium-134.0.6998.35/chrome/browser/ui/tabs/tab_strip_model.cc chromium-134.0.6998.88/chrome/browser/ui/tabs/tab_strip_model.cc --- chromium-134.0.6998.35/chrome/browser/ui/tabs/tab_strip_model.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/tabs/tab_strip_model.cc 2025-03-07 21:29:53.000000000 +0000 @@ -2176,7 +2176,10 @@ std::vector TabStripModel::GetIndicesClosedByCommand( int index, ContextMenuCommand id) const { - CHECK(ContainsIndex(index)); + std::vector indices; + if (!ContainsIndex(index)) { + return indices; + } DCHECK(id == CommandCloseTabsToRight || id == CommandCloseOtherTabs); bool is_selected = IsTabSelected(index); int last_unclosed_tab = -1; @@ -2186,7 +2189,6 @@ } // NOTE: callers expect the vector to be sorted in descending order. - std::vector indices; for (int i = count() - 1; i > last_unclosed_tab; --i) { if (i != index && !IsTabPinned(i) && (!is_selected || !IsTabSelected(i))) { indices.push_back(i); diff -Nru chromium-134.0.6998.35/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc chromium-134.0.6998.88/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc --- chromium-134.0.6998.35/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc 2025-03-07 21:29:53.000000000 +0000 @@ -394,14 +394,6 @@ SetID(VIEW_ID_BOOKMARK_BAR); SetProperty(views::kElementIdentifierKey, kBookmarkBarElementId); - // TODO(lgrey): This layer was introduced to support clipping the bookmark - // bar to bounds to prevent it from drawing over the toolbar while animating. - // This is no longer necessary, so the masking was removed; however removing - // the layer now makes the animation jerky (or jerkier). The animation should - // be fixed and, if the layer is no longer necessary, itshould be removed. - // See https://crbug.com/844037. - SetPaintToLayer(); - size_animation_.Reset(1); if (!gfx::Animation::ShouldRenderRichAnimation()) { animations_enabled = false; diff -Nru chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler.cc chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler.cc --- chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler.cc 2025-03-07 21:29:53.000000000 +0000 @@ -6,6 +6,7 @@ #include +#include "base/metrics/histogram_functions.h" #include "chrome/browser/new_tab_page/microsoft_auth/microsoft_auth_service.h" #include "chrome/browser/new_tab_page/microsoft_auth/microsoft_auth_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -32,9 +33,17 @@ auth_service_->ClearAuthData(); } +// TODO(crbug.com/396144770): Update logic to something that simply calls +// `OnAuthStateUpdated` after merges for M134 are complete, instead of the +// renderer calling this and deciding for itself based on the response. void MicrosoftAuthUntrustedPageHandler::GetAuthState( GetAuthStateCallback callback) { - std::move(callback).Run(auth_service_->GetAuthState()); + auto state = auth_service_->GetAuthState(); + if (state == new_tab_page::mojom::AuthState::kNone) { + base::UmaHistogramEnumeration("NewTabPage.MicrosoftAuth.AuthStarted", + new_tab_page::mojom::AuthType::kSilent); + } + std::move(callback).Run(std::move(state)); } void MicrosoftAuthUntrustedPageHandler::SetAccessToken( @@ -50,5 +59,7 @@ new_tab_page::mojom::AuthState auth_state = auth_service_->GetAuthState(); if (auth_state == new_tab_page::mojom::AuthState::kNone) { document_->AcquireTokenSilent(); + base::UmaHistogramEnumeration("NewTabPage.MicrosoftAuth.AuthStarted", + new_tab_page::mojom::AuthType::kSilent); } } diff -Nru chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler_unittest.cc chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler_unittest.cc --- chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler_unittest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_page_handler_unittest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -7,6 +7,7 @@ #include #include "base/test/gmock_move_support.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "chrome/browser/new_tab_page/microsoft_auth/microsoft_auth_service.h" #include "chrome/browser/new_tab_page/microsoft_auth/microsoft_auth_service_factory.h" @@ -90,15 +91,17 @@ mock_document_.BindAndGetRemote(), profile_.get()); } - MicrosoftAuthUntrustedPageHandler& handler() { return *handler_; } - MockMicrosoftAuthService& mock_auth_service() { return *mock_auth_service_; } - MockDocument& mock_document() { return mock_document_; } MicrosoftAuthServiceObserver& auth_service_observer() { return *auth_service_observer_; } + MicrosoftAuthUntrustedPageHandler& handler() { return *handler_; } + base::HistogramTester& histogram_tester() { return histogram_tester_; } + MockMicrosoftAuthService& mock_auth_service() { return *mock_auth_service_; } + MockDocument& mock_document() { return mock_document_; } private: testing::NiceMock mock_document_; + base::HistogramTester histogram_tester_; // NOTE: The initialization order of these members matters. content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; @@ -125,6 +128,24 @@ handler().GetAuthState(callback.Get()); EXPECT_EQ(state, new_tab_page::mojom::AuthState::kSuccess); + histogram_tester().ExpectBucketCount("NewTabPage.MicrosoftAuth.AuthStarted", + new_tab_page::mojom::AuthType::kSilent, + 0); +} + +TEST_F(NtpMicrosoftAuthUntrustedPageHandlerTest, GetAuthStateNone) { + base::MockCallback + callback; + new_tab_page::mojom::AuthState state; + EXPECT_CALL(callback, Run).WillOnce(MoveArg<0>(&state)); + ON_CALL(mock_auth_service(), GetAuthState) + .WillByDefault(testing::Return(new_tab_page::mojom::AuthState::kNone)); + + handler().GetAuthState(callback.Get()); + EXPECT_EQ(state, new_tab_page::mojom::AuthState::kNone); + histogram_tester().ExpectBucketCount("NewTabPage.MicrosoftAuth.AuthStarted", + new_tab_page::mojom::AuthType::kSilent, + 1); } TEST_F(NtpMicrosoftAuthUntrustedPageHandlerTest, SetAccessToken) { @@ -155,4 +176,7 @@ EXPECT_CALL(mock_document(), AcquireTokenSilent); auth_service_observer().OnAuthStateUpdated(); + histogram_tester().ExpectBucketCount("NewTabPage.MicrosoftAuth.AuthStarted", + new_tab_page::mojom::AuthType::kSilent, + 1); } diff -Nru chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_shared_ui.mojom chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_shared_ui.mojom --- chromium-134.0.6998.35/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_shared_ui.mojom 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chrome/browser/ui/webui/ntp_microsoft_auth/ntp_microsoft_auth_shared_ui.mojom 2025-03-07 21:29:53.000000000 +0000 @@ -4,6 +4,13 @@ module new_tab_page.mojom; +// Enum for use in NewTabPage.MicrosoftAuth.AuthStarted histogram. +// Must match the NTPMicrosoftAuthType enum. +enum AuthType { + kSilent, + kPopup, +}; + // Interfaces for inter-frame communication between chrome:// and its embedded // chrome-untrusted:// child document. diff -Nru chromium-134.0.6998.35/chromeos/CHROMEOS_LKGM chromium-134.0.6998.88/chromeos/CHROMEOS_LKGM --- chromium-134.0.6998.35/chromeos/CHROMEOS_LKGM 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chromeos/CHROMEOS_LKGM 2025-03-07 21:29:53.000000000 +0000 @@ -1 +1 @@ -16181.24.0 \ No newline at end of file +16181.34.0 \ No newline at end of file diff -Nru chromium-134.0.6998.35/chromeos/strings/chromeos_strings_et.xtb chromium-134.0.6998.88/chromeos/strings/chromeos_strings_et.xtb --- chromium-134.0.6998.35/chromeos/strings/chromeos_strings_et.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chromeos/strings/chromeos_strings_et.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -394,7 +394,7 @@ Luba tume värvirežiim esmaspäeval Kogu printimisajaloo kustutamine -Oodake ... +Palun oodake ... Ok Jagatud EAP 2. etapi autentimine diff -Nru chromium-134.0.6998.35/chromeos/strings/chromeos_strings_vi.xtb chromium-134.0.6998.88/chromeos/strings/chromeos_strings_vi.xtb --- chromium-134.0.6998.35/chromeos/strings/chromeos_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chromeos/strings/chromeos_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1015,7 +1015,7 @@ () Album trong Phòng tranh Không có phím tắt này. Nhấn vào một phím tắt mới không có . -Tắt +Đang tắt Bật Tải mô hình chép lời xuống Bật để chọn trong số các lựa chọn diff -Nru chromium-134.0.6998.35/chromeos/ui/frame/frame_header.cc chromium-134.0.6998.88/chromeos/ui/frame/frame_header.cc --- chromium-134.0.6998.35/chromeos/ui/frame/frame_header.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/chromeos/ui/frame/frame_header.cc 2025-03-07 21:29:53.000000000 +0000 @@ -4,9 +4,9 @@ #include "chromeos/ui/frame/frame_header.h" -#include #include +#include "base/logging.h" // DCHECK #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/caption_buttons/frame_center_button.h" #include "chromeos/ui/frame/frame_utils.h" @@ -24,9 +24,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/font_list.h" -#include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" #include "ui/gfx/scoped_canvas.h" #include "ui/views/background.h" #include "ui/views/view.h" @@ -302,11 +300,8 @@ return; } - // If the frame header's radius is reduced, the area encompassing the - // curvature of both corners must be repainted. - view_->SchedulePaintInRect( - gfx::Rect(view_->width(), std::max(radius, corner_radius_))); corner_radius_ = radius; + view_->SchedulePaint(); } void FrameHeader::SetLeftHeaderView(views::View* left_header_view) { diff -Nru chromium-134.0.6998.35/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator.cc chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator.cc --- chromium-134.0.6998.35/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator.cc 2025-03-07 21:29:53.000000000 +0000 @@ -563,6 +563,7 @@ // `NAME_FULL` as main text, unless in field by field filling mode. FieldType main_text_field_type = GroupTypeOfFieldType(trigger_field_type) == FieldTypeGroup::kName && + !IsAlternativeNameType(trigger_field_type) && suggestion_type != SuggestionType::kAddressFieldByFieldFilling && base::FeatureList::IsEnabled(features::kAutofillImprovedLabels) && !features::kAutofillImprovedLabelsParamWithoutMainTextChangesParam diff -Nru chromium-134.0.6998.35/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator_unittest.cc chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator_unittest.cc --- chromium-134.0.6998.35/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator_unittest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/autofill/core/browser/suggestions/addresses/address_suggestion_generator_unittest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -871,6 +871,33 @@ profile.GetRawInfo(NAME_FULL), Suggestion::Text::IsPrimary(true)))); } +// Tests that suggestions for alternative name fields have the alternative name +// as the main text. +TEST_F(AddressLabelSuggestionGeneratorTest, + CreateSuggestionsFromProfiles_AlternativeNameFieldMainText) { + base::test::ScopedFeatureList features; + features.InitWithFeatures({features::kAutofillImprovedLabels, + features::kAutofillSupportPhoneticNameForJP}, + {}); + AutofillProfile profile(AddressCountryCode("JP")); + test::SetProfileInfo(&profile, "firstName", "middleName", "lastName", + "mail@mail.com", "company", "line1", "line2", "city", + "state", "zip", "JP", "phone"); + profile.SetRawInfo(ALTERNATIVE_GIVEN_NAME, u"あおい"); + profile.SetRawInfo(ALTERNATIVE_FAMILY_NAME, u"やまもと"); + profile.FinalizeAfterImport(); + + // Suggestions for alternative name fields should have the alternative name + // as the main text. + EXPECT_THAT(CreateSuggestionsFromProfilesForTest( + {profile}, {ALTERNATIVE_GIVEN_NAME, ALTERNATIVE_FAMILY_NAME}, + SuggestionType::kAddressEntry, ALTERNATIVE_GIVEN_NAME, + /*trigger_field_max_length=*/0), + SuggestionVectorMainTextsAre( + Suggestion::Text(profile.GetRawInfo(ALTERNATIVE_GIVEN_NAME), + Suggestion::Text::IsPrimary(true)))); +} + // Suggestions for `ADDRESS_HOME_LINE1` should have `NAME_FULL` as the label. // Suggestions for name or address fields which do not include // `ADDRESS_HOME_LINE1` should have `ADDRESS_HOME_LINE1` as the label. diff -Nru chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb --- chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_es.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -388,7 +388,7 @@ Última visita: hace días Ver más Usar notificaciones más discretas (bloquea las notificaciones emergentes para que no te interrumpan) -Vista ordenador +Sitio para ordenadores {COUNT,plural, =1{Cookies permitidas en sitio de }other{Cookies permitidas en sitios de }}  GB Contenido protegido diff -Nru chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb --- chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_fa.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -355,7 +355,7 @@ بیشتر بدانید هرگاه روشن باشد، سایت‌ها می‌توانند استفاده از دستگاه‌های بلوتوث را درخواست کنند. هرگاه خاموش باشد، سایت‌ها نمی‌توانند از دستگاه‌های بلوتوث استفاده کنند. اتصال شما به این سایت امن نیست -افزودن سایتی به استثناها +افزودن سایت استثناشده موارد استثنا {DAYS,plural, =1{‏Chrome کوکی‌ها را فردا دوباره مسدود خواهد کرد}one{کوکی‌ها # روز دیگر دوباره مسدود خواهد شد}other{کوکی‌ها # روز دیگر دوباره مسدود خواهد شد}} کوکی‌های طرف سوم محدود شده است diff -Nru chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb --- chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_ru.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -227,7 +227,7 @@ Сегодня Chrome снова ограничит использование файлов cookie Все сайты с доменом Блокировать передачу на сайты информации об использовании устройства -Разрешить использование сторонних файлов cookie +Принимать сторонние файлы cookie Chrome запрещает сайтам использовать сторонние файлы cookie для отслеживания ваших действий в интернете. Управлять доступом к сторонним файлам cookie можно в настройках. Всплывающие окна и переадресация Это действие удалит все локальные данные сайта , включая файлы cookie, и сбросит все его разрешения. diff -Nru chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb --- chromium-134.0.6998.35/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/browser_ui/strings/android/translations/browser_ui_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -329,7 +329,7 @@ Quyền Khi bạn bật tuỳ chọn này, các trang web có thể yêu cầu xem văn bản và hình ảnh đã lưu vào bảng nhớ tạm. Khi bạn tắt tuỳ chọn này, các trang web không thể xem văn bản hoặc hình ảnh đã lưu vào bảng nhớ tạm. Khi bạn bật tuỳ chọn này, các trang web có thể yêu cầu gửi thông báo. Khi bạn tắt tuỳ chọn này, các trang web không thể gửi thông báo. -Tắt +Đang tắt Bật Tạm dừng video Thu gọn tất cả yêu cầu diff -Nru chromium-134.0.6998.35/components/certificate_transparency/data/log_list.json chromium-134.0.6998.88/components/certificate_transparency/data/log_list.json --- chromium-134.0.6998.35/components/certificate_transparency/data/log_list.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/certificate_transparency/data/log_list.json 2025-03-07 21:29:53.000000000 +0000 @@ -1,6 +1,6 @@ { - "version": "51.22", - "log_list_timestamp": "2025-02-24T12:55:23Z", + "version": "51.35", + "log_list_timestamp": "2025-03-07T12:53:53Z", "operators": [ { "name": "Google", diff -Nru chromium-134.0.6998.35/components/policy/resources/policy_templates_id.xtb chromium-134.0.6998.88/components/policy/resources/policy_templates_id.xtb --- chromium-134.0.6998.35/components/policy/resources/policy_templates_id.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/policy/resources/policy_templates_id.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -4602,7 +4602,7 @@ Jika kebijakan disetel ke Nonaktif atau tidak disetel, perilaku default akan diterapkan. Perhatikan bahwa fitur ini hanya didukung di dalam lingkungan jaringan internal Google. -Izinkan pengguna untuk memutuskan +Izinkan pengguna menentukan Menyetel kebijakan ini akan menentukan Aplikasi Web Terisolasi (IWA) mana yang dapat terhubung ke kartu smart menggunakan Web Smart Card API tanpa meminta izin kepada pengguna. Kebijakan ini tidak menerima karakter pengganti. Kebijakan ini menggantikan ; khususnya, nilai daftar yang tidak diizinkan berarti bahwa semua IWA tidak akan dapat terhubung ke pembaca kartu smart (pengguna bahkan tidak akan dimintai izin) kecuali untuk IWA yang tercantum dalam kebijakan ini. diff -Nru chromium-134.0.6998.35/components/policy/resources/policy_templates_nl.xtb chromium-134.0.6998.88/components/policy/resources/policy_templates_nl.xtb --- chromium-134.0.6998.35/components/policy/resources/policy_templates_nl.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/policy/resources/policy_templates_nl.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1460,7 +1460,7 @@ De gebruiker om toestemming vragen om plug-ins uit te voeren waarvoor machtiging is vereist Rapportage van gebruiks- en crashgegevens aanzetten Uitlogknop niet tonen in systeemvak -Hiermee worden vooraf ingevulde Kerberos-accounts toegevoegd. Als de Kerberos-gegevens overeenkomen met de inloggegevens, kun je een account instellen om de inloggegevens opnieuw te gebruiken door '' en '' op te geven voor respectievelijk het hoofdaccount en wachtwoord. Hierdoor kan het Kerberos-ticket automatisch kan worden opgehaald, tenzij verificatie in 2 stappen is ingesteld. Gebruikers kunnen accounts die zijn toegevoegd via dit beleid niet aanpassen. +Hiermee worden vooraf ingevulde Kerberos-accounts toegevoegd. Als de Kerberos-gegevens overeenkomen met de inloggegevens, kun je een account instellen om de inloggegevens opnieuw te gebruiken door '' en '' op te geven voor respectievelijk het hoofdaccount en wachtwoord. Hierdoor kan het Kerberos-ticket automatisch kan worden opgehaald, tenzij tweefactorauthenticatie is ingesteld. Gebruikers kunnen accounts die zijn toegevoegd via dit beleid niet aanpassen. Als dit beleid aanstaat, wordt de lijst met accounts die is gespecificeerd door het beleid, toegevoegd aan de instellingen voor Kerberos-accounts. @@ -3866,7 +3866,7 @@ Als je het beleid instelt op 2, worden advertenties geblokkeerd op alle sites met opdringerige advertenties. De functie EphemeralNetworkPolicies aanzetten. -Geïntegreerde modus voor authenticatie met twee factoren +Geïntegreerde modus voor tweefactorauthenticatie Lijst met afgedwongen geïnstalleerde web-apps instellen Import van opgeslagen wachtwoorden bij eerste uitvoering uitzetten Dit beleid is beëindigd in M53 en is verwijderd in M54, omdat de ondersteuning voor SPDY/3.1 is verwijderd. @@ -7857,7 +7857,7 @@ Dit beleid is alleen van toepassing op nieuwe verbindingspogingen en maakt bestaande verbindingen niet ongeldig. Monochroom afdrukken aanzetten Hiermee kun je aangeven of websites op een onbeveiligde manier verzoeken mogen sturen naar netwerkeindpunten die meer privé zijn. -Verificatie in 2 stappen aanzetten voor hosts voor externe toegang +Tweefactorauthenticatie aanzetten voor hosts voor externe toegang Als je dit beleid instelt, wordt de handhaving van vereisten voor openbaarmaking via Certificaattransparantie uitgezet voor een lijst van -hashes. Enterprise-hosts kunnen certificaten blijven gebruiken die anders niet zouden worden vertrouwd (omdat deze niet op de juiste manier openbaar zijn gemaakt). Als je de handhaving wilt uitzetten, moet de hash aan een van de volgende voorwaarden voldoen: * De hash maakt deel uit van een van het servercertificaat. @@ -8255,7 +8255,7 @@ Vermeld domeinen die zijn uitgesloten voor omzetting via DNS-over-HTTPS Toestaan dat alle pop-ups die zijn geopend met het doel , interactie hebben met de pagina die het openen van de pop-up heeft aangevraagd, tenzij de openende pagina expliciet geen toestemming geeft voor dergelijke interactie Toestaan dat gebruikers screenshots en video-opnamen maken -Geeft aan hoe de ingebouwde Secure Element-hardware kan worden gebruikt voor authenticatie met meerdere factoren, indien de hardware geschikt is voor deze functie. De aan/uit-knop van de machine wordt gebruikt om de fysieke aanwezigheid van de gebruiker te detecteren. +Geeft aan hoe de ingebouwde Secure Element-hardware kan worden gebruikt voor tweefactorauthenticatie, indien de hardware geschikt is voor deze functie. De aan/uit-knop van de machine wordt gebruikt om de fysieke aanwezigheid van de gebruiker te detecteren. Als Uitgezet is geselecteerd, wordt er geen tweede factor verstrekt. @@ -8446,7 +8446,7 @@ Beëindiging van processen in Taakbeheer aanzetten Bepaalt of de functie Wachtwoord onthouden aanstaat in het dialoogvenster voor Kerberos-verificatie. Wachtwoorden worden versleuteld opgeslagen op een schijf, alleen toegankelijk voor de systeemdaemon van Kerberos en tijdens een gebruikerssessie. -Als je dit beleid toepast of niet instelt, kunnen gebruikers besluiten of Kerberos-wachtwoorden worden onthouden, zodat deze niet opnieuw hoeven worden ingevoerd. Kerberos-tickets worden automatisch opgehaald tenzij aanvullende verificatie vereist is (verificatie in 2 stappen). +Als je dit beleid toepast of niet instelt, kunnen gebruikers besluiten of Kerberos-wachtwoorden worden onthouden, zodat deze niet opnieuw hoeven worden ingevoerd. Kerberos-tickets worden automatisch opgehaald tenzij aanvullende verificatie vereist is (tweefactorauthenticatie). Als je dit beleid niet toepast, worden wachtwoorden nooit onthouden en worden alle eerder opgeslagen wachtwoorden verwijderd. Gebruikers moeten elke keer dat ze zich moeten laten verifiëren bij het Kerberos-systeem, hun wachtwoord invoeren. Afhankelijk van de serverinstelling gebeurt dit normaal elke 8 uur tot een aantal maanden. Instellingen voor JavaScript @@ -9186,11 +9186,11 @@ Percentage voor schermhelderheid als er op netvoeding wordt gewerkt Toestaan dat apparaten een gebruiken op Extensies die het bevestigingsdialoogvenster mogen overslaan als ze afdruktaken sturen via chrome.printing API -Hiermee zet je verificatie in 2 stappen aan in plaats van een door de gebruiker gedefinieerde pincode voor hosts voor externe toegang. +Hiermee zet je tweefactorauthenticatie aan in plaats van een door de gebruiker gedefinieerde pincode voor hosts voor externe toegang. Als deze instelling aanstaat, moeten gebruikers een geldige code in 2 stappen opgeven wanneer ze toegang willen krijgen tot een host. - Als deze instelling uitstaat of niet is ingesteld, wordt verificatie in 2 stappen niet aangezet en wordt het standaardgedrag van een door de gebruiker gedefinieerde pincode gebruikt. + Als deze instelling uitstaat of niet is ingesteld, wordt tweefactorauthenticatie niet aangezet en wordt het standaardgedrag van een door de gebruiker gedefinieerde pincode gebruikt. Als je dit beleid toepast of niet instelt, kunnen gebruikers klikken door waarschuwingspagina's die door worden getoond als gebruikers naar sites gaan die SSL-fouten bevatten. Als je het beleid niet toepast, kunnen gebruikers niet door waarschuwingspagina's klikken. diff -Nru chromium-134.0.6998.35/components/policy/resources/policy_templates_zh-CN.xtb chromium-134.0.6998.88/components/policy/resources/policy_templates_zh-CN.xtb --- chromium-134.0.6998.35/components/policy/resources/policy_templates_zh-CN.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/policy/resources/policy_templates_zh-CN.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2479,7 +2479,7 @@ 允许所有 HTTP 身份验证的来源列表 允许用户使用“即时网络共享”功能 允许用户将电话号码从 Chrome 发送到 Android 设备 -停用 Google 云端硬盘同步 +停用 Google 云端硬盘同步功能 企业资料分离设置 关机 停用 GIF 支持。 diff -Nru chromium-134.0.6998.35/components/strings/components_strings_ca.xtb chromium-134.0.6998.88/components/strings/components_strings_ca.xtb --- chromium-134.0.6998.35/components/strings/components_strings_ca.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/components_strings_ca.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -2640,7 +2640,7 @@ 7 darrers dies Baixades automàtiques Alimentació per tracció -Identificador de l'informe d'error penjat: +Identificador de l'informe de bloqueig penjat: L'URL no inclou la cadena de substitució necessària: Adreça electrònica Una carpeta intel·ligent nova que et permet desar totes les teves pàgines de compra en un sol lloc i fer un seguiment automàtic dels preus, obtenir estadístiques de preus i més. diff -Nru chromium-134.0.6998.35/components/strings/components_strings_fa.xtb chromium-134.0.6998.88/components/strings/components_strings_fa.xtb --- chromium-134.0.6998.35/components/strings/components_strings_fa.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/components_strings_fa.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -8,7 +8,7 @@ بار کردن صفحه در فرصتی دیگر درحال آماده‌سازی فایل‌ها درحال واگرداندن نتیجه -جزئیات بیشتری ارائه دهید +جزئیات اضافی ارائه دهید خاموش ‏علت این مشکل وجود یکی از گواهی‌هایی است که شما یا فردی دیگر در دستگاهتان نصب کرده‌اید. از این گواهی برای نظارت بر شبکه‌ها و رهگیری آن‌ها استفاده می‌شود و مورداعتماد Chromium نیست. علی‌رغم وجود برخی موارد قانونی برای نظارت، مثلاً نظارت بر شبکه‌های مدارس و شرکت‌ها، Chromium می‌خواهد مطمئن شود که شما از این جریان آگاهی دارید، حتی اگر نتوانید آن را متوقف کنید. نظارت ممکن است در هر مرورگر یا برنامه‌ای که به وب دسترسی دارد انجام شود. گاهی‌اوقات مهاجمان با ایجاد تغییراتی بسیار جزئی در نشانی وب، سایت‌ها را جعل می‌کنند. @@ -4558,7 +4558,7 @@ اطلاعات بیشتری نیاز است خلاصه سفارش اگر قیمت محصولاتی که پیگیری می‌کنید در هر سایتی کاهش پیدا کند، ایمیلی به ارسال می‌شود. -خط‌مشی ساعت‌های خاموشی: +خط‌مشی ساعات خاموشی: موسیقی کارائیبی و رگِی پیوست‌ها جستجوی سابقه، با بهره‌گیری از هوش مصنوعی diff -Nru chromium-134.0.6998.35/components/strings/components_strings_ne.xtb chromium-134.0.6998.88/components/strings/components_strings_ne.xtb --- chromium-134.0.6998.35/components/strings/components_strings_ne.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/components_strings_ne.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1595,7 +1595,7 @@ ब्लुटुथ उपकरणहरू "" सँग सबैभन्दा बढी मिल्दाजुल्दा परिणाम आकार १६ -स्थापना गर्नुहोस् +इन्स्टल गर्नुहोस् एपहरू अदलबदल नगरिकनै भुक्तानी गर्नुहोस् ( x इन्च) प्रशंसकको जमात भएका तथा इन्डी चलचित्रहरू diff -Nru chromium-134.0.6998.35/components/strings/components_strings_zh-CN.xtb chromium-134.0.6998.88/components/strings/components_strings_zh-CN.xtb --- chromium-134.0.6998.35/components/strings/components_strings_zh-CN.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/components_strings_zh-CN.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1850,7 +1850,7 @@ 餐馆外卖服务 可以询问能否使用和移动您的摄像头 8 x 13 英寸 -Chrome 会在 30 天内自动删除可建议广告的主题和网站。您也可屏蔽不喜欢的特定主题和网站。 +Chrome 会在 30 天内自动删除可提供广告建议的主题和网站。您也可屏蔽不喜欢的特定主题和网站。 有效 标签 您尝试访问的网站上的攻击者可能会诱使您安装软件或泄露某些信息,例如您的密码、手机号码或信用卡号码。 diff -Nru chromium-134.0.6998.35/components/strings/privacy_sandbox_strings_ne.xtb chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ne.xtb --- chromium-134.0.6998.35/components/strings/privacy_sandbox_strings_ne.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ne.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -1,25 +1,68 @@ +"साइटले सिफारिस गर्ने विज्ञापनहरू" अन गरिएका खण्डमा साइटहरूले तपाईंको ब्राउजिङ हिस्ट्री तथा पहिचान सुरक्षित राखेर तपाईंलाई सान्दर्भिक विज्ञापनहरू देखाउन पाउँछन्। अन्य साइटहरूले तपाईं विभिन्न साइटहरूमा कसरी समय बिताउनुहुन्छ भन्नेलगायतका तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गरेर तपाईंले विभिन्न साइटहरू ब्राउज गर्दै गर्दा तपाईंलाई सम्बन्धित विज्ञापनहरू सिफारिस गर्न सक्छन्। तपाईं सेटिङमा गई यी साइटहरूको सूची हेर्न सक्नुहुन्छ। साथै, तपाईं जुन जुन साइटबाट विज्ञापनका सिफारिस प्राप्त गर्न चाहनुहुन्न तपाईं ती साइटहरू ब्लक गर्न पनि सक्नुहुन्छ। +Chromium ले तपाईंले साइटहरूसँग सेयर गर्ने क्रियाकलापसम्बन्धी सबै जानकारी ३० दिनपछि मेटाउँछ। तपाईं कुनै साइटमा फेरि जानुभयो भने उक्त साइट यो सूचीमा फेरि देखिन सक्छ। Chromium मा विज्ञापनको गोपनीयता व्यवस्थापन गर्ने तरिकाका बारेमा थप जान्नुहोस्। Chrome ले तपाईंको हालसालैको ब्राउजिङ हिस्ट्रीका आधारमा तपाईंका रुचिका विषयहरू थाहा पाउँछ +के कस्ता जानकारी प्रयोग गरिन्छ? तपाईंका विज्ञापनका विषयहरू तपाईंको हालसालैको ब्राउजिङ हिस्ट्री अर्थात् तपाईंले यो डिभाइसमा Chrome प्रयोग गरी खोलेका साइटहरूको सूचीमा आधारित हुन्छन्। +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर Google ले तपाईंको जानकारी कसरी सुरक्षित राख्छ भन्ने बारेमा थप जान्नुहोस्। +साइटहरूले यो जानकारी कसरी प्रयोग गर्छन्? तपाईं ब्राउज गर्दै गर्दा Chrome ले तपाईंलाई रुचि लाग्ने विषयहरू थाहा पाउँछ। विषयका लेबलहरू पहिले नै तोकिएका हुन्छन् र यसअन्तर्गत कला तथा मनोरञ्जन, किनमेल तथा खेलकुदलगायतका कुराहरू समावेश हुन्छन्। तपाईंले यसपछि खोल्ने साइटले तपाईंलाई देखाइने विज्ञापनहरू पर्सनलाइज गर्ने प्रयोजनका लागि Chrome सँग तपाईंका केही विषयसम्बन्धी जानकारी माग्न सक्छ। +तपाईं विज्ञापनको गोपनीयतासम्बन्धी सेटिङमा गई यी कुरा परिवर्तन गर्न सक्नुहुन्छ +उदाहरणका लागि, तपाईं बेलुकाको खानाका पाकविधिहरू भेट्टाउनका निम्ति कुनै साइटमा जानुभयो भने उक्त साइटले तपाईं पाक कलामा रुचि राख्नुहुन्छ भन्ने कुरा बुझ्न सक्छ। पछि, अर्को साइटले तपाईंलाई पहिलो साइटले सिफारिस गरेअनुसार फलफूल तथा सागसब्जी डेलिभरी गर्ने सेवासँग सम्बन्धित विज्ञापन देखाउन सक्छ। +विज्ञापनको गोपनीयता कायम राख्नेसम्बन्धी सुविधाहरूले वेबसाइट र तिनका विज्ञापन साझेदारहरूले तपाईंलाई पर्सनलाइज गरिएका विज्ञापन देखाउँदा तपाईंका बारेमा थाहा पाउने जानकारी सीमित पार्न सघाउँछन्। +तपाईं यो जानकारी कसरी व्यवस्थापन गर्न सक्नुहुन्छ? Chrome ले ३० दिनभन्दा पुराना साइटहरू स्वतः मेटाउँछ। तपाईंले कुनै साइटमा फेरि जानुभयो भने उक्त साइट यो सूचीमा फेरि देखिन सक्छ। तपाईं जुनसुकै बेला Chrome का सेटिङमा गई कुनै साइटले तपाईंलाई विज्ञापन सिफारिस गर्न नपाउने गरी उक्त साइट ब्लक गर्न र "साइटले सिफारिस गर्ने विज्ञापनहरू" अफ गर्न सक्नुहुन्छ। Google को गोपनीयता नीति +विज्ञापनको गोपनीयता व्यवस्थापन गर्ने तरिकाका बारेमा थप जान्नुहोस् +साइट र तिनका विज्ञापन साझेदारहरू विज्ञापनहरू पर्सनलाइज गर्ने प्रयोजनका लागि तपाईं आफूले खोलेका साइटहरूमा कसरी समय बिताउनुहुन्छ भन्नेलगायतका तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन् +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर थप जान्नुहोस् Chromium ले तपाईंको हालसालैको ब्राउजिङ हिस्ट्रीका आधारमा तपाईंका रुचिका विषयहरू थाहा पाउँछ +तपाईं आफूले नचाहेका साइटहरू ब्लक गर्न सक्नुहुन्छ। Chromium ले उक्त सूचीमा भएका ३० दिनभन्दा पुराना साइटहरू पनि स्वतः मेटाउँछ। तेस्रो पक्षीय कुकीहरू सीमित गरिएका छन् +तपाईंलाई देखाइने कुनै विज्ञापन पर्सनलाइज गरिन्छ कि गरिँदैन भन्ने कुरा यो सेटिङ, साइटले सिफारिस गर्ने विज्ञापन, तपाईंले तय गर्ने कुकीसम्बन्धी सेटिङ र तपाईंले हेरिरहनुभएको साइटले विज्ञापन पर्सनलाइज गर्छ कि गर्दैन भन्ने कुरालगायतका सेटिङमा भर पर्न सक्छ। +विज्ञापनको पर्फर्मेन्स मापन गर्ने सुविधा तपाईंले Chrome मा साइन इन गरेका बेला यो सेटिङले तपाईंको IP एड्रेस गोप्य राख्न मद्दत गर्छ। Chrome लाई कुनै साइटले तपाईंलाई ट्र्याक गरिरहेको शङ्का लागेमा तपाईंका केही ट्राफिक प्राइभेसी सर्भरहरूमार्फत पठाइन सक्छ। IP सुरक्षाले कसरी काम गर्छ भन्ने बारेमा थप जान्नुहोस् +Chromium ले तपाईंले साइटहरूसँग सेयर गर्ने क्रियाकलापसम्बन्धी सबै जानकारी ३० दिनपछि मेटाउँछ। तपाईं कुनै साइटमा फेरि जानुभयो भने उक्त साइट यो सूचीमा फेरि देखिन सक्छ। Chromium मा विज्ञापनको गोपनीयता व्यवस्थापन गर्ने तरिकाका बारेमा थप जान्नुहोस्। +"विज्ञापनको पर्फर्मेन्स मापन गर्ने सुविधा" अन गरिएका खण्डमा साइटहरूका विज्ञापनहरूको पर्फर्मेन्स मापन गर्ने प्रयोजनका लागि साइटहरूका बिचमा तपाईंले कुनै साइट खोलेपछि सामग्री खरिद गर्नुभयो कि गर्नुभएन भन्नेलगायतका सीमित प्रकारका जानकारी सेयर गरिन्छ। आफ्नो IP एड्रेस लुकाउने सुविधाका बारेमा थप जान्नुहोस् +साइटहरूले तपाईंको डेटा कसरी प्रयोग गर्छन् +साइटले सिफारिस गर्ने विज्ञापनका बारेमा थप जान्नुहोस् +तपाईं आफूले नचाहेका साइटहरू ब्लक गर्न सक्नुहुन्छ। Chrome ले उक्त सूचीमा भएका ३० दिनभन्दा पुराना साइटहरू पनि स्वतः मेटाउँछ। पछाडि +Chrome ले तपाईंले साइटहरूसँग सेयर गर्ने क्रियाकलापसम्बन्धी सबै जानकारी ३० दिनपछि मेटाउँछ। तपाईं कुनै साइटमा फेरि जानुभयो भने उक्त साइट यो सूचीमा फेरि देखिन सक्छ। Chrome मा विज्ञापनको गोपनीयता व्यवस्थापन गर्ने तरिकाका बारेमा थप जान्नुहोस्। +साइटले सिफारिस गर्ने विज्ञापनहरू। +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर थप जान्नुहोस्। ४ हप्ताभन्दा पुराना विज्ञापनका विषयहरू स्वतः मेटाइन्छन्। विषयमा खेलकुद, लत्ताकपडालगायतका कुरा समावेश हुन्छन् विज्ञापनका विषयहरू विज्ञापनका विषयहरू भनेका साइटले विज्ञापन पर्सनलाइज गर्न प्रयोग गर्न सक्ने थुप्रै कुरामध्येको एक कुरा मात्र हो। तपाईंले "विज्ञापनका विषयहरू" अफ गर्नुभयो भने पनि साइटहरू तपाईंलाई विज्ञापन देखाउन सक्छन् तर ती विज्ञापन कम सान्दर्भिक हुन सक्छन्। विज्ञापनको गोपनीयता व्यवस्थापन गर्ने सम्बन्धमा थप जान्नुहोस्। +तपाईंलाई देखाइने कुनै विज्ञापन पर्सनलाइज गरिन्छ कि गरिँदैन भन्ने कुरा यो सेटिङ, साइटले सिफारिस गर्ने विज्ञापन, तपाईंले तय गर्ने कुकीसम्बन्धी सेटिङ र तपाईंले हेरिरहनुभएको साइटले विज्ञापन पर्सनलाइज गर्छ कि गर्दैन भन्ने कुरालगायतका सेटिङमा भर पर्न सक्छ। हाम्रो गोपनीयता नीति पढेर Google ले तपाईंको जानकारी कसरी सुरक्षित राख्छ भन्ने बारेमा थप जान्नुहोस्। +तपाईंलाई देखाइने कुनै विज्ञापन पर्सनलाइज गरिन्छ कि गरिँदैन भन्ने कुरा यो सेटिङ, विज्ञापनका विषय, तपाईंले तय गर्ने कुकीसम्बन्धी सेटिङ र तपाईंले हेरिरहनुभएको साइटले विज्ञापन पर्सनलाइज गर्छ कि गर्दैन भन्ने कुरालगायतका सेटिङमा भर पर्न सक्छ। तपाईं Chromium का सेटिङमा गई आफ्ना विज्ञापनका विषयहरू हेर्न र आफूले साइटहरूसँग सेयर गर्न नचाहेका विषय ब्लक गर्न सक्नुहुन्छ आफ्नो IP एड्रेस लुकाउनुहोस् +साइटले सिफारिस गर्ने विज्ञापनहरू तपाईं Chrome का सेटिङमा गई आफ्ना विज्ञापनका विषयहरू हेर्न र आफूले साइटहरूसँग सेयर गर्न नचाहेका विषय ब्लक गर्न सक्नुहुन्छ +साइटले विज्ञापनहरू सिफारिस गर्ने प्रयोजनका लागि तपाईंको गतिविधिसम्बन्धी जानकारीलगायतका कुराहरू प्रयोग गर्न सक्छ। "साइटले सिफारिस गर्ने विज्ञापनहरू" अफ गरिएका बेला साइटहरूले अझै पनि तपाईंलाई विज्ञापन देखाउन सक्छन् तर ती विज्ञापन भने कम पर्सनलाइज गरिएका हुन सक्छन्। निम्न कुराका बारेमा थप जान्नुहोस्: +साइट र तिनका विज्ञापन साझेदारहरू अन्य साइटमा विज्ञापनहरू पर्सनलाइज गर्ने प्रयोजनका लागि तपाईं आफूले खोलेका साइटहरूमा कसरी समय बिताउनुहुन्छ भन्नेलगायतका तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। उदाहरणका लागि, तपाईं बेलुकाको खानाका पाकविधिहरू भेट्टाउनका निम्ति कुनै साइटमा जानुभयो भने उक्त साइटले तपाईं पाक कलामा रुचि राख्नुहुन्छ भन्ने कुरा बुझ्न सक्छ। पछि, अर्को साइटले तपाईंलाई पहिलो साइटले सिफारिस गरेअनुसार फलफूल तथा सागसब्जी डेलिभरी गर्ने सेवासँग सम्बन्धित विज्ञापन देखाउन सक्छ। तपाईंले खोल्ने साइटहरूले तपाईंलाई सान्दर्भिक विज्ञापनहरू देखाउनका निम्ति तपाईंको ब्राउजिङ हिस्ट्री र पहिचान सुरक्षित राख्दै Chromium सँग तपाईंलाई मन पर्ने विषयहरूसम्बन्धी जानकारी माग्न सक्छन् +साइटले विज्ञापनहरू सिफारिस गर्ने प्रयोजनका लागि तपाईंको गतिविधिसम्बन्धी जानकारीलगायतका कुराहरू प्रयोग गर्न सक्छ। "साइटले सिफारिस गर्ने विज्ञापनहरू" अफ गरिएका बेला साइटहरूले अझै पनि तपाईंलाई विज्ञापन देखाउन सक्छन् तर ती विज्ञापन भने कम पर्सनलाइज गरिएका हुन सक्छन्। साइटले सिफारिस गर्ने विज्ञापनका बारेमा थप जान्नुहोस्। +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर थप जान्नुहोस्। +साइटहरूले यो जानकारी कसरी प्रयोग गर्छन्? तपाईंले खोल्ने साइटहरूले आफ्ना विज्ञापनको पर्फर्मेन्स मापन गर्न Chrome सँग जानकारी माग्न सक्छन्। Chrome ले साइटहरूले एक अर्काका बिचमा सेयर गर्न सक्ने जानकारी सीमित पारेर तपाईंको गोपनीयता सुरक्षित राख्छ। हाम्रो गोपनीयता नीति पढेर Google ले तपाईंको जानकारी कसरी सुरक्षित राख्छ भन्ने बारेमा थप जान्नुहोस्। तपाईंले खोल्ने साइटहरूले तपाईंलाई सान्दर्भिक विज्ञापनहरू देखाउनका निम्ति तपाईंको ब्राउजिङ हिस्ट्री र पहिचान सुरक्षित राख्दै Chrome सँग तपाईंलाई मन पर्ने विषयहरूसम्बन्धी जानकारी माग्न सक्छन् तेस्रो पक्षीय कुकीहरू सीमित गरिएका छन् +"साइटले सिफारिस गर्ने विज्ञापनहरू" अन गरिएका खण्डमा साइटहरूले तपाईंको ब्राउजिङ हिस्ट्री तथा पहिचान सुरक्षित राखेर तपाईंलाई सान्दर्भिक विज्ञापनहरू देखाउन पाउँछन्। अन्य साइटले तपाईंले विभिन्न साइटहरू ब्राउज गर्दै गर्दा सम्बन्धित विज्ञापनहरू सिफारिस गर्न सक्छन्। तपाईं सेटिङमा गई यी साइटहरूको सूची हेर्न सक्नुहुन्छ। साथै, तपाईं जुन जुन साइटबाट विज्ञापनका सिफारिस प्राप्त गर्न चाहनुहुन्न तपाईं ती साइटहरू ब्लक गर्न पनि सक्नुहुन्छ। तपाईंले Chromium मा साइन इन गरेका बेला यो सेटिङले तपाईंको IP एड्रेस गोप्य राख्न मद्दत गर्छ। Chromium लाई कुनै साइटले तपाईंलाई ट्र्याक गरिरहेको शङ्का लागेमा तपाईंका केही ट्राफिक प्राइभेसी सर्भरहरूमार्फत पठाइन सक्छ। IP सुरक्षाले कसरी काम गर्छ भन्ने बारेमा थप जान्नुहोस् हाम्रो गोपनीयता नीति पढेर Google ले तपाईंको जानकारी कसरी सुरक्षित राख्छ भन्ने बारेमा थप जान्नुहोस्। +"विज्ञापनका विषयहरू" अन गरिएका खण्डमा वेबसाइटहरूले तपाईंको ब्राउजिङ हिस्ट्री तथा पहिचान सुरक्षित राखेर तपाईंलाई सान्दर्भिक विज्ञापनहरू देखाउन सक्छन्। Chrome ले तपाईंको हालसालैको ब्राउजिङ हिस्ट्रीका आधारमा तपाईंका रुचिका विषयहरू थाहा पाउन सक्छ। तपाईंले यसपछि खोल्ने साइटले तपाईंलाई देखाइने विज्ञापनहरू पर्सनलाइज गर्ने प्रयोजनका लागि Chrome सँग सान्दर्भिक विषयसम्बन्धी जानकारी माग्न सक्छ। +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर थप जान्नुहोस्। +तपाईंलाई देखाइने कुनै विज्ञापन पर्सनलाइज गरिन्छ कि गरिँदैन भन्ने कुरा यो सेटिङ, विज्ञापनका विषय, तपाईंले तय गर्ने कुकीसम्बन्धी सेटिङ र तपाईंले हेरिरहनुभएको साइटले विज्ञापन पर्सनलाइज गर्छ कि गर्दैन भन्ने कुरालगायतका सेटिङमा भर पर्न सक्छ। +विज्ञापनको पर्फर्मेन्स मापन गर्ने सुविधाका बारेमा थप जानकारी +Chrome ले तपाईंले साइटहरूसँग सेयर गर्ने क्रियाकलापसम्बन्धी सबै जानकारी ३० दिनपछि मेटाउँछ। तपाईं कुनै साइटमा फेरि जानुभयो भने उक्त साइट यो सूचीमा फेरि देखिन सक्छ। Chrome मा विज्ञापनको गोपनीयता व्यवस्थापन गर्ने तरिकाका बारेमा थप जान्नुहोस्। विज्ञापनका विषयसम्बन्धी आफूले तय गरेको सेटिङको समीक्षा गर्नुहोस् +साइटले सिफारिस गर्ने विज्ञापनका बारेमा थप जानकारी +तपाईंले खोल्ने साइटले यो जानकारी (तपाईंका विज्ञापनका विषय वा तपाईंले खोलेका साइटले सिफारिस गर्ने विज्ञापनहरू) माग्न सक्छ। +गोपनीयता नीति नयाँ ट्याबमा खुल्छ +तपाईं यो जानकारी कसरी व्यवस्थापन गर्न सक्नुहुन्छ? Chrome ले ४ हप्ताभन्दा पुराना विषयहरू स्वतः मेटाउँछ। तपाईंले विभिन्न साइटहरू ब्राउज गरिराख्ने क्रममा कुनै विषय यो सूचीमा फेरि देखिन सक्छ। तपाईं जुनसुकै बेला Chrome का सेटिङमा गई तपाईं Chrome ले साइटहरूसँग जुन जुन विषयहरू सेयर नगरोस् भन्ने चाहनुहुन्छ ती विषय ब्लक गर्नुका साथै "विज्ञापनका विषयहरू" अफ गर्न पनि सक्नुहुन्छ। +साइटहरूले यो जानकारी कसरी प्रयोग गर्छन्? साइट र तिनका विज्ञापन साझेदारहरू अन्य साइटमा विज्ञापनहरू पर्सनलाइज गर्ने प्रयोजनका लागि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। उदाहरणका लागि, तपाईं बेलुकाको खानाका पाकविधिहरू भेट्टाउनका निम्ति कुनै साइटमा जानुभयो भने उक्त साइटले तपाईं पाक कलामा रुचि राख्नुहुन्छ भन्ने कुरा बुझ्न सक्छ। पछि, अर्को साइटले तपाईंलाई पहिलो साइटले सिफारिस गरेअनुसार फलफूल तथा सागसब्जी डेलिभरी गर्ने सेवासँग सम्बन्धित विज्ञापन देखाउन सक्छ। +Google को नियमअनुसार कम्पनीहरूले उनीहरू विभिन्न साइटमा तपाईंलाई ट्र्याक गर्ने प्रयोजनका लागि यो जानकारी प्रयोग गर्दैनन् भन्ने कुरा सार्वजनिक रूपमा उल्लेख गर्नु पर्ने हुन्छ। केही साइटले विज्ञापनका अतिरिक्त अन्य सुविधा पर्सनलाइज गर्न पनि तपाईंको गतिविधिसम्बन्धी जानकारी प्रयोग गर्न सक्छन्। तिनले यो जानकारी र तिनलाई तपाईंका बारेमा पहिले नै थाहा भएको अन्य जानकारी गाभेर प्रयोग गर्न पनि सक्छन्। कम्पनीहरूले तपाईंको जानकारी कसरी प्रयोग गर्छन् भन्ने कुरा तपाईंलाई बताउने जिम्मेवारी पनि ती कम्पनीहरूकै हुन्छ। हाम्रो गोपनीयता नीति पढेर थप जान्नुहोस् \ No newline at end of file diff -Nru chromium-134.0.6998.35/components/strings/privacy_sandbox_strings_ta.xtb chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ta.xtb --- chromium-134.0.6998.35/components/strings/privacy_sandbox_strings_ta.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/strings/privacy_sandbox_strings_ta.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -5,7 +5,7 @@ தளங்களுடன் நீங்கள் பகிரும் செயல்பாட்டுத் தரவை 30 நாட்களுக்குப் பிறகு Chromium நீக்கும். ஒரு தளத்தை மீண்டும் பார்த்தால் பட்டியலில் அது மறுபடியும் காட்டப்படக்கூடும். Chromiumமில் உங்கள் விளம்பரத் தனியுரிமையை நிர்வகிப்பது குறித்து மேலும் தெரிந்துகொள்ளுங்கள். நீங்கள் சமீபத்தில் இணையத்தில் பார்த்தவற்றின் அடிப்படையில் உங்களுக்கு ஆர்வமுள்ள தலைப்புகளை Chrome நினைவில் வைத்துக்கொள்ளும் எந்தெந்தத் தரவு பயன்படுத்தப்படுகிறது: உங்கள் சமீபத்திய பிரவுசிங் பதிவுகள், இந்தச் சாதனத்தில் Chromeமைப் பயன்படுத்தி நீங்கள் பார்த்த தளங்கள் ஆகியவற்றின் அடிப்படையில் உங்கள் விளம்பரத் தலைப்புகள் இருக்கும். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். Google உங்கள் தரவை எப்படிப் பாதுகாக்கிறது என்பதை எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். Google உங்கள் தரவை எப்படிப் பாதுகாக்கிறது என்பதை எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். இந்தத் தரவைத் தளங்கள் எப்படிப் பயன்படுத்துகின்றன? நீங்கள் பிரவுசிங் செய்யும்போது உங்களுக்கு ஆர்வமுள்ள தலைப்புகளை Chrome குறித்துக்கொள்ளும். கலைகள், பொழுதுபோக்கு, ஷாப்பிங், விளையாட்டு போன்ற தலைப்பு லேபிள்கள் முன்கூட்டியே வரையறுக்கப்பட்டிருக்கும். பின்னர் உங்களுக்குக் காட்டப்படும் விளம்பரங்களைப் பிரத்தியேகமாக்க, தொடர்புடைய தலைப்புகளை Chromeமில் இருந்து நீங்கள் பார்க்கும் தளம் பெற முடியும். விளம்பரத் தனியுரிமை அமைப்புகளில் நீங்கள் மாற்றங்களைச் செய்யலாம் உதாரணமாக, இரவு உணவிற்கான ரெசிபிகளைக் கண்டறிய ஒரு தளத்திற்குச் சென்றால், நீங்கள் சமையலில் ஆர்வம் காட்டுகிறீர்கள் என்று அந்தத் தளம் கருதும். பின்னர் நீங்கள் மற்றொரு தளத்திற்குச் செல்லும்போது மளிகைப் பொருட்களை டெலிவரி செய்யும் சேவை போன்ற தொடர்புடைய விளம்பரம் காட்டப்படக்கூடும். நீங்கள் முன்னர் பார்த்த தளம் இதைப் பரிந்துரைக்கும். @@ -14,7 +14,7 @@ Google தனியுரிமைக் கொள்கை உங்கள் விளம்பரத் தனியுரிமையை நிர்வகிப்பது குறித்து மேலும் தெரிந்துகொள்ளலாம் உங்களுக்கான விளம்பரங்களைப் பிரத்தியேகமாக்க, நீங்கள் பார்க்கும் தளங்களில் நேரத்தைச் செலவிடும் விதம் போன்ற உங்கள் செயல்பாட்டு விவரங்களை விளம்பரக் கூட்டாளர்களும் தளங்களும் பயன்படுத்தலாம். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். நீங்கள் சமீபத்தில் இணையத்தில் பார்த்தவற்றின் அடிப்படையில் உங்களுக்கு ஆர்வமுள்ள தலைப்புகளை Chromium நினைவில் வைத்துக்கொள்ளும் உங்களுக்குத் தேவையில்லாத தளங்களைத் தடுக்கலாம். 30 நாட்களுக்கு முந்தைய தளங்களைப் பட்டியலில் இருந்து Chromium தானாகவே நீக்கும். மூன்றாம் தரப்புக் குக்கீகள் வரம்பிடப்பட்டுள்ளன @@ -30,7 +30,7 @@ பின்செல்லும் தளங்களுடன் நீங்கள் பகிரும் செயல்பாட்டுத் தரவை 30 நாட்களுக்குப் பிறகு Chrome நீக்கும். ஒரு தளத்தை மீண்டும் பார்த்தால் பட்டியலில் அது மறுபடியும் காட்டப்படக்கூடும். Chromeமில் உங்கள் விளம்பரத் தனியுரிமையை நிர்வகிப்பது குறித்து மேலும் தெரிந்துகொள்ளுங்கள். தளம் பரிந்துரைக்கும் விளம்பரங்கள். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். 4 வாரங்களுக்கு முந்தைய தலைப்புகள் தானாக நீக்கப்படும். விளையாட்டு, ஆடைகள் மற்றும் பலவும் தலைப்புகளில் அடங்கும். விளம்பரத் தலைப்புகள் விளம்பரங்களைப் பிரத்தியேகமாக்க, தளம் பயன்படுத்தும் பலவற்றில் விளம்பரத் தலைப்புகளும் ஒன்றாகும். விளம்பரத் தலைப்புகள் இல்லாவிட்டாலும் தளங்கள் உங்களுக்கு விளம்பரங்களைக் காட்டலாம். ஆனால், அவை உங்களுக்குத் பிரத்தியேகமானதாக இல்லாமல் போகலாம். உங்கள் விளம்பரங்கள் தொடர்பான தனியுரிமையை நிர்வகிப்பது குறித்து மேலும் தெரிந்துகொள்ளுங்கள். @@ -45,7 +45,7 @@ உங்களுக்குப் பிற தளங்களில் காட்டப்படும் விளம்பரங்களைப் பிரத்தியேகமாக்க, நீங்கள் பார்க்கும் தளங்களில் நேரத்தைச் செலவிடும் விதம் போன்ற உங்கள் செயல்பாட்டு விவரங்களை விளம்பரக் கூட்டாளர்களும் தளங்களும் பயன்படுத்தலாம். உதாரணமாக, இரவு உணவிற்கான ரெசிபிகளைக் கண்டறிய ஒரு தளத்திற்குச் சென்றால், நீங்கள் சமையலில் ஆர்வம் காட்டுகிறீர்கள் என்று அந்தத் தளம் கருதும். பின்னர் நீங்கள் மற்றொரு தளத்திற்குச் செல்லும்போது மளிகைப் பொருட்களை டெலிவரி செய்யும் சேவை போன்ற தொடர்புடைய விளம்பரம் காட்டப்படக்கூடும். நீங்கள் முன்னர் பார்த்த தளம் இதைப் பரிந்துரைக்கும். உங்கள் அடையாளத்தையும் இதுவரை இணையத்தில் பார்த்தவற்றையும் பாதுகாக்கும் அதே நேரத்தில் உங்களுக்குத் தொடர்புடைய விளம்பரங்களைக் காட்ட நீங்கள் பார்வையிடும் தளங்கள், Chromiumமில் இருந்து தலைப்புகளைப் பெற முடியும் விளம்பரங்களைப் பரிந்துரைக்க தளங்கள் பயன்படுத்தும் பல விஷயங்களில் உங்கள் செயல்பாடும் ஒன்றாகும். ‘தளம் பரிந்துரைக்கும் விளம்பரங்கள்’ அம்சம் முடக்கப்பட்டிருந்தாலும், தளங்கள் உங்களுக்கு விளம்பரங்களைக் காட்டும். ஆனால் அவை குறைந்த அளவிலேயே பிரத்தியேகமாக்கப்படும். தளம் பரிந்துரைக்கும் விளம்பரங்கள் குறித்து மேலும் தெரிந்துகொள்ளுங்கள். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். இந்தத் தரவைத் தளங்கள் எப்படிப் பயன்படுத்துகின்றன? நீங்கள் பார்க்கும் தளங்களில் காட்டப்படும் விளம்பரங்களின் செயல்திறனை அளவிட உதவும் தகவலை அந்தத் தளங்கள் Chrome பிரவுசரில் இருந்து பெற முடியும். தளங்கள் அவற்றுக்கிடையே பகிரக்கூடிய தகவலை வரம்பிடுவதன் மூலம் Chrome உங்கள் தனியுரிமையைப் பாதுகாக்கிறது. Google உங்கள் தரவை எப்படிப் பாதுகாக்கிறது என்பது குறித்து எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். உங்கள் அடையாளத்தையும் இதுவரை இணையத்தில் பார்த்தவற்றையும் பாதுகாக்கும் அதே நேரத்தில் உங்களுக்குத் தொடர்புடைய விளம்பரங்களைக் காட்ட நீங்கள் பார்வையிடும் தளங்கள், Chromeமில் இருந்து தலைப்புகளைப் பெற முடியும் @@ -54,7 +54,7 @@ Chromiumமில் உள்நுழைந்திருக்கும்போது, உங்கள் IP முகவரியைத் தனிப்பட்டதாக வைத்திருக்க இந்த அமைப்பு உதவும். ஒரு தளம் உங்களைக் கண்காணிப்பதாக Chromium கண்டறிந்தால், தனியுரிமைச் சேவையகங்களுக்கு உங்களின் சில டிராபிக் தரவுகள் அனுப்பிவைக்கப்படும். IP பாதுகாப்பு வேலைசெய்யும் விதம் பற்றித் தெரிந்துகொள்ளுங்கள் Google உங்கள் தரவை எப்படிப் பாதுகாக்கிறது என்பது குறித்து எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். உங்கள் பிரவுசிங் பதிவுகளையும் அடையாளத்தையும் பாதுகாக்கும் அதே சமயத்தில் தொடர்புடைய விளம்பரங்களைக் காட்டவும் விளம்பரத் தலைப்புகள் தளங்களுக்கு உதவுகின்றன. உங்கள் சமீபத்திய பிரவுசிங் பதிவுகளின் அடிப்படையில் உங்களுக்கு ஆர்வமுள்ள தலைப்புகளை Chrome குறித்துக்கொள்ளலாம். பின்னர் உங்களுக்குக் காட்டப்படும் விளம்பரங்களைப் பிரத்தியேகமாக்க, தொடர்புடைய தலைப்புகளை Chromeமில் இருந்து நீங்கள் பார்க்கும் தளம் பெற முடியும். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். உங்களுக்குக் காட்டப்படும் விளம்பரம் பிரத்தியேகமானதா என்பது பல காரணிகளைப் பொறுத்தது. இந்த அமைப்பு, விளம்பரத் தலைப்புகள், உங்கள் குக்கீ அமைப்புகள், நீங்கள் பார்க்கும் தளம் விளம்பரங்களைப் பிரத்தியேகமாக்குகிறதா போன்றவை இதிலடங்கும். விளம்பர அளவீடு குறித்த கூடுதல் தகவல்கள் தளங்களுடன் நீங்கள் பகிரும் செயல்பாட்டுத் தரவை 30 நாட்களுக்குப் பிறகு Chrome நீக்கும். ஒரு தளத்தை மீண்டும் பார்த்தால் பட்டியலில் அது மறுபடியும் காட்டப்படக்கூடும். Chromeமில் உங்கள் விளம்பரத் தனியுரிமையை நிர்வகிப்பது குறித்து மேலும் தெரிந்துகொள்ளுங்கள். @@ -64,5 +64,5 @@ தனியுரிமைக் கொள்கையைப் புதிய பக்கத்தில் திறக்கும் இந்தத் தரவை நீங்கள் எப்படி நிர்வகிக்கலாம்? 4 வாரங்களுக்கு முந்தைய தலைப்புகளை Chrome தானாகவே நீக்கும். நீங்கள் தொடர்ந்து பிரவுஸ் செய்யும்போது பட்டியலில் ஒரு தலைப்பு மீண்டும் காட்டப்படக்கூடும். எப்போது வேண்டுமானாலும் Chrome அமைப்புகளுக்குச் சென்று, தளங்களுடன் Chrome பகிரக்கூடாது என்று நினைக்கும் தலைப்புகளைத் தடுக்கலாம், விளம்பரத் தலைப்புகளை முடக்கலாம். இந்தத் தரவைத் தளங்கள் எப்படிப் பயன்படுத்துகின்றன? உங்களுக்குப் பிற தளங்களில் காட்டப்படும் விளம்பரங்களைப் பிரத்தியேகமாக்க, விளம்பரக் கூட்டாளர்களும் தளங்களும் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தலாம். உதாரணமாக, இரவு உணவிற்கான ரெசிபிகளைக் கண்டறிய ஒரு தளத்திற்குச் சென்றால், நீங்கள் சமையலில் ஆர்வம் காட்டுகிறீர்கள் என்று அந்தத் தளம் கருதும். பின்னர் நீங்கள் மற்றொரு தளத்திற்குச் செல்லும்போது மளிகைப் பொருட்களை டெலிவரி செய்யும் சேவை போன்ற தொடர்புடைய விளம்பரம் காட்டப்படக்கூடும். நீங்கள் முன்னர் பார்த்த தளம் இதைப் பரிந்துரைக்கும். -பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று பொதுவில் தெரிவிக்குமாறு நிறுவனங்களை Google வலியுறுத்துகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். +பல தளங்களில் உங்களைக் கண்காணிக்க இந்தத் தரவைப் பயன்படுத்த மாட்டோம் என்று நிறுவனங்கள் பொதுவில் தெரிவிப்பதை Google அவசியமாக்குகிறது. சில தளங்கள் உங்கள் செயல்பாட்டு விவரங்களைப் பயன்படுத்தி விளம்பரங்களை மட்டுமல்லாமல் உங்கள் மேலும் பல அனுபவங்களைப் பிரத்தியேகமாக்கலாம். உங்களைப் பற்றி ஏற்கெனவே தெரிந்த பிற தகவல்களுடனும் அதைச் சேர்த்துப் பயன்படுத்தலாம். உங்கள் தரவை நிறுவனங்கள் எப்படிப் பயன்படுத்துகின்றன என்று உங்களுக்குத் தெரிவிப்பது அவர்களின் பொறுப்பாகும். எங்கள் தனியுரிமைக் கொள்கையில் மேலும் தெரிந்துகொள்ளுங்கள். \ No newline at end of file diff -Nru chromium-134.0.6998.35/components/webapps/browser/android/translations/android_webapps_strings_ne.xtb chromium-134.0.6998.88/components/webapps/browser/android/translations/android_webapps_strings_ne.xtb --- chromium-134.0.6998.35/components/webapps/browser/android/translations/android_webapps_strings_ne.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/components/webapps/browser/android/translations/android_webapps_strings_ne.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -12,7 +12,7 @@ वेब एपहरूको समीक्षा गर्नुहोस् एप स्थापना गर्नुहोस् यो एप इन्स्टल गर्न मिल्दैन। -स्थापना गर्नुहोस् +इन्स्टल गर्नुहोस् इन्स्टल गर्न सकिएन स्क्रिसट होम स्क्रिनमा हाल्नुहोस् diff -Nru chromium-134.0.6998.35/content/browser/browsing_data/clear_site_data_handler.cc chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler.cc --- chromium-134.0.6998.35/content/browser/browsing_data/clear_site_data_handler.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler.cc 2025-03-07 21:29:53.000000000 +0000 @@ -258,7 +258,7 @@ if (!base::IsStringASCII(header)) { delegate->AddMessage(current_url, "Must only contain ASCII characters.", - blink::mojom::ConsoleMessageLevel::kError); + blink::mojom::ConsoleMessageLevel::kWarning); LogEvent(CLEAR_SITE_DATA_NO_RECOGNIZABLE_TYPES); return false; } @@ -311,7 +311,7 @@ delegate->AddMessage( current_url, base::StringPrintf("Unrecognized type: %s.", input_type.c_str()), - blink::mojom::ConsoleMessageLevel::kError); + blink::mojom::ConsoleMessageLevel::kWarning); continue; } @@ -329,7 +329,7 @@ if (clear_site_data_types->empty() && storage_buckets_to_remove->empty()) { delegate->AddMessage(current_url, "No recognized types specified.", - blink::mojom::ConsoleMessageLevel::kError); + blink::mojom::ConsoleMessageLevel::kWarning); LogEvent(CLEAR_SITE_DATA_NO_RECOGNIZABLE_TYPES); return false; } diff -Nru chromium-134.0.6998.35/content/browser/browsing_data/clear_site_data_handler_unittest.cc chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler_unittest.cc --- chromium-134.0.6998.35/content/browser/browsing_data/clear_site_data_handler_unittest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/browsing_data/clear_site_data_handler_unittest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -357,7 +357,7 @@ std::string multiline_message; for (const auto& message : console_delegate.GetMessagesForTesting()) { - EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kError, message.level); + EXPECT_EQ(blink::mojom::ConsoleMessageLevel::kWarning, message.level); multiline_message += message.text + "\n"; } diff -Nru chromium-134.0.6998.35/content/browser/interest_group/interest_group_features.cc chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.cc --- chromium-134.0.6998.35/content/browser/interest_group/interest_group_features.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.cc 2025-03-07 21:29:53.000000000 +0000 @@ -61,6 +61,20 @@ "FledgeFacilitatedTestingSignalsHeaders", base::FEATURE_DISABLED_BY_DEFAULT); +// Provides a configurable limit on the number of +// `selectableBuyerAndSellerReportingIds` for which the browser fetches k-anon +// keys. If the `SelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit` is +// negative, no limit is enforced. +BASE_FEATURE(kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon, + "FledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon", + base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE_PARAM( + int, + kFledgeSelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit, + &kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon, + "SelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit", + -1); + // Turning on kFledgeQueryKAnonymity loads k-anonymity status at interest group // join and update time. kFledgeQueryKAnonymity is enabled by default. It may // be reasonable to disable kFledgeQueryKAnonymity on clients on which diff -Nru chromium-134.0.6998.35/content/browser/interest_group/interest_group_features.h chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.h --- chromium-134.0.6998.35/content/browser/interest_group/interest_group_features.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/interest_group/interest_group_features.h 2025-03-07 21:29:53.000000000 +0000 @@ -9,6 +9,7 @@ #include "base/metrics/field_trial_params.h" #include "base/time/time.h" #include "content/common/content_export.h" +#include "third_party/blink/public/common/features.h" namespace features { // Please keep features in alphabetical order. @@ -26,6 +27,12 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kFledgeEnableWALForInterestGroupStorage); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFledgeFacilitatedTestingSignalsHeaders); +CONTENT_EXPORT BASE_DECLARE_FEATURE( + kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon); +CONTENT_EXPORT BASE_DECLARE_FEATURE_PARAM( + int, + kFledgeSelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit); + CONTENT_EXPORT BASE_DECLARE_FEATURE(kFledgeQueryKAnonymity); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFledgeStartAnticipatoryProcesses); diff -Nru chromium-134.0.6998.35/content/browser/interest_group/interest_group_storage.cc chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage.cc --- chromium-134.0.6998.35/content/browser/interest_group/interest_group_storage.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage.cc 2025-03-07 21:29:53.000000000 +0000 @@ -861,10 +861,26 @@ if (base::FeatureList::IsEnabled( blink::features::kFledgeAuctionDealSupport) && ad.selectable_buyer_and_seller_reporting_ids) { - for (const std::string& selectable_id : - *ad.selectable_buyer_and_seller_reporting_ids) { + size_t num_selectable_kanon_keys = + ad.selectable_buyer_and_seller_reporting_ids->size(); + if (base::FeatureList::IsEnabled( + features:: + kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon) && + features:: + kFledgeSelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit + .Get() >= 0) { + num_selectable_kanon_keys = std::min( + num_selectable_kanon_keys, + static_cast( + features:: + kFledgeSelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit + .Get())); + } + for (size_t selectable_idx = 0; + selectable_idx < num_selectable_kanon_keys; ++selectable_idx) { hashed_keys.emplace(blink::HashedKAnonKeyForAdNameReporting( - interest_group, ad, selectable_id)); + interest_group, ad, + (*ad.selectable_buyer_and_seller_reporting_ids)[selectable_idx])); } } hashed_keys.emplace( diff -Nru chromium-134.0.6998.35/content/browser/interest_group/interest_group_storage_unittest.cc chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage_unittest.cc --- chromium-134.0.6998.35/content/browser/interest_group/interest_group_storage_unittest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/interest_group/interest_group_storage_unittest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -27,6 +27,7 @@ #include "base/time/time.h" #include "content/browser/interest_group/bidding_and_auction_server_key_fetcher.h" #include "content/browser/interest_group/for_debugging_only_report_util.h" +#include "content/browser/interest_group/interest_group_features.h" #include "content/browser/interest_group/interest_group_update.h" #include "content/browser/interest_group/storage_interest_group.h" #include "content/public/browser/browser_thread.h" @@ -885,6 +886,52 @@ kanon_report1b, kanon_report2})); } + // Limit the number of deals per ad on which k-anon keys are fetched. + { + base::test::ScopedFeatureList scoped_feature_to_enforce_limit; + scoped_feature_to_enforce_limit.InitAndEnableFeatureWithParameters( + features:: + kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon, + {{"SelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit", "1"}}); + + std::optional k_anon_update_data = + storage->UpdateInterestGroup(group_key, update); + ASSERT_TRUE(k_anon_update_data.has_value()); + EXPECT_EQ(k_anon_update_data->update_time, update_time); + // `kanon_report1b` is notably absent because of the configured limit. + EXPECT_THAT(k_anon_update_data->hashed_keys, + testing::UnorderedElementsAreArray( + {kanon_bid1, kanon_bid2, kanon_report1, kanon_report1a, + kanon_report2, kanon_component_1, kanon_component_2})); + // Empty because all of these keys were loaded in the previous test. + EXPECT_THAT(k_anon_update_data->newly_added_hashed_keys, + testing::IsEmpty()); + } + + // Similar to the above, but with the Limit the number of deals per ad on + // which k-anon keys are fetched set to -1, which enforces no limit. + { + base::test::ScopedFeatureList scoped_feature_to_enforce_limit; + scoped_feature_to_enforce_limit.InitAndEnableFeatureWithParameters( + features:: + kFledgeLimitSelectableBuyerAndSellerReportingIdsFetchedFromKAnon, + {{"SelectableBuyerAndSellerReportingIdsFetchedFromKAnonLimit", "-1"}}); + + std::optional k_anon_update_data = + storage->UpdateInterestGroup(group_key, update); + ASSERT_TRUE(k_anon_update_data.has_value()); + EXPECT_EQ(k_anon_update_data->update_time, update_time); + // `kanon_report1b` is notably back in this list. + EXPECT_THAT(k_anon_update_data->hashed_keys, + testing::UnorderedElementsAreArray( + {kanon_bid1, kanon_bid2, kanon_report1, kanon_report1a, + kanon_report1b, kanon_report2, kanon_component_1, + kanon_component_2})); + // Empty because all of these keys were loaded in the previous test. + EXPECT_THAT(k_anon_update_data->newly_added_hashed_keys, + testing::IsEmpty()); + } + // Do an interest group update that updates the bidding URL, ads, and ad // components. { diff -Nru chromium-134.0.6998.35/content/browser/renderer_host/render_view_host_impl.cc chromium-134.0.6998.88/content/browser/renderer_host/render_view_host_impl.cc --- chromium-134.0.6998.35/content/browser/renderer_host/render_view_host_impl.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/renderer_host/render_view_host_impl.cc 2025-03-07 21:29:53.000000000 +0000 @@ -542,9 +542,19 @@ mojom::CreateProvisionalLocalMainFrameParams::New( std::move(local_frame_params), frame_tree_node->current_frame_host()->GetFrameToken())); - } else if (frame_tree_->is_prerendering()) { - // During a prerender navigation, a local main frame for a new - // RenderViewHost must always start as a provisinonal RenderFrame in the + } else if (frame_tree_->is_prerendering() && + (!base::FeatureList::IsEnabled( + features::kPrerenderMoreCorrectSpeculativeRFHCreation) || + main_rfh->lifecycle_state() == + RenderFrameHostImpl::LifecycleStateImpl::kSpeculative)) { + // During prerender, the browser may need to create new speculative local + // main frames. Normally, creating a speculative local main frame is a + // two step process: the browser first creates a RenderViewHost with a + // main RenderFrameProxyHost and then creates the speculative main + // RenderFrameHost. + // + // Prerender skips the RenderFrameProxyHost creation step, but the new + // RenderViewHost must still start with a provisional RenderFrame in the // renderer. Otherwise, discarding a speculative RFH during prerender // navigation causes the browser and the renderer to go out of sync. See // https://crbug.com/40076091 for more background and details. diff -Nru chromium-134.0.6998.35/content/browser/webrtc/webrtc_audio_browsertest.cc chromium-134.0.6998.88/content/browser/webrtc/webrtc_audio_browsertest.cc --- chromium-134.0.6998.35/content/browser/webrtc/webrtc_audio_browsertest.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/browser/webrtc/webrtc_audio_browsertest.cc 2025-03-07 21:29:53.000000000 +0000 @@ -112,24 +112,6 @@ } IN_PROC_BROWSER_TEST_F(WebRtcAudioBrowserTest, - EnsureRemoteAudioTrackStopCloneNotStopOriginalTrack) { - std::string constraints = - BuildConstraints(kAudioConstraints, kVideoConstraints); - MakeAudioDetectingPeerConnectionCall( - "callAndEnsureRemoteClonedAudioTrackStopNotStopOriginalTrack(" + - constraints + ");"); -} - -IN_PROC_BROWSER_TEST_F(WebRtcAudioBrowserTest, - EnsureRemoteAudioTrackDisableNotDisableClonedTrack) { - std::string constraints = - BuildConstraints(kAudioConstraints, kVideoConstraints); - MakeAudioDetectingPeerConnectionCall( - "callAndEnsureRemoteAudioTrackDisableNotDisableClonedTrack(" + - constraints + ");"); -} - -IN_PROC_BROWSER_TEST_F(WebRtcAudioBrowserTest, EstablishAudioVideoCallAndVerifyLocalMutingWorks) { std::string constraints = BuildConstraints(kAudioConstraints, kVideoConstraints); diff -Nru chromium-134.0.6998.35/content/common/features.cc chromium-134.0.6998.88/content/common/features.cc --- chromium-134.0.6998.35/content/common/features.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/common/features.cc 2025-03-07 21:29:53.000000000 +0000 @@ -311,6 +311,15 @@ "PreloadingConfig", base::FEATURE_ENABLED_BY_DEFAULT); +// A misunderstanding when fixing crbug.com/40076091 meant that non-speculative +// RFHs were being created with a provisional RenderFrame in the renderer. This +// is nominally harmless, but can crash prerenders if devtool's network +// overrides feature is enabled. Guarded by a feature since fixing this new bug +// might reintroduce the previous crashes. +BASE_FEATURE(kPrerenderMoreCorrectSpeculativeRFHCreation, + "PrerenderMoreCorrectSpeculativeRFHCreation", + base::FEATURE_ENABLED_BY_DEFAULT); + // This feature makes it so that having pending views increase the priority of a // RenderProcessHost even when there is a priority override. BASE_FEATURE(kPriorityOverridePendingViews, diff -Nru chromium-134.0.6998.35/content/common/features.h chromium-134.0.6998.88/content/common/features.h --- chromium-134.0.6998.35/content/common/features.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/content/common/features.h 2025-03-07 21:29:53.000000000 +0000 @@ -76,6 +76,8 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kPermissionsPolicyVerificationInContent); #endif CONTENT_EXPORT BASE_DECLARE_FEATURE(kPreloadingConfig); +CONTENT_EXPORT BASE_DECLARE_FEATURE( + kPrerenderMoreCorrectSpeculativeRFHCreation); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPriorityOverridePendingViews); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPrivacySandboxAdsAPIsM1Override); CONTENT_EXPORT BASE_DECLARE_FEATURE(kProcessReuseOnPrerenderCOOPSwap); diff -Nru chromium-134.0.6998.35/debian/changelog chromium-134.0.6998.88/debian/changelog --- chromium-134.0.6998.35/debian/changelog 2025-03-05 18:26:45.000000000 +0000 +++ chromium-134.0.6998.88/debian/changelog 2025-03-11 18:28:43.000000000 +0000 @@ -1,3 +1,29 @@ +chromium (134.0.6998.88-1~deb12u1) bookworm-security; urgency=high + + * New upstream security release. + - CVE-2025-1920: Type Confusion in V8. Reported by Excello s.r.o. + - CVE-2025-2135: Type Confusion in V8. + Reported by Zhenghang Xiao (@Kipreyyy). + - CVE-2025-24201: Out of bounds write in GPU on Mac. Reported by + Apple Security Engineering and Architecture (SEAR). + - CVE-2025-2136: Use after free in Inspector. Reported by Sakana.S. + - CVE-2025-2137: Out of bounds read in V8. Reported by zeroxiaobai@. + + -- Andres Salomon Tue, 11 Mar 2025 14:28:43 -0400 + +chromium (134.0.6998.35-3) unstable; urgency=high + + * Fix FTBFS with pipewire 1.4.0. + + -- Andres Salomon Sat, 08 Mar 2025 13:35:36 -0500 + +chromium (134.0.6998.35-2) unstable; urgency=high + + * Revert "Have chromium-driver depend upon chromium-common instead of + chromium" to make autopkgtests of various packages happy. + + -- Andres Salomon Fri, 07 Mar 2025 00:58:06 -0500 + chromium (134.0.6998.35-1~deb12u1) bookworm-security; urgency=high [ Andres Salomon ] diff -Nru chromium-134.0.6998.35/debian/control chromium-134.0.6998.88/debian/control --- chromium-134.0.6998.35/debian/control 2025-03-04 05:01:01.000000000 +0000 +++ chromium-134.0.6998.88/debian/control 2025-03-11 18:28:43.000000000 +0000 @@ -180,7 +180,7 @@ Depends: ${misc:Depends}, ${shlibs:Depends}, - chromium-common (= ${binary:Version}), + chromium (= ${binary:Version}), Description: web browser - WebDriver support Web browser that aims to build a safer, faster, and more stable internet browsing experience. diff -Nru chromium-134.0.6998.35/debian/patches/fixes/pipewire14.patch chromium-134.0.6998.88/debian/patches/fixes/pipewire14.patch --- chromium-134.0.6998.35/debian/patches/fixes/pipewire14.patch 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/debian/patches/fixes/pipewire14.patch 2025-03-11 18:28:43.000000000 +0000 @@ -0,0 +1,45 @@ +../../third_party/webrtc/modules/video_capture/linux/pipewire_session.cc:90:3: error: no matching function for call to 'pw_node_add_listener' + 90 | pw_node_add_listener(proxy_, &node_listener_, &node_events, this); + | ^~~~~~~~~~~~~~~~~~~~ +/usr/include/pipewire-0.3/pipewire/node.h:189:22: note: candidate function not viable: cannot convert argument of incomplete type 'pw_proxy *' to 'struct pw_node *' for 1st argument + 189 | PW_API_NODE_IMPL int pw_node_add_listener(struct pw_node *object, + | ^ ~~~~~~~~~~~~~~~~~~~~~~ +../../third_party/webrtc/modules/video_capture/linux/pipewire_session.cc:122:9: error: no matching function for call to 'pw_node_enum_params' + 122 | pw_node_enum_params(that->proxy_, 0, id, 0, UINT32_MAX, nullptr); + | ^~~~~~~~~~~~~~~~~~~ +/usr/include/pipewire-0.3/pipewire/node.h:208:22: note: candidate function not viable: cannot convert argument of incomplete type 'pw_proxy *' to 'struct pw_node *' for 1st argument + 208 | PW_API_NODE_IMPL int pw_node_enum_params(struct pw_node *object, + | ^ ~~~~~~~~~~~~~~~~~~~~~~ +2 errors generated. + +This started with pipewire 1.4.0. + +I initially thought that since they were calling a bunch of pw_node_* +functions, they should've been requesting a pw_node rather than a +pw_proxy. But it looks like casting between the two is just a thing +that pipewire does (see, for example, pipewire source code's +src/modules/module-protocol-pulse/manager.c calls to pw_node_enum_params()). + +So we fix this by casting, under the assumption that the webrtc folks +actually did intend to call pw_node_* functions on a pw_proxy. + +--- a/third_party/webrtc/modules/video_capture/linux/pipewire_session.cc ++++ b/third_party/webrtc/modules/video_capture/linux/pipewire_session.cc +@@ -87,7 +87,7 @@ PipeWireNode::PipeWireNode(PipeWireSessi + .param = OnNodeParam, + }; + +- pw_node_add_listener(proxy_, &node_listener_, &node_events, this); ++ pw_node_add_listener((struct pw_node*) proxy_, &node_listener_, &node_events, this); + } + + // static +@@ -119,7 +119,7 @@ void PipeWireNode::OnNodeInfo(void* data + uint32_t id = info->params[i].id; + if (id == SPA_PARAM_EnumFormat && + info->params[i].flags & SPA_PARAM_INFO_READ) { +- pw_node_enum_params(that->proxy_, 0, id, 0, UINT32_MAX, nullptr); ++ pw_node_enum_params((struct pw_node*) that->proxy_, 0, id, 0, UINT32_MAX, nullptr); + break; + } + } diff -Nru chromium-134.0.6998.35/debian/patches/series chromium-134.0.6998.88/debian/patches/series --- chromium-134.0.6998.35/debian/patches/series 2025-03-05 18:26:45.000000000 +0000 +++ chromium-134.0.6998.88/debian/patches/series 2025-03-11 18:28:43.000000000 +0000 @@ -25,6 +25,7 @@ fixes/stdatomic.patch fixes/variant.patch fixes/swiftshader-llvm.patch +fixes/pipewire14.patch upstream/qualifications.patch upstream/optional.patch diff -Nru chromium-134.0.6998.35/extensions/browser/api/web_request/web_request_api.cc chromium-134.0.6998.88/extensions/browser/api/web_request/web_request_api.cc --- chromium-134.0.6998.35/extensions/browser/api/web_request/web_request_api.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/extensions/browser/api/web_request/web_request_api.cc 2025-03-07 21:29:53.000000000 +0000 @@ -91,6 +91,24 @@ namespace { +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// +// LINT.IfChange(ProxyDecisionDetailsForExtension) +enum class ProxyDecisionDetailsForExtension { + // Proxy will be used only for WebRequest* permissions. + kOnlyForWebRequest = 0, + // Proxy will be used only for Declarative{Web|Net}Request* permissions. + kOnlyForDeclarativeRequest = 1, + // Proxy will be used only for WebView permissions. + kOnlyForWebView = 2, + // Proxy will be used only for multiple kinds of permissions. + kForMixedReasons = 3, + + kMaxValue = kForMixedReasons, +}; +// LINT.ThenChange(/tools/metrics/histograms/metadata/extensions/enums.xml:WebRequestProxyDecisionDetailsForExtension) + // Converts an HttpHeaders dictionary to a |name|, |value| pair. Returns // true if successful. bool FromHeaderDictionary(const base::Value::Dict& header_value, @@ -425,6 +443,30 @@ base::UmaHistogramExactLinear( "Extensions.WebRequest.WebViewDependentExtensionCount", web_view_extension_count_, kMaxCount); + + if (decision == ProxyDecision::kWillProxyForExtension && + !base::FeatureList::IsEnabled( + extensions_features::kForceWebRequestProxyForTest)) { + // Check if kWillProxyForExtension is decided only for one type of + // permissions, or mixed reasons. + ProxyDecisionDetailsForExtension details = + ProxyDecisionDetailsForExtension::kForMixedReasons; + if (web_request_extension_count_ == 0 && + declarative_request_extension_count_ == 0) { + CHECK_NE(web_view_extension_count_, 0); + details = ProxyDecisionDetailsForExtension::kOnlyForWebView; + } else if (web_view_extension_count_ == 0 && + declarative_request_extension_count_ == 0) { + CHECK_NE(web_request_extension_count_, 0); + details = ProxyDecisionDetailsForExtension::kOnlyForWebRequest; + } else if (web_request_extension_count_ == 0 && + web_view_extension_count_ == 0) { + CHECK_NE(declarative_request_extension_count_, 0); + details = ProxyDecisionDetailsForExtension::kOnlyForDeclarativeRequest; + } + base::UmaHistogramEnumeration( + "Extensions.WebRequest.ProxyDecisionDetailsForExtension", details); + } return decision != ProxyDecision::kWillNotProxy; } diff -Nru chromium-134.0.6998.35/gin/v8_initializer.cc chromium-134.0.6998.88/gin/v8_initializer.cc --- chromium-134.0.6998.35/gin/v8_initializer.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/gin/v8_initializer.cc 2025-03-07 21:29:53.000000000 +0000 @@ -264,7 +264,6 @@ // Sets mandatory V8 flags. void SetFlags(IsolateHolder::ScriptMode mode, const std::string& js_command_line_flags) { - SetV8Flags("--js-explicit-resource-management"); if (IsolateHolder::kStrictMode == mode) { SetV8Flags("--use_strict"); diff -Nru chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder.cc chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder.cc --- chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder.cc 2025-03-07 21:29:53.000000000 +0000 @@ -3272,6 +3272,13 @@ } } + if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2) { + // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled. + // See the section in WebGL 2 spec: + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4 + DoEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); + } + if (group_->gpu_preferences().enable_gpu_driver_debug_logging && feature_info_->feature_flags().khr_debug) { InitializeGLDebugLogging(true, GLDebugMessageCallback, &logger_); diff -Nru chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc --- chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1066,6 +1066,17 @@ api()->glDisableFn(GL_TEXTURE_RECTANGLE_ANGLE); #endif + // TEMPORARY: Set primitive restart to enabled by default for WebGL2. Clear + // errors afterwards so that when this state is initialized and validated in + // ANGLE, it will not generate errors during command buffer initialization. + if (feature_info_->context_type() == CONTEXT_TYPE_WEBGL2) { + // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled. + // See the section in WebGL 2 spec: + // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4 + api()->glEnableFn(GL_PRIMITIVE_RESTART_FIXED_INDEX); + CheckErrorCallbackState(); + } + // Register this object as a GPU switching observer. if (feature_info_->IsWebGLContext()) { ui::GpuSwitchingManager::GetInstance()->AddObserver(this); @@ -2161,6 +2172,11 @@ case GL_DEBUG_OUTPUT: return true; + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + // Disable setting primitive restart at the command decoder level until + // it's blocked in ANGLE for WebGL contexts. + return feature_info_->IsWebGLContext(); + default: return false; } diff -Nru chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc --- chromium-134.0.6998.35/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc 2025-03-07 21:29:53.000000000 +0000 @@ -439,6 +439,13 @@ } #endif + if (init.context_type == CONTEXT_TYPE_WEBGL2 && + group_->feature_info()->gl_version_info().is_es3) { + EXPECT_CALL(*gl_, Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX)) + .Times(1) + .RetiresOnSaturation(); + } + if (context_->HasRobustness()) { EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()) .WillOnce(Return(init.lose_context_on_init ? GL_GUILTY_CONTEXT_RESET_ARB diff -Nru chromium-134.0.6998.35/gpu/config/gpu_lists_version.h chromium-134.0.6998.88/gpu/config/gpu_lists_version.h --- chromium-134.0.6998.35/gpu/config/gpu_lists_version.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/gpu/config/gpu_lists_version.h 2025-03-07 21:29:53.000000000 +0000 @@ -3,6 +3,6 @@ #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_ #define GPU_CONFIG_GPU_LISTS_VERSION_H_ -#define GPU_LISTS_VERSION "ea6ef4c2ac15ae95d2cfd65682da62c093415099" +#define GPU_LISTS_VERSION "7e3d5c978c6d3a6eda25692cfac7f893a2b20dd0" #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_ diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android FYI Release (Pixel 6)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android FYI Release (Pixel 6)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android FYI Release (Pixel 6)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android FYI Release (Pixel 6)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -19,7 +19,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { @@ -52,7 +52,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android Release (Pixel 2)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android Release (Pixel 2)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android Release (Pixel 2)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android Release (Pixel 2)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android WebView O (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView O (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android WebView O (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView O (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -59,7 +59,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android WebView P (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView P (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android WebView P (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android WebView P (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -59,7 +59,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm Builder (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm Builder (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm Builder (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm Builder (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm64 Builder (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm64 Builder (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -27,7 +27,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -65,7 +65,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -100,7 +100,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -130,7 +130,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -165,7 +165,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm64 Builder All Targets (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder All Targets (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android arm64 Builder All Targets (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android arm64 Builder All Targets (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android x64 Builder All Targets (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x64 Builder All Targets (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android x64 Builder All Targets (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x64 Builder All Targets (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Debug", - "config": "android", + "config": "x64_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android x86 Builder (dbg)/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x86 Builder (dbg)/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Android x86 Builder (dbg)/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Android x86 Builder (dbg)/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Debug", - "config": "android", + "config": "x86_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/GPU FYI Android arm64 Builder/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { @@ -55,7 +55,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { diff -Nru "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Oreo Phone Tester/properties.json" "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Oreo Phone Tester/properties.json" --- "/srv/release.debian.org/tmp/1aNaLYpeFG/chromium-134.0.6998.35/infra/config/generated/builders/ci/Oreo Phone Tester/properties.json" 2025-02-25 19:55:16.000000000 +0000 +++ "/srv/release.debian.org/tmp/0BD1BWLfSp/chromium-134.0.6998.88/infra/config/generated/builders/ci/Oreo Phone Tester/properties.json" 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -51,7 +51,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-12-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-12-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-12l-x64-rel-cq/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12l-x64-rel-cq/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-12l-x64-rel-cq/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-12l-x64-rel-cq/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-13-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-13-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-13-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-13-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-14-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-14-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-14-tablet-landscape-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-tablet-landscape-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-14-tablet-landscape-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-14-tablet-landscape-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Release", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-15-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-15-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-15-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-15-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "cast_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "cast_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "cast_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cast-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cast-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "cast_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-arm-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-arm-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "main_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-arm-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-arm-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-arm-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-mainline-clang-x86-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-mainline-clang-x86-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-mainline-clang-x86-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-mainline-clang-x86-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x86-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x86-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, @@ -56,7 +56,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x86-dbg-10-tests/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg-10-tests/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-cronet-x86-dbg-10-tests/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-cronet-x86-dbg-10-tests/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, @@ -53,7 +53,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-official/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-official/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-official/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-official/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ "apply_configs": [ "mb" ], - "config": "android", + "config": "main_builder", "target_arch": "arm", "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-oreo-x86-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-oreo-x86-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-oreo-x86-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-oreo-x86-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Release", - "config": "android", + "config": "x86_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -51,7 +51,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-x86-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-x86-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-pie-x86-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-pie-x86-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/ci/android-webview-13-x64-hostside-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/ci/android-webview-13-x64-hostside-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/ci/android-webview-13-x64-hostside-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/ci/android-webview-13-x64-hostside-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-12-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-12-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-12-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-12-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-12l-x64-rel-cq/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-12l-x64-rel-cq/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-12l-x64-rel-cq/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-12l-x64-rel-cq/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-13-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-13-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-13-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-13-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-14-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-14-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-14-tablet-landscape-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-tablet-landscape-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-14-tablet-landscape-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-14-tablet-landscape-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Release", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-15-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-15-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-15-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-15-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-arm-compile-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm-compile-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-arm-compile-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm-compile-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -29,7 +29,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, @@ -60,7 +60,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, @@ -91,7 +91,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "cast_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "cast_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "cast_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cast-arm64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cast-arm64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "cast_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-arm-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-arm-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "main_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-arm-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-arm-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-arm-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "main_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-mainline-clang-x86-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-mainline-clang-x86-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-mainline-clang-x86-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-mainline-clang-x86-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-x64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-x64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-cronet-x86-dbg-10-tests/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, @@ -56,7 +56,7 @@ "mb" ], "build_config": "Debug", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-official/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-official/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-official/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-official/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ "apply_configs": [ "mb" ], - "config": "android", + "config": "main_builder", "target_arch": "arm", "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-oreo-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -54,7 +54,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-pie-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-pie-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -54,7 +54,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-pie-x86-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-x86-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-pie-x86-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-pie-x86-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x86_builder", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-oreo-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -27,7 +27,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -62,7 +62,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-webview-pie-arm64-dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -27,7 +27,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, @@ -62,7 +62,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-x64-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-x64-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-x64-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-x64-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -28,7 +28,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, @@ -58,7 +58,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, @@ -88,7 +88,7 @@ "mb" ], "build_config": "Release", - "config": "android", + "config": "x64_builder", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android-x86-rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android-x86-rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android-x86-rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android-x86-rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -25,7 +25,7 @@ }, "legacy_chromium_config": { "build_config": "Release", - "config": "android", + "config": "x86_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -24,7 +24,7 @@ "download_xr_test_apks" ], "build_config": "Debug", - "config": "android", + "config": "main_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x64_dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Debug", - "config": "android", + "config": "x64_builder_mb", "target_bits": 64, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_x86_dbg/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x86_dbg/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android_compile_x86_dbg/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android_compile_x86_dbg/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -21,7 +21,7 @@ }, "legacy_chromium_config": { "build_config": "Debug", - "config": "android", + "config": "x86_builder_mb", "target_bits": 32, "target_platform": "android" }, diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/android_optional_gpu_tests_rel/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -20,7 +20,7 @@ "config": "main_builder" }, "legacy_chromium_config": { - "config": "android", + "config": "main_builder", "target_platform": "android" }, "legacy_gclient_config": { diff -Nru chromium-134.0.6998.35/infra/config/generated/builders/try/gpu-fyi-cq-android-arm64/properties.json chromium-134.0.6998.88/infra/config/generated/builders/try/gpu-fyi-cq-android-arm64/properties.json --- chromium-134.0.6998.35/infra/config/generated/builders/try/gpu-fyi-cq-android-arm64/properties.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/builders/try/gpu-fyi-cq-android-arm64/properties.json 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { @@ -55,7 +55,7 @@ "apply_configs": [ "download_xr_test_apks" ], - "config": "android", + "config": "arm64_builder_rel_mb", "target_platform": "android" }, "legacy_gclient_config": { diff -Nru chromium-134.0.6998.35/infra/config/generated/luci/commit-queue.cfg chromium-134.0.6998.88/infra/config/generated/luci/commit-queue.cfg --- chromium-134.0.6998.35/infra/config/generated/luci/commit-queue.cfg 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/generated/luci/commit-queue.cfg 2025-03-07 21:29:53.000000000 +0000 @@ -22,7 +22,7 @@ } verifiers { gerrit_cq_ability { - committer_list: "project-chromium-committers" + committer_list: "project-chromium-submit-access" dry_run_access_list: "project-chromium-tryjob-access" new_patchset_run_access_list: "project-chromium-tryjob-access" } diff -Nru chromium-134.0.6998.35/infra/config/lib/builder_config.star chromium-134.0.6998.88/infra/config/lib/builder_config.star --- chromium-134.0.6998.35/infra/config/lib/builder_config.star 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/lib/builder_config.star 2025-03-07 21:29:53.000000000 +0000 @@ -233,6 +233,21 @@ archive_subdir = archive_subdir, ) +# After calling chromium.set_config, chromium_tests.configure_build calls +# chromium_android.configure_from_properties. configure_from_properties calls +# chromium.set_config with the same name as used for +# chromium_android.set_config. This means that in most cases, the value +# specified for the chromium config will be ignored. The exception to this is if +# there is no config item for the chromium module with the name specified for +# android_config. Because configure_from_properties calls chromium.set_config +# with optional=True, in that case the chromium module will not be modified and +# the prior config set by configure_from_build will be used. This provides the +# names being used for the chromium_android config that do not have +# corresponding chromium module config items to avoid rewriting the field. +_NONEXISTENT_ANDROID_CHROMIUM_CONFIGS = set([ + "clang_builder_mb_x64", +]) + def _builder_spec( *, gclient_config, @@ -254,7 +269,12 @@ gclient_config: (gclient_config) The gclient config for the builder. chromium_config: (chromium_config) The chromium config for the builder. execution_mode: (execution_mode) The execution mode of the builder. - android_config: (android_config) The android config for the builder. + android_config: (android_config) The android config for the builder. If + this is set, the config value in chromium_config will be overridden + with the config field of this unless that config does not name a + chromium config item. This matches the runtime behavior of the + chromium_tests.configure_build and + chromium_android.configure_from_properties. android_version_file: (str) A path relative to the checkout to a file containing the Chrome version information for Android. clobber: (bool) Whether to have bot_update perform a clobber of any @@ -300,6 +320,12 @@ if not chromium_config: fail("chromium_config must be provided") + # TODO: crbug.com/374819553 - Once chromium_tests code is not using + # chromium_android.configure_from_properties, explicitly set the chromium + # config to the appropriate values. + if android_config and android_config.config not in _NONEXISTENT_ANDROID_CHROMIUM_CONFIGS: + chromium_config = structs.evolve(chromium_config, config = android_config.config) + return struct( execution_mode = execution_mode, gclient_config = gclient_config, diff -Nru chromium-134.0.6998.35/infra/config/subprojects/chromium/try.star chromium-134.0.6998.88/infra/config/subprojects/chromium/try.star --- chromium-134.0.6998.35/infra/config/subprojects/chromium/try.star 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/config/subprojects/chromium/try.star 2025-03-07 21:29:53.000000000 +0000 @@ -120,7 +120,7 @@ acls = [ acl.entry( acl.CQ_COMMITTER, - groups = "project-chromium-committers", + groups = "project-chromium-submit-access", ), acl.entry( acl.CQ_DRY_RUNNER, @@ -186,7 +186,7 @@ acls = [ acl.entry( acl.CQ_COMMITTER, - groups = "project-chromium-committers", + groups = "project-chromium-submit-access", ), acl.entry( acl.CQ_DRY_RUNNER, diff -Nru chromium-134.0.6998.35/infra/inclusive_language_presubmit_exempt_dirs.txt chromium-134.0.6998.88/infra/inclusive_language_presubmit_exempt_dirs.txt --- chromium-134.0.6998.35/infra/inclusive_language_presubmit_exempt_dirs.txt 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/infra/inclusive_language_presubmit_exempt_dirs.txt 2025-03-07 21:29:53.000000000 +0000 @@ -209,8 +209,7 @@ extensions/shell/common 1 1 google_apis/gaia 1 1 gpu/config 1 1 -infra 4 2 -infra/config/generated/luci 1 1 +infra 5 3 infra/config/generators 2 1 infra/config/gn_args 1 1 infra/config/subprojects/webrtc/consoles 1 1 @@ -251,7 +250,7 @@ net/disk_cache/blockfile 1 1 net/dns 1 1 net/docs 3 1 -net/http 23 2 +net/http 22 2 net/proxy_resolution 1 1 net/socket 1 1 net/tools/crash_cache 1 1 diff -Nru chromium-134.0.6998.35/net/http/transport_security_state_static.pins chromium-134.0.6998.88/net/http/transport_security_state_static.pins --- chromium-134.0.6998.35/net/http/transport_security_state_static.pins 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/net/http/transport_security_state_static.pins 2025-03-07 21:29:53.000000000 +0000 @@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2025-02-24 12:55 UTC +# Last updated: 2025-03-07 12:53 UTC PinsListTimestamp -1740401723 +1741352033 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= diff -Nru chromium-134.0.6998.35/net/http/transport_security_state_static_pins.json chromium-134.0.6998.88/net/http/transport_security_state_static_pins.json --- chromium-134.0.6998.35/net/http/transport_security_state_static_pins.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/net/http/transport_security_state_static_pins.json 2025-03-07 21:29:53.000000000 +0000 @@ -31,7 +31,7 @@ // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets' // refer to, and the timestamp at which the pins list was last updated. // -// Last updated: 2025-02-24 12:55 UTC +// Last updated: 2025-03-07 12:53 UTC // { "pinsets": [ @@ -801,6 +801,11 @@ "include_subdomains": true, "pins": "google" }, + { + "name": "google.eus", + "include_subdomains": true, + "pins": "google" + }, { "name": "google.cc", "include_subdomains": true, diff -Nru chromium-134.0.6998.35/remoting/resources/remoting_strings_fa.xtb chromium-134.0.6998.88/remoting/resources/remoting_strings_fa.xtb --- chromium-134.0.6998.35/remoting/resources/remoting_strings_fa.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/remoting/resources/remoting_strings_fa.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -50,7 +50,7 @@ می‌خواهد تغییراتی ایجاد کند. دسترسی ایمن به رایانه‌تان از طریق اینترنت مالک میزبان نامعتبر است. -فرایند برقراری ارتباط ازراه‌دور کلید ایمنی +فرایند برقراری ارتباط ازراه‌دور کلید امنیتی اتصال به شبکه انجام نشد. لطفاً بررسی کنید که دستگاه شما به اینترنت وصل باشد. ‏این سرویس اتصالات ورودی از کلاینت‌های کنترل دسک‌تاپ ازراه‌دور Chrome را فعال می‌کند. با نحوه انجام کار آشنا شوید diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/css/invalidation/rule_invalidation_data_visitor.cc chromium-134.0.6998.88/third_party/blink/renderer/core/css/invalidation/rule_invalidation_data_visitor.cc --- chromium-134.0.6998.35/third_party/blink/renderer/core/css/invalidation/rule_invalidation_data_visitor.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/css/invalidation/rule_invalidation_data_visitor.cc 2025-03-07 21:29:53.000000000 +0000 @@ -931,10 +931,13 @@ // TODO(futhark): We can extract the features from the current compound // to optimize this. SetWholeSubtreeInvalid(invalidation_set); - AddFeaturesToInvalidationSet( + InvalidationSetType* sibling_descendant_set = EnsureSiblingDescendantInvalidationSet( - To(invalidation_set)), - descendant_features); + To(invalidation_set)); + if (sibling_descendant_set != nullptr) { + AddFeaturesToInvalidationSet(sibling_descendant_set, + descendant_features); + } return; } else { AddFeaturesToInvalidationSet(invalidation_set, descendant_features); @@ -954,9 +957,12 @@ SetInvalidatesNth(sibling_invalidation_set); } } else { - AddFeaturesToInvalidationSet( - EnsureSiblingDescendantInvalidationSet(sibling_invalidation_set), - descendant_features); + InvalidationSetType* sibling_descendant_set = + EnsureSiblingDescendantInvalidationSet(sibling_invalidation_set); + if (sibling_descendant_set != nullptr) { + AddFeaturesToInvalidationSet(sibling_descendant_set, + descendant_features); + } } return; } @@ -1060,16 +1066,21 @@ const InvalidationSetFeatures& descendant_features) { SiblingInvalidationSetType* universal_set = EnsureUniversalSiblingInvalidationSet(); - AddFeaturesToInvalidationSet(universal_set, sibling_features); - UpdateMaxDirectAdjacentSelectors( - universal_set, sibling_features.max_direct_adjacent_selectors); - - if (&sibling_features == &descendant_features) { - SetInvalidatesSelf(universal_set); - } else { - AddFeaturesToInvalidationSet( - EnsureSiblingDescendantInvalidationSet(universal_set), - descendant_features); + if (universal_set != nullptr) { + AddFeaturesToInvalidationSet(universal_set, sibling_features); + UpdateMaxDirectAdjacentSelectors( + universal_set, sibling_features.max_direct_adjacent_selectors); + + if (&sibling_features == &descendant_features) { + SetInvalidatesSelf(universal_set); + } else { + InvalidationSetType* sibling_descendant_set = + EnsureSiblingDescendantInvalidationSet(universal_set); + if (sibling_descendant_set != nullptr) { + AddFeaturesToInvalidationSet(sibling_descendant_set, + descendant_features); + } + } } } diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc --- chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.cc 2025-03-07 21:29:53.000000000 +0000 @@ -214,13 +214,13 @@ CharacterData* character_data) { String origin_url = GetOriginUrl(character_data); if (origin_url) - origin_url_map_->insert(character_data->GetDomNodeId(), origin_url); + origin_url_map_->map.insert(character_data->GetDomNodeId(), origin_url); } void InspectorDOMSnapshotAgent::DidInsertDOMNode(Node* node) { String origin_url = GetOriginUrl(node); if (origin_url) - origin_url_map_->insert(node->GetDomNodeId(), origin_url); + origin_url_map_->map.insert(node->GetDomNodeId(), origin_url); } void InspectorDOMSnapshotAgent::EnableAndReset() { @@ -264,8 +264,10 @@ Document* document = inspected_frames_->Root()->GetDocument(); if (!document) return protocol::Response::ServerError("Document is not available"); - LegacyDOMSnapshotAgent legacySupport(dom_debugger_agent_, - origin_url_map_.get()); + LegacyDOMSnapshotAgent legacySupport( + dom_debugger_agent_, origin_url_map_ + ? origin_url_map_->weak_ptr_factory.GetWeakPtr() + : base::WeakPtr()); return legacySupport.GetSnapshot( document, std::move(style_filter), std::move(include_event_listeners), std::move(include_paint_order), std::move(include_user_agent_shadow_tree), @@ -517,16 +519,17 @@ BuildArrayForElementAttributes(node)); BuildLayoutTreeNode(node->GetLayoutObject(), node, index, contrast); - if (origin_url_map_ && origin_url_map_->Contains(backend_node_id)) { - String origin_url = origin_url_map_->at(backend_node_id); + if (origin_url_map_ && origin_url_map_->map.Contains(backend_node_id)) { + String origin_url = origin_url_map_->map.at(backend_node_id); // In common cases, it is implicit that a child node would have the same // origin url as its parent, so no need to mark twice. if (!node->parentNode()) { SetRare(nodes->getOriginURL(nullptr), index, std::move(origin_url)); } else { DOMNodeId parent_id = node->parentNode()->GetDomNodeId(); - auto it = origin_url_map_->find(parent_id); - String parent_url = it != origin_url_map_->end() ? it->value : String(); + auto it = origin_url_map_->map.find(parent_id); + String parent_url = + it != origin_url_map_->map.end() ? it->value : String(); if (parent_url != origin_url) SetRare(nodes->getOriginURL(nullptr), index, std::move(origin_url)); } diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h --- chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/inspector_dom_snapshot_agent.h 2025-03-07 21:29:53.000000000 +0000 @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_DOM_SNAPSHOT_AGENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_INSPECTOR_INSPECTOR_DOM_SNAPSHOT_AGENT_H_ +#include "base/memory/weak_ptr.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h" @@ -25,6 +26,7 @@ class InspectedFrames; class Node; class PaintLayer; +struct OriginUrlMap; class CORE_EXPORT InspectorDOMSnapshotAgent final : public InspectorBaseAgent { @@ -105,7 +107,6 @@ static void VisitPaintLayer(PaintLayer*, PaintOrderMap* paint_order_map); using CSSPropertyFilter = Vector; - using OriginUrlMap = WTF::HashMap; // State of current snapshot. std::unique_ptr> dom_nodes_; diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map_test.cc chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map_test.cc --- chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map_test.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/invalidation_set_to_selector_map_test.cc 2025-03-07 21:29:53.000000000 +0000 @@ -535,6 +535,76 @@ EXPECT_EQ(found_event_count, 1u); } +TEST_F(InvalidationSetToSelectorMapTest, + StartTracingLateWithPendingInsertRule_UniversalSiblingRules) { + SetBodyInnerHTML(R"HTML( + +
+
A
+
B +
  • C + D +
  • +
    +
    + )HTML"); + + StartTracing(); + + // Insert the first rule and perform a mutation to trigger a revisit. + // If we complete the revisit without crashing, this part of the test is + // considered to have passed. + DummyExceptionStateForTesting exception_state; + CSSStyleSheet* sheet = + To(GetElementById("target"))->sheet(); + sheet->insertRule("* + .x { color: red }", 0, exception_state); + Element* first = GetElementById("first"); + first->classList().Remove(AtomicString("a")); + first->removeAttribute(html_names::kClassAttr); + UpdateAllLifecyclePhasesForTest(); + + // Stop tracing, ensure the tracker is shut down, and restart tracing + // to set up for the next part of the test. + StopTracing(); + InvalidationSetToSelectorMap::StartOrStopTrackingIfNeeded( + GetDocument().GetStyleEngine()); + EXPECT_EQ(GetInstance(), nullptr); + StartTracing(); + + // Insert the second rule, exercising the case where we have an indexed + // universal sibling rule and a pending sibling-descendant rule, and + // perform another mutation to trigger another revisit. + sheet->insertRule("* + .b li span { color: red }", 0, exception_state); + first->classList().Add(AtomicString("a")); + UpdateAllLifecyclePhasesForTest(); + + // Now perform a mutation that will actually invalidate with the second rule. + first->parentNode()->removeChild(first); + UpdateAllLifecyclePhasesForTest(); + + auto analyzer = StopTracing(); + trace_analyzer::TraceEventVector events; + analyzer->FindEvents(trace_analyzer::Query::EventNameIs( + "StyleInvalidatorInvalidationTracking"), + &events); + size_t found_event_count = 0; + for (auto event : events) { + ASSERT_TRUE(event->HasDictArg("data")); + base::Value::Dict data_dict = event->GetKnownArgAsDict("data"); + std::string* reason = data_dict.FindString("reason"); + if (reason != nullptr && *reason == "Invalidation set matched class") { + base::Value::List* selector_list = data_dict.FindList("selectors"); + if (selector_list != nullptr) { + EXPECT_EQ(selector_list->size(), 1u); + EXPECT_EQ((*selector_list)[0], "* + .b li span"); + found_event_count++; + } + } + } + EXPECT_EQ(found_event_count, 1u); +} + TEST_F(InvalidationSetToSelectorMapTest, HandleRebuildAfterRuleSetChange) { // This test is intended to cover the case that necessitates us walking both // global and per-sheet rule sets when revisiting invalidation data on a late @@ -574,8 +644,7 @@ StartTracing(); - // Invalidation data revisit happens on the first lifecycle update following - // the start of tracing. Perform a simple mutation to cause that to happen. + // Perform a simple mutation to trigger initial invalidation data revisit. GetDocument().body()->appendChild( GetDocument().CreateRawElement(html_names::kDivTag)); UpdateAllLifecyclePhasesForTest(); diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc --- chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.cc 2025-03-07 21:29:53.000000000 +0000 @@ -97,8 +97,8 @@ LegacyDOMSnapshotAgent::LegacyDOMSnapshotAgent( InspectorDOMDebuggerAgent* dom_debugger_agent, - OriginUrlMap* origin_url_map) - : origin_url_map_(origin_url_map), + base::WeakPtr origin_url_map) + : origin_url_map_(std::move(origin_url_map)), dom_debugger_agent_(dom_debugger_agent) {} LegacyDOMSnapshotAgent::~LegacyDOMSnapshotAgent() = default; @@ -186,16 +186,18 @@ .setBackendNodeId(IdentifiersFactory::IntIdForNode(node)) .build(); if (origin_url_map_ && - origin_url_map_->Contains(owned_value->getBackendNodeId())) { - String origin_url = origin_url_map_->at(owned_value->getBackendNodeId()); + origin_url_map_->map.Contains(owned_value->getBackendNodeId())) { + String origin_url = + origin_url_map_->map.at(owned_value->getBackendNodeId()); // In common cases, it is implicit that a child node would have the same // origin url as its parent, so no need to mark twice. if (!node->parentNode()) { owned_value->setOriginURL(std::move(origin_url)); } else { DOMNodeId parent_id = node->parentNode()->GetDomNodeId(); - auto it = origin_url_map_->find(parent_id); - String parent_url = it != origin_url_map_->end() ? it->value : String(); + auto it = origin_url_map_->map.find(parent_id); + String parent_url = + it != origin_url_map_->map.end() ? it->value : String(); if (parent_url != origin_url) owned_value->setOriginURL(std::move(origin_url)); } diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h --- chromium-134.0.6998.35/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/core/inspector/legacy_dom_snapshot_agent.h 2025-03-07 21:29:53.000000000 +0000 @@ -22,12 +22,17 @@ class Node; class PaintLayer; +struct OriginUrlMap { + WTF::HashMap map; + base::WeakPtrFactory weak_ptr_factory{this}; +}; + class CORE_EXPORT LegacyDOMSnapshotAgent { STACK_ALLOCATED(); public: - using OriginUrlMap = WTF::HashMap; - LegacyDOMSnapshotAgent(InspectorDOMDebuggerAgent*, OriginUrlMap*); + LegacyDOMSnapshotAgent(InspectorDOMDebuggerAgent*, + base::WeakPtr); LegacyDOMSnapshotAgent(const LegacyDOMSnapshotAgent&) = delete; LegacyDOMSnapshotAgent& operator=(const LegacyDOMSnapshotAgent&) = delete; ~LegacyDOMSnapshotAgent(); @@ -98,7 +103,7 @@ PaintOrderMap* paint_order_map_ = nullptr; // Maps a backend node id to the url of the script (if any) that generates // the corresponding node. - OriginUrlMap* origin_url_map_; + base::WeakPtr origin_url_map_; using DocumentOrderMap = HeapHashMap, int>; InspectorDOMDebuggerAgent* dom_debugger_agent_; }; diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc chromium-134.0.6998.88/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc --- chromium-134.0.6998.35/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc 2025-03-07 21:29:53.000000000 +0000 @@ -4056,11 +4056,16 @@ // The active descendant or focus may lose its implicit selected state. Node* focus = FocusedNode(); if (focus == container->GetNode()) { - if (AXObject* activedescendant = container->ActiveDescendant()) { - AddDirtyObjectToSerializationQueue(activedescendant); + if (const Element* activedescendant = + AXObject::ElementFromAttributeOrInternals( + container->GetElement(), + html_names::kAriaActivedescendantAttr)) { + if (const AXObject* ax_activedescendant = Get(activedescendant)) { + AddDirtyObjectToSerializationQueue(ax_activedescendant); + } } } - if (AXObject* ax_focus = Get(focus)) { + if (const AXObject* ax_focus = Get(focus)) { AddDirtyObjectToSerializationQueue(ax_focus); } } @@ -4640,6 +4645,10 @@ CHECK(relation_cache_); if (AXObject* obj = Get(node)) { relation_cache_->UpdateAriaOwnsWithCleanLayout(obj); + // Make sure that the owner's children are updated even in the case where + // aria-owns is empty, or the object is not a valid owner. This protects + // from ending up with parent containing invalid children. + ChildrenChangedWithCleanLayout(obj); } } diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc chromium-134.0.6998.88/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc --- chromium-134.0.6998.35/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1429,12 +1429,6 @@ WTF::BindRepeating(&WebGLRenderingContextBase::OnErrorMessage, WrapWeakPersistent(this))); - // If WebGL 2, the PRIMITIVE_RESTART_FIXED_INDEX should be always enabled. - // See the section in WebGL 2 spec: - // https://www.khronos.org/registry/webgl/specs/latest/2.0/#4.1.4 - if (IsWebGL2()) - ContextGL()->Enable(GL_PRIMITIVE_RESTART_FIXED_INDEX); - // This ensures that the context has a valid "lastFlushID" and won't be // mistakenly identified as the "least recently used" context. ContextGL()->Flush(); diff -Nru chromium-134.0.6998.35/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc chromium-134.0.6998.88/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc --- chromium-134.0.6998.35/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/blink/renderer/platform/webrtc/peer_connection_remote_audio_source.cc 2025-03-07 21:29:53.000000000 +0000 @@ -62,12 +62,14 @@ "PCRAT::SetEnabled([id=%s] {enabled=%s})", track_interface_->id().c_str(), base::ToString(enabled).c_str())); - // TODO(crbug.com/40849402): AudioTrackInterface::set_enabled() is not called - // because doing so would set the volume to 0 for the source level in the - // receiving audio in the WebRTC side. - // For now, we skip calling AudioTrackInterface::set_enabled() to avoid these - // issues. We need to monitor this approach to ensure that skipping - // set_enabled() does not introduce regressions. + // This affects the shared state of the source for whether or not it's a part + // of the mixed audio that's rendered for remote tracks from WebRTC. + // All tracks from the same source will share this state and thus can step + // on each other's toes. + // This is also why we can't check the enabled state for equality with + // |enabled| before setting the mixing enabled state. This track's enabled + // state and the shared state might not be the same. + track_interface_->set_enabled(enabled); MediaStreamAudioTrack::SetEnabled(enabled); } diff -Nru chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.test.ts chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.test.ts --- chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.test.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.test.ts 2025-03-07 21:29:53.000000000 +0000 @@ -94,6 +94,31 @@ }); }); + it('handles worker requests originating from the frame target', async () => { + const target = createTarget(); + const workerTarget = createTarget({type: SDK.Target.Type.Worker}); + + const multiTargetNetworkManager = SDK.NetworkManager.MultitargetNetworkManager.instance(); + const initialNetworkManager = target.model(SDK.NetworkManager.NetworkManager)!; + + assert.strictEqual(multiTargetNetworkManager.inflightMainResourceRequests.size, 0); + + const requestId = 'mockId'; + const requestPromise = initialNetworkManager.once(SDK.NetworkManager.Events.RequestStarted); + initialNetworkManager.dispatcher.requestWillBeSent( + {requestId, loaderId: '', request: {url: 'example.com'}} as Protocol.Network.RequestWillBeSentEvent); + + const {request} = await requestPromise; + assert.isOk(SDK.NetworkManager.NetworkManager.forRequest(request) === initialNetworkManager); + assert.isOk(multiTargetNetworkManager.inflightMainResourceRequests.has(requestId)); + + const workerNetworkManager = workerTarget.model(SDK.NetworkManager.NetworkManager)!; + workerNetworkManager.dispatcher.loadingFinished({requestId} as Protocol.Network.LoadingFinishedEvent); + + assert.isOk(SDK.NetworkManager.NetworkManager.forRequest(request) === workerNetworkManager); + assert.isOk(!multiTargetNetworkManager.inflightMainResourceRequests.has(requestId)); + }); + it('uses main frame to get certificate', () => { SDK.ChildTargetManager.ChildTargetManager.install(); const tabTarget = createTarget({type: SDK.Target.Type.TAB}); diff -Nru chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts --- chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts 2025-03-07 21:29:53.000000000 +0000 @@ -1106,9 +1106,12 @@ if (loaderId) { this.#requestsByLoaderId.set(loaderId, networkRequest); } - // The following relies on the fact that loaderIds and requestIds are - // globally unique and that the main request has them equal. - if (networkRequest.loaderId === networkRequest.requestId()) { + // The following relies on the fact that loaderIds and requestIds + // are globally unique and that the main request has them equal. If + // loaderId is an empty string, it indicates a worker request. For the + // request to fetch the main worker script, the request ID is the future + // worker target ID and, therefore, it is unique. + if (networkRequest.loaderId === networkRequest.requestId() || networkRequest.loaderId === '') { MultitargetNetworkManager.instance().inflightMainResourceRequests.set(networkRequest.requestId(), networkRequest); } diff -Nru chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/panels/sources/SourcesView.ts chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/panels/sources/SourcesView.ts --- chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/panels/sources/SourcesView.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/panels/sources/SourcesView.ts 2025-03-07 21:29:53.000000000 +0000 @@ -148,6 +148,7 @@ private placeholderElement(): Element { const placeholder = document.createElement('div'); + placeholder.classList.add('sources-placeholder'); const workspaceElement = placeholder.createChild('div', 'tabbed-pane-placeholder-row'); workspaceElement.classList.add('workspace'); diff -Nru chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/ui/components/text_editor/theme.ts chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/components/text_editor/theme.ts --- chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/ui/components/text_editor/theme.ts 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/components/text_editor/theme.ts 2025-03-07 21:29:53.000000000 +0000 @@ -51,6 +51,10 @@ background: 'var(--sys-color-tonal-container)', }, + '.cm-line::selection': { + color: 'currentColor', + }, + '.cm-selectionBackground': { background: 'var(--sys-color-neutral-container)', }, diff -Nru chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/ui/legacy/tabbedPane.css chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/legacy/tabbedPane.css --- chromium-134.0.6998.35/third_party/devtools-frontend/src/front_end/ui/legacy/tabbedPane.css 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/devtools-frontend/src/front_end/ui/legacy/tabbedPane.css 2025-03-07 21:29:53.000000000 +0000 @@ -48,6 +48,10 @@ .tabbed-pane-placeholder { text-align: center; align-content: center; + + .sources-placeholder { + display: inline-block; + } } .tabbed-pane-placeholder-row { diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/Cargo.lock chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.lock --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/Cargo.lock 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.lock 2025-03-07 21:29:53.000000000 +0000 @@ -1198,7 +1198,7 @@ [[package]] name = "skrifa" -version = "0.26.5" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytemuck", diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/Cargo.toml chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.toml --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/Cargo.toml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/Cargo.toml 2025-03-07 21:29:53.000000000 +0000 @@ -43,7 +43,7 @@ rustc-demangle-capi = "0.1" serde = "1" serde_json = "1" -skrifa = "0.26.3" +skrifa = "0.26.6" small_ctor = "0.1" static_assertions = "1" strum = "0.25.0" diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/supply-chain/audits.toml chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/audits.toml --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/supply-chain/audits.toml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/audits.toml 2025-03-07 21:29:53.000000000 +0000 @@ -3068,6 +3068,12 @@ delta = "0.26.4 -> 0.26.5" notes = "Contains fixes for hdmx metrics for fonts such as Arimo, Tinos, Market Sans." +[[audits.skrifa]] +who = "Dominik Röttsches " +criteria = ["safe-to-deploy", "does-not-implement-crypto", "ub-risk-0"] +delta = "0.26.5 -> 0.26.6" +notes = "Cherry-pick of hang in GSUB processing in Skrifa during autohinting." + [[audits.small_ctor]] who = "danakj@chromium.org" criteria = ["safe-to-run", "does-not-implement-crypto"] diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/supply-chain/config.toml chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/config.toml --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/supply-chain/config.toml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/supply-chain/config.toml 2025-03-07 21:29:53.000000000 +0000 @@ -416,7 +416,7 @@ [policy."simd-adler32:0.3.7"] criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"] -[policy."skrifa:0.26.5"] +[policy."skrifa:0.26.6"] criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"] [policy."small_ctor:0.1.2"] diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo-checksum.json chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo-checksum.json --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo-checksum.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -{"files":{}} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo_vcs_info.json chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo_vcs_info.json --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo_vcs_info.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -{ - "git": { - "sha1": "57715f398fdc5c4444cd19eb07105fc0df56316c" - }, - "path_in_vcs": "skrifa" -} \ No newline at end of file diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.lock chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.lock --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.lock 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.lock 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - -[[package]] -name = "bytemuck" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "core_maths" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b02505ccb8c50b0aa21ace0fc08c3e53adebd4e58caa18a36152803c7709a3" -dependencies = [ - "libm", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "font-types" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c3a23a5a151afb1f74ea797f8c300dee41eff9ee3cb1bf94ed316d860c46b3" -dependencies = [ - "bytemuck", - "serde", -] - -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "itoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" - -[[package]] -name = "kurbo" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5aa9f0f96a938266bdb12928a67169e8d22c6a786fda8ed984b85e6ba93c3c" -dependencies = [ - "arrayvec", - "smallvec", -] - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "log" -version = "0.4.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" - -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi", -] - -[[package]] -name = "proc-macro2" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "read-fonts" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f9e8a4f503e5c8750e4cd3b32a4e090035c46374b305a15c70bad833dca05f" -dependencies = [ - "bytemuck", - "core_maths", - "font-types", - "serde", -] - -[[package]] -name = "ryu" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" - -[[package]] -name = "serde" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.197" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "skrifa" -version = "0.26.5" -dependencies = [ - "bytemuck", - "core_maths", - "kurbo", - "pretty_assertions", - "read-fonts", - "serde", - "serde_json", - "write-fonts", -] - -[[package]] -name = "smallvec" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" - -[[package]] -name = "syn" -version = "2.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "write-fonts" -version = "0.33.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4569c5d3e6a8ca11632efeb1f13105663e3643a77de21d3dbc1a7c2ed80a10" -dependencies = [ - "font-types", - "indexmap", - "kurbo", - "log", - "read-fonts", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.toml chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.toml --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.toml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. -# -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. - -[package] -edition = "2021" -name = "skrifa" -version = "0.26.5" -build = false -autolib = false -autobins = false -autoexamples = false -autotests = false -autobenches = false -description = "Metadata reader and glyph scaler for OpenType fonts." -readme = "README.md" -categories = [ - "text-processing", - "parsing", - "graphics", -] -license = "MIT OR Apache-2.0" -repository = "https://github.com/googlefonts/fontations" - -[package.metadata.docs.rs] -all-features = true - -[lib] -name = "skrifa" -path = "src/lib.rs" - -[dependencies.bytemuck] -version = "1.13.1" - -[dependencies.core_maths] -version = "0.1" -optional = true - -[dependencies.read-fonts] -version = "0.25.3" -default-features = false - -[dev-dependencies.kurbo] -version = "0.11.0" - -[dev-dependencies.pretty_assertions] -version = "1.3.0" - -[dev-dependencies.read-fonts] -version = "0.25.3" -features = [ - "scaler_test", - "serde", -] -default-features = false - -[dev-dependencies.serde] -version = "1.0" - -[dev-dependencies.serde_json] -version = "1.0" - -[dev-dependencies.write-fonts] -version = "0.33.1" - -[features] -autohint_shaping = [] -default = [ - "autohint_shaping", - "traversal", -] -libm = [ - "dep:core_maths", - "read-fonts/libm", -] -spec_next = ["read-fonts/spec_next"] -std = ["read-fonts/std"] -traversal = [ - "std", - "read-fonts/experimental_traverse", -] diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -Copyright 2019 Colin Rothfels - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-MIT chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-MIT --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-MIT 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -Copyright (c) 2019 Colin Rothfels - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/README.md chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/README.md --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/README.md 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/README.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -# skrifa - -[![Crates.io](https://img.shields.io/crates/v/skrifa.svg)](https://crates.io/crates/skrifa) -[![Docs](https://docs.rs/skrifa/badge.svg)](https://docs.rs/skrifa) -[![MIT/Apache 2.0](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](#license) - -This crate aims to be a robust, ergonomic, high performance library for reading -OpenType fonts. It is built on top of the -[read-fonts](https://github.com/googlefonts/fontations/tree/main/read-fonts) -low level parsing library and is also part of the -[oxidize](https://github.com/googlefonts/oxidize) project. - -## Features - -### Metadata - -The following information is currently exposed: - -* Global font metrics with variation support (units per em, ascender, -descender, etc) -* Glyph metrics with variation support (advance width, left side-bearing, etc) -* Codepoint to nominal glyph identifier mapping - * Unicode variation sequences -* Localized strings -* Attributes (stretch, style and weight) -* Variation axes and named instances - * Conversion from user coordinates to normalized design coordinates - -Future goals include: - -* Color palettes -* Embedded bitmap strikes - -### Glyph formats - -| Source | Decoding | Variations | Hinting | -|--------|----------|------------|---------| -| glyf | ✔️ | ✔️ | ✔️ | -| CFF | ✔️ | - | ✔️ | -| CFF2 | ✔️ | ✔️ | ✔️ | -| COLRv0 | ✔️ | - | - | -| COLRv1 | ✔️ | ✔️ | - | -| EBDT | ✔️* | - | - | -| CBDT | ✔️* | - | - | -| sbix | ✔️* | - | - | - -\* Raw support available through the `read-fonts` crate. - -## Panicking - -This library should not panic regardless of API misuse or use of -corrupted/malicious font files. Please file an issue if this occurs. - -## The name? - -Following along with our theme, *skrifa* is Old Norse for "write" or "it is -written." And so it is named. - -## Safety - -Unsafe code is forbidden by a `#![forbid(unsafe_code)]` attribute in the root -of the library. diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/generated/generated_autohint_styles.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/generated/generated_autohint_styles.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/generated/generated_autohint_styles.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/generated/generated_autohint_styles.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1440 +0,0 @@ -// THIS FILE IS AUTOGENERATED. -// Any changes to this file will be overwritten. -// Use ../scripts/gen_autohint_scripts.py to regenerate. - -#[rustfmt::skip] -pub(super) const SCRIPT_CLASSES: &[ScriptClass] = &[ - ScriptClass { - name: "Adlam", - group: ScriptGroup::Default, - tag: Tag::new(b"Adlm"), - hint_top_to_bottom: false, - std_chars: "𞤌 𞤮", - blues: &[ - ("𞤌 𞤅 𞤈 𞤏 𞤔 𞤚", BlueZones::TOP), - ("𞤂 𞤖", BlueZones::NONE), - ("𞤬 𞤮 𞤻 𞤼 𞤾", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Arabic", - group: ScriptGroup::Default, - tag: Tag::new(b"Arab"), - hint_top_to_bottom: false, - std_chars: "ل ح ـ", - blues: &[ - ("ا إ ل ك ط ظ", BlueZones::TOP), - ("ت ث ط ظ ك", BlueZones::NONE), - ("ـ", BlueZones::NEUTRAL), - ], - }, - ScriptClass { - name: "Armenian", - group: ScriptGroup::Default, - tag: Tag::new(b"Armn"), - hint_top_to_bottom: false, - std_chars: "ս Ս", - blues: &[ - ("Ա Մ Ւ Ս Բ Գ Դ Օ", BlueZones::TOP), - ("Ւ Ո Դ Ճ Շ Ս Տ Օ", BlueZones::NONE), - ("ե է ի մ վ ֆ ճ", BlueZones::TOP), - ("ա յ ւ ս գ շ ր օ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("հ ո ճ ա ե ծ ս օ", BlueZones::NONE), - ("բ ը ի լ ղ պ փ ց", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Avestan", - group: ScriptGroup::Default, - tag: Tag::new(b"Avst"), - hint_top_to_bottom: false, - std_chars: "𐬚", - blues: &[ - ("𐬀 𐬁 𐬐 𐬛", BlueZones::TOP), - ("𐬀 𐬁", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Bamum", - group: ScriptGroup::Default, - tag: Tag::new(b"Bamu"), - hint_top_to_bottom: false, - std_chars: "ꛁ ꛯ", - blues: &[ - ("ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ", BlueZones::TOP), - ("ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Bengali", - group: ScriptGroup::Default, - tag: Tag::new(b"Beng"), - hint_top_to_bottom: true, - std_chars: "০ ৪", - blues: &[ - ("ই ট ঠ ি ী ৈ ৗ", BlueZones::TOP), - ("ও এ ড ত ন ব ল ক", BlueZones::TOP), - ("অ ড ত ন ব ভ ল ক", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), - ("অ ড ত ন ব ভ ল ক", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Buhid", - group: ScriptGroup::Default, - tag: Tag::new(b"Buhd"), - hint_top_to_bottom: false, - std_chars: "ᝋ ᝏ", - blues: &[ - ("ᝐ ᝈ", BlueZones::TOP), - ("ᝅ ᝊ ᝎ", BlueZones::TOP), - ("ᝂ ᝃ ᝉ ᝌ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Chakma", - group: ScriptGroup::Default, - tag: Tag::new(b"Cakm"), - hint_top_to_bottom: false, - std_chars: "𑄤 𑄉 𑄛", - blues: &[ - ("𑄃 𑄅 𑄉 𑄙 𑄗", BlueZones::TOP), - ("𑄅 𑄛 𑄝 𑄗 𑄓", BlueZones::NONE), - ("𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Canadian Syllabics", - group: ScriptGroup::Default, - tag: Tag::new(b"Cans"), - hint_top_to_bottom: false, - std_chars: "ᑌ ᓚ", - blues: &[ - ("ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ", BlueZones::TOP), - ("ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ", BlueZones::NONE), - ("ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ", BlueZones::NONE), - ("ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ", BlueZones::TOP), - ("ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Carian", - group: ScriptGroup::Default, - tag: Tag::new(b"Cari"), - hint_top_to_bottom: false, - std_chars: "𐊫 𐋉", - blues: &[ - ("𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿", BlueZones::TOP), - ("𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Cherokee", - group: ScriptGroup::Default, - tag: Tag::new(b"Cher"), - hint_top_to_bottom: false, - std_chars: "Ꭴ Ꮕ ꮕ", - blues: &[ - ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", BlueZones::TOP), - ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", BlueZones::NONE), - ("ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ", BlueZones::TOP), - ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", BlueZones::NONE), - ("ᏸ ꮐ ꭹ ꭻ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Coptic", - group: ScriptGroup::Default, - tag: Tag::new(b"Copt"), - hint_top_to_bottom: false, - std_chars: "Ⲟ ⲟ", - blues: &[ - ("Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ", BlueZones::TOP), - ("Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ", BlueZones::NONE), - ("ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Cypriot", - group: ScriptGroup::Default, - tag: Tag::new(b"Cprt"), - hint_top_to_bottom: false, - std_chars: "𐠅 𐠣", - blues: &[ - ("𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦", BlueZones::TOP), - ("𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐", BlueZones::NONE), - ("𐠈 𐠏 𐠖", BlueZones::TOP), - ("𐠈 𐠏 𐠖", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Cyrillic", - group: ScriptGroup::Default, - tag: Tag::new(b"Cyrl"), - hint_top_to_bottom: false, - std_chars: "о О", - blues: &[ - ("Б В Е П З О С Э", BlueZones::TOP), - ("Б В Е Ш З О С Э", BlueZones::NONE), - ("х п н ш е з о с", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("х п н ш е з о с", BlueZones::NONE), - ("р у ф", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Devanagari", - group: ScriptGroup::Default, - tag: Tag::new(b"Deva"), - hint_top_to_bottom: true, - std_chars: "ठ व ट", - blues: &[ - ("ई ऐ ओ औ ि ी ो ौ", BlueZones::TOP), - ("क म अ आ थ ध भ श", BlueZones::TOP), - ("क न म उ छ ट ठ ड", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), - ("क न म उ छ ट ठ ड", BlueZones::NONE), - ("ु ृ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Deseret", - group: ScriptGroup::Default, - tag: Tag::new(b"Dsrt"), - hint_top_to_bottom: false, - std_chars: "𐐄 𐐬", - blues: &[ - ("𐐂 𐐄 𐐋 𐐗 𐐑", BlueZones::TOP), - ("𐐀 𐐂 𐐄 𐐗 𐐛", BlueZones::NONE), - ("𐐪 𐐬 𐐳 𐐿 𐐹", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("𐐨 𐐪 𐐬 𐐿 𐑃", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Ethiopic", - group: ScriptGroup::Default, - tag: Tag::new(b"Ethi"), - hint_top_to_bottom: false, - std_chars: "ዐ", - blues: &[ - ("ሀ ሃ ዘ ፐ ማ በ ዋ ዐ", BlueZones::TOP), - ("ለ ሐ በ ዘ ሀ ሪ ዐ ጨ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Georgian (Mkhedruli)", - group: ScriptGroup::Default, - tag: Tag::new(b"Geor"), - hint_top_to_bottom: false, - std_chars: "ი ე ა Ჿ", - blues: &[ - ("გ დ ე ვ თ ი ო ღ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ა ზ მ ს შ ძ ხ პ", BlueZones::NONE), - ("ს ხ ქ ზ მ შ ჩ წ", BlueZones::TOP), - ("ე ვ ჟ ტ უ ფ ქ ყ", BlueZones::NONE), - ("Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ", BlueZones::TOP), - ("Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Georgian (Khutsuri)", - group: ScriptGroup::Default, - tag: Tag::new(b"Geok"), - hint_top_to_bottom: false, - std_chars: "Ⴖ Ⴑ ⴙ", - blues: &[ - ("Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ", BlueZones::TOP), - ("Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ", BlueZones::NONE), - ("ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ", BlueZones::NONE), - ("ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ", BlueZones::TOP), - ("ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Glagolitic", - group: ScriptGroup::Default, - tag: Tag::new(b"Glag"), - hint_top_to_bottom: false, - std_chars: "Ⱅ ⱅ", - blues: &[ - ("Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ", BlueZones::TOP), - ("Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ", BlueZones::NONE), - ("ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Gothic", - group: ScriptGroup::Default, - tag: Tag::new(b"Goth"), - hint_top_to_bottom: true, - std_chars: "𐌴 𐌾 𐍃", - blues: &[ - ("𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾", BlueZones::TOP), - ("𐌶 𐌴 𐍃 𐍈", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Greek", - group: ScriptGroup::Default, - tag: Tag::new(b"Grek"), - hint_top_to_bottom: false, - std_chars: "ο Ο", - blues: &[ - ("Γ Β Ε Ζ Θ Ο Ω", BlueZones::TOP), - ("Β Δ Ζ Ξ Θ Ο", BlueZones::NONE), - ("β θ δ ζ λ ξ", BlueZones::TOP), - ("α ε ι ο π σ τ ω", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("α ε ι ο π σ τ ω", BlueZones::NONE), - ("β γ η μ ρ φ χ ψ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Gujarati", - group: ScriptGroup::Default, - tag: Tag::new(b"Gujr"), - hint_top_to_bottom: false, - std_chars: "ટ ૦", - blues: &[ - ("ત ન ઋ ઌ છ ટ ર ૦", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ખ ગ ઘ ઞ ઇ ઈ ઠ જ", BlueZones::NONE), - ("ઈ ઊ િ ી લી શ્ચિ જિ સી", BlueZones::TOP), - ("ુ ૃ ૄ ખુ છૃ છૄ", BlueZones::NONE), - ("૦ ૧ ૨ ૩ ૭", BlueZones::TOP), - ], - }, - ScriptClass { - name: "Gurmukhi", - group: ScriptGroup::Default, - tag: Tag::new(b"Guru"), - hint_top_to_bottom: true, - std_chars: "ਠ ਰ ੦", - blues: &[ - ("ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ", BlueZones::TOP), - ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", BlueZones::TOP), - ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), - ("ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ", BlueZones::NONE), - ("੦ ੧ ੨ ੩ ੭", BlueZones::TOP), - ], - }, - ScriptClass { - name: "Hebrew", - group: ScriptGroup::Default, - tag: Tag::new(b"Hebr"), - hint_top_to_bottom: false, - std_chars: "ם", - blues: &[ - ("ב ד ה ח ך כ ם ס", BlueZones::TOP.union(BlueZones::LONG)), - ("ב ט כ ם ס צ", BlueZones::NONE), - ("ק ך ן ף ץ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Kayah Li", - group: ScriptGroup::Default, - tag: Tag::new(b"Kali"), - hint_top_to_bottom: false, - std_chars: "ꤍ ꤀", - blues: &[ - ("꤅ ꤏ ꤁ ꤋ ꤀ ꤍ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("꤈ ꤘ ꤀ ꤍ ꤢ", BlueZones::NONE), - ("ꤖ ꤡ", BlueZones::TOP), - ("ꤑ ꤜ ꤞ", BlueZones::NONE), - ("ꤑ꤬ ꤜ꤭ ꤔ꤬", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Khmer", - group: ScriptGroup::Default, - tag: Tag::new(b"Khmr"), - hint_top_to_bottom: false, - std_chars: "០", - blues: &[ - ("ខ ទ ន ឧ ឩ ា", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ក្ក ក្ខ ក្គ ក្ថ", BlueZones::SUB_TOP), - ("ខ ឃ ច ឋ ប ម យ ឲ", BlueZones::NONE), - ("ត្រ រៀ ឲ្យ អឿ", BlueZones::NONE), - ("ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Khmer Symbols", - group: ScriptGroup::Default, - tag: Tag::new(b"Khms"), - hint_top_to_bottom: false, - std_chars: "᧡ ᧪", - blues: &[ - ("᧠ ᧡", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("᧶ ᧹", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Kannada", - group: ScriptGroup::Default, - tag: Tag::new(b"Knda"), - hint_top_to_bottom: false, - std_chars: "೦ ಬ", - blues: &[ - ("ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ", BlueZones::TOP), - ("ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Lao", - group: ScriptGroup::Default, - tag: Tag::new(b"Laoo"), - hint_top_to_bottom: false, - std_chars: "໐", - blues: &[ - ("າ ດ ອ ມ ລ ວ ຣ ງ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("າ ອ ບ ຍ ຣ ຮ ວ ຢ", BlueZones::NONE), - ("ປ ຢ ຟ ຝ", BlueZones::TOP), - ("ໂ ໄ ໃ", BlueZones::TOP), - ("ງ ຊ ຖ ຽ ໆ ຯ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Latin", - group: ScriptGroup::Default, - tag: Tag::new(b"Latn"), - hint_top_to_bottom: false, - std_chars: "o O 0", - blues: &[ - ("T H E Z O C Q S", BlueZones::TOP), - ("H E Z L O C U S", BlueZones::NONE), - ("f i j k d b h", BlueZones::TOP), - ("u v x z o e s c", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("n r x z o e s c", BlueZones::NONE), - ("p q g j y", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Latin Subscript Fallback", - group: ScriptGroup::Default, - tag: Tag::new(b"Latb"), - hint_top_to_bottom: false, - std_chars: "ₒ ₀", - blues: &[ - ("₀ ₃ ₅ ₇ ₈", BlueZones::TOP), - ("₀ ₁ ₂ ₃ ₈", BlueZones::NONE), - ("ᵢ ⱼ ₕ ₖ ₗ", BlueZones::TOP), - ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", BlueZones::NONE), - ("ᵦ ᵧ ᵨ ᵩ ₚ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Latin Superscript Fallback", - group: ScriptGroup::Default, - tag: Tag::new(b"Latp"), - hint_top_to_bottom: false, - std_chars: "ᵒ ᴼ ⁰", - blues: &[ - ("⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ", BlueZones::TOP), - ("⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ", BlueZones::NONE), - ("ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ", BlueZones::TOP), - ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", BlueZones::NONE), - ("ᵖ ʸ ᵍ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Lisu", - group: ScriptGroup::Default, - tag: Tag::new(b"Lisu"), - hint_top_to_bottom: false, - std_chars: "ꓳ", - blues: &[ - ("ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ", BlueZones::TOP), - ("ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Malayalam", - group: ScriptGroup::Default, - tag: Tag::new(b"Mlym"), - hint_top_to_bottom: false, - std_chars: "ഠ റ", - blues: &[ - ("ഒ ട ഠ റ ച പ ച്ച പ്പ", BlueZones::TOP), - ("ട ഠ ധ ശ ഘ ച ഥ ല", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Medefaidrin", - group: ScriptGroup::Default, - tag: Tag::new(b"Medf"), - hint_top_to_bottom: false, - std_chars: "𖹡 𖹛 𖹯", - blues: &[ - ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟", BlueZones::TOP), - ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓", BlueZones::NONE), - ("𖹤 𖹬 𖹧 𖹴 𖹶 𖹾", BlueZones::TOP), - ("𖹠 𖹡 𖹢 𖹹 𖹳 𖹮", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("𖹠 𖹡 𖹢 𖹳 𖹭 𖹽", BlueZones::NONE), - ("𖹥 𖹨 𖹩", BlueZones::NONE), - ("𖺀 𖺅 𖺈 𖺄 𖺍", BlueZones::TOP), - ], - }, - ScriptClass { - name: "Mongolian", - group: ScriptGroup::Default, - tag: Tag::new(b"Mong"), - hint_top_to_bottom: true, - std_chars: "ᡂ ᠪ", - blues: &[ - ("ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍", BlueZones::TOP), - ("ᡃ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Myanmar", - group: ScriptGroup::Default, - tag: Tag::new(b"Mymr"), - hint_top_to_bottom: false, - std_chars: "ဝ င ဂ", - blues: &[ - ("ခ ဂ င ဒ ဝ ၥ ၊ ။", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("င ဎ ဒ ပ ဗ ဝ ၊ ။", BlueZones::NONE), - ("ဩ ြ ၍ ၏ ၆ ါ ိ", BlueZones::TOP), - ("ဉ ည ဥ ဩ ဨ ၂ ၅ ၉", BlueZones::NONE), - ], - }, - ScriptClass { - name: "N'Ko", - group: ScriptGroup::Default, - tag: Tag::new(b"Nkoo"), - hint_top_to_bottom: false, - std_chars: "ߋ ߀", - blues: &[ - ("ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ", BlueZones::TOP), - ("߀ ߘ ߡ ߠ ߥ", BlueZones::NONE), - ("ߏ ߛ ߋ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("ߎ ߏ ߛ ߋ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "no script", - group: ScriptGroup::Default, - tag: Tag::new(b"None"), - hint_top_to_bottom: false, - std_chars: "", - blues: &[], - }, - ScriptClass { - name: "Ol Chiki", - group: ScriptGroup::Default, - tag: Tag::new(b"Olck"), - hint_top_to_bottom: false, - std_chars: "ᱛ", - blues: &[ - ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", BlueZones::TOP), - ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Old Turkic", - group: ScriptGroup::Default, - tag: Tag::new(b"Orkh"), - hint_top_to_bottom: false, - std_chars: "𐰗", - blues: &[ - ("𐰗 𐰘 𐰧", BlueZones::TOP), - ("𐰉 𐰗 𐰦 𐰧", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Osage", - group: ScriptGroup::Default, - tag: Tag::new(b"Osge"), - hint_top_to_bottom: false, - std_chars: "𐓂 𐓪", - blues: &[ - ("𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆", BlueZones::TOP), - ("𐒰 𐓍 𐓂 𐒿 𐓎 𐒹", BlueZones::NONE), - ("𐒼 𐒽 𐒾", BlueZones::NONE), - ("𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶", BlueZones::NONE), - ("𐓤 𐓦 𐓸 𐓹 𐓛", BlueZones::TOP), - ("𐓤 𐓥 𐓦", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Osmanya", - group: ScriptGroup::Default, - tag: Tag::new(b"Osma"), - hint_top_to_bottom: false, - std_chars: "𐒆 𐒠", - blues: &[ - ("𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣", BlueZones::TOP), - ("𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Hanifi Rohingya", - group: ScriptGroup::Default, - tag: Tag::new(b"Rohg"), - hint_top_to_bottom: false, - std_chars: "𐴰", - blues: &[ - ("𐴃 𐴀 𐴆 𐴖 𐴕", BlueZones::TOP), - ("𐴔 𐴖 𐴕 𐴑 𐴐", BlueZones::NONE), - ("ـ", BlueZones::NEUTRAL), - ], - }, - ScriptClass { - name: "Saurashtra", - group: ScriptGroup::Default, - tag: Tag::new(b"Saur"), - hint_top_to_bottom: false, - std_chars: "ꢝ ꣐", - blues: &[ - ("ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ", BlueZones::TOP), - ("ꢂ ꢨ ꢺ ꢤ ꢎ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Shavian", - group: ScriptGroup::Default, - tag: Tag::new(b"Shaw"), - hint_top_to_bottom: false, - std_chars: "𐑴", - blues: &[ - ("𐑕 𐑙", BlueZones::TOP), - ("𐑔 𐑖 𐑗 𐑹 𐑻", BlueZones::NONE), - ("𐑟 𐑣", BlueZones::NONE), - ("𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("𐑴 𐑻 𐑹", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Sinhala", - group: ScriptGroup::Default, - tag: Tag::new(b"Sinh"), - hint_top_to_bottom: false, - std_chars: "ට", - blues: &[ - ("ඉ ක ඝ ඳ ප ය ල ෆ", BlueZones::TOP), - ("එ ඔ ඝ ජ ට ථ ධ ර", BlueZones::NONE), - ("ද ඳ උ ල තූ තු බු දු", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Sundanese", - group: ScriptGroup::Default, - tag: Tag::new(b"Sund"), - hint_top_to_bottom: false, - std_chars: "᮰", - blues: &[ - ("ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ", BlueZones::TOP), - ("ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ", BlueZones::NONE), - ("ᮼ ᳄", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Tamil", - group: ScriptGroup::Default, - tag: Tag::new(b"Taml"), - hint_top_to_bottom: false, - std_chars: "௦", - blues: &[ - ("உ ஒ ஓ ற ஈ க ங ச", BlueZones::TOP), - ("க ச ல ஶ உ ங ட ப", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Tai Viet", - group: ScriptGroup::Default, - tag: Tag::new(b"Tavt"), - hint_top_to_bottom: false, - std_chars: "ꪒ ꪫ", - blues: &[ - ("ꪆ ꪔ ꪒ ꪖ ꪫ", BlueZones::TOP), - ("ꪉ ꪫ ꪮ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Telugu", - group: ScriptGroup::Default, - tag: Tag::new(b"Telu"), - hint_top_to_bottom: false, - std_chars: "౦ ౧", - blues: &[ - ("ఇ ఌ ఙ ఞ ణ ఱ ౯", BlueZones::TOP), - ("అ క చ ర ఽ ౨ ౬", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Tifinagh", - group: ScriptGroup::Default, - tag: Tag::new(b"Tfng"), - hint_top_to_bottom: false, - std_chars: "ⵔ", - blues: &[ - ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", BlueZones::TOP), - ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Thai", - group: ScriptGroup::Default, - tag: Tag::new(b"Thai"), - hint_top_to_bottom: false, - std_chars: "า ๅ ๐", - blues: &[ - ("บ เ แ อ ก า", BlueZones::TOP.union(BlueZones::X_HEIGHT)), - ("บ ป ษ ฯ อ ย ฮ", BlueZones::NONE), - ("ป ฝ ฟ", BlueZones::TOP), - ("โ ใ ไ", BlueZones::TOP), - ("ฎ ฏ ฤ ฦ", BlueZones::NONE), - ("ญ ฐ", BlueZones::NONE), - ("๐ ๑ ๓", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Vai", - group: ScriptGroup::Default, - tag: Tag::new(b"Vaii"), - hint_top_to_bottom: false, - std_chars: "ꘓ ꖜ ꖴ", - blues: &[ - ("ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ", BlueZones::TOP), - ("ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ", BlueZones::NONE), - ], - }, - ScriptClass { - name: "Limbu", - group: ScriptGroup::Indic, - tag: Tag::new(b"Limb"), - hint_top_to_bottom: false, - std_chars: "o", - blues: &[], - }, - ScriptClass { - name: "Oriya", - group: ScriptGroup::Indic, - tag: Tag::new(b"Orya"), - hint_top_to_bottom: false, - std_chars: "o", - blues: &[], - }, - ScriptClass { - name: "Syloti Nagri", - group: ScriptGroup::Indic, - tag: Tag::new(b"Sylo"), - hint_top_to_bottom: false, - std_chars: "o", - blues: &[], - }, - ScriptClass { - name: "Tibetan", - group: ScriptGroup::Indic, - tag: Tag::new(b"Tibt"), - hint_top_to_bottom: false, - std_chars: "o", - blues: &[], - }, - ScriptClass { - name: "CJKV ideographs", - group: ScriptGroup::Cjk, - tag: Tag::new(b"Hani"), - hint_top_to_bottom: false, - std_chars: "田 囗", - blues: &[ - ("他 们 你 來 們 到 和 地 对 對 就 席 我 时 時 會 来 為 能 舰 說 说 这 這 齊 | 军 同 已 愿 既 星 是 景 民 照 现 現 理 用 置 要 軍 那 配 里 開 雷 露 面 顾", BlueZones::TOP), - ("个 为 人 他 以 们 你 來 個 們 到 和 大 对 對 就 我 时 時 有 来 為 要 說 说 | 主 些 因 它 想 意 理 生 當 看 着 置 者 自 著 裡 过 还 进 進 過 道 還 里 面", BlueZones::NONE), - (" 些 们 你 來 們 到 和 地 她 将 將 就 年 得 情 最 样 樣 理 能 說 说 这 這 通 | 即 吗 吧 听 呢 品 响 嗎 师 師 收 断 斷 明 眼 間 间 际 陈 限 除 陳 随 際 隨", BlueZones::HORIZONTAL), - ("事 前 學 将 將 情 想 或 政 斯 新 样 樣 民 沒 没 然 特 现 現 球 第 經 谁 起 | 例 別 别 制 动 動 吗 嗎 增 指 明 朝 期 构 物 确 种 調 调 費 费 那 都 間 间", BlueZones::HORIZONTAL.union(BlueZones::RIGHT)), - ], - }, -]; - -#[allow(unused)]impl ScriptClass { - pub const ADLM: usize = 0; - pub const ARAB: usize = 1; - pub const ARMN: usize = 2; - pub const AVST: usize = 3; - pub const BAMU: usize = 4; - pub const BENG: usize = 5; - pub const BUHD: usize = 6; - pub const CAKM: usize = 7; - pub const CANS: usize = 8; - pub const CARI: usize = 9; - pub const CHER: usize = 10; - pub const COPT: usize = 11; - pub const CPRT: usize = 12; - pub const CYRL: usize = 13; - pub const DEVA: usize = 14; - pub const DSRT: usize = 15; - pub const ETHI: usize = 16; - pub const GEOR: usize = 17; - pub const GEOK: usize = 18; - pub const GLAG: usize = 19; - pub const GOTH: usize = 20; - pub const GREK: usize = 21; - pub const GUJR: usize = 22; - pub const GURU: usize = 23; - pub const HEBR: usize = 24; - pub const KALI: usize = 25; - pub const KHMR: usize = 26; - pub const KHMS: usize = 27; - pub const KNDA: usize = 28; - pub const LAOO: usize = 29; - pub const LATN: usize = 30; - pub const LATB: usize = 31; - pub const LATP: usize = 32; - pub const LISU: usize = 33; - pub const MLYM: usize = 34; - pub const MEDF: usize = 35; - pub const MONG: usize = 36; - pub const MYMR: usize = 37; - pub const NKOO: usize = 38; - pub const NONE: usize = 39; - pub const OLCK: usize = 40; - pub const ORKH: usize = 41; - pub const OSGE: usize = 42; - pub const OSMA: usize = 43; - pub const ROHG: usize = 44; - pub const SAUR: usize = 45; - pub const SHAW: usize = 46; - pub const SINH: usize = 47; - pub const SUND: usize = 48; - pub const TAML: usize = 49; - pub const TAVT: usize = 50; - pub const TELU: usize = 51; - pub const TFNG: usize = 52; - pub const THAI: usize = 53; - pub const VAII: usize = 54; - pub const LIMB: usize = 55; - pub const ORYA: usize = 56; - pub const SYLO: usize = 57; - pub const TIBT: usize = 58; - pub const HANI: usize = 59; -} - -#[rustfmt::skip] -pub(super) const STYLE_CLASSES: &[StyleClass] = &[ - StyleClass { name: "Adlam", index: 0, script: &SCRIPT_CLASSES[0], feature: None }, - StyleClass { name: "Arabic", index: 1, script: &SCRIPT_CLASSES[1], feature: None }, - StyleClass { name: "Armenian", index: 2, script: &SCRIPT_CLASSES[2], feature: None }, - StyleClass { name: "Avestan", index: 3, script: &SCRIPT_CLASSES[3], feature: None }, - StyleClass { name: "Bamum", index: 4, script: &SCRIPT_CLASSES[4], feature: None }, - StyleClass { name: "Bengali", index: 5, script: &SCRIPT_CLASSES[5], feature: None }, - StyleClass { name: "Buhid", index: 6, script: &SCRIPT_CLASSES[6], feature: None }, - StyleClass { name: "Chakma", index: 7, script: &SCRIPT_CLASSES[7], feature: None }, - StyleClass { name: "Canadian Syllabics", index: 8, script: &SCRIPT_CLASSES[8], feature: None }, - StyleClass { name: "Carian", index: 9, script: &SCRIPT_CLASSES[9], feature: None }, - StyleClass { name: "Cherokee", index: 10, script: &SCRIPT_CLASSES[10], feature: None }, - StyleClass { name: "Coptic", index: 11, script: &SCRIPT_CLASSES[11], feature: None }, - StyleClass { name: "Cypriot", index: 12, script: &SCRIPT_CLASSES[12], feature: None }, - StyleClass { name: "Cyrillic petite capitals from capitals", index: 13, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"c2cp")) }, - StyleClass { name: "Cyrillic small capitals from capitals", index: 14, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"c2sc")) }, - StyleClass { name: "Cyrillic ordinals", index: 15, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"ordn")) }, - StyleClass { name: "Cyrillic petite capitals", index: 16, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"pcap")) }, - StyleClass { name: "Cyrillic ruby", index: 17, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"ruby")) }, - StyleClass { name: "Cyrillic scientific inferiors", index: 18, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"sinf")) }, - StyleClass { name: "Cyrillic small capitals", index: 19, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"smcp")) }, - StyleClass { name: "Cyrillic subscript", index: 20, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"subs")) }, - StyleClass { name: "Cyrillic superscript", index: 21, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"sups")) }, - StyleClass { name: "Cyrillic titling", index: 22, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"titl")) }, - StyleClass { name: "Cyrillic", index: 23, script: &SCRIPT_CLASSES[13], feature: None }, - StyleClass { name: "Devanagari", index: 24, script: &SCRIPT_CLASSES[14], feature: None }, - StyleClass { name: "Deseret", index: 25, script: &SCRIPT_CLASSES[15], feature: None }, - StyleClass { name: "Ethiopic", index: 26, script: &SCRIPT_CLASSES[16], feature: None }, - StyleClass { name: "Georgian (Mkhedruli)", index: 27, script: &SCRIPT_CLASSES[17], feature: None }, - StyleClass { name: "Georgian (Khutsuri)", index: 28, script: &SCRIPT_CLASSES[18], feature: None }, - StyleClass { name: "Glagolitic", index: 29, script: &SCRIPT_CLASSES[19], feature: None }, - StyleClass { name: "Gothic", index: 30, script: &SCRIPT_CLASSES[20], feature: None }, - StyleClass { name: "Greek petite capitals from capitals", index: 31, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"c2cp")) }, - StyleClass { name: "Greek small capitals from capitals", index: 32, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"c2sc")) }, - StyleClass { name: "Greek ordinals", index: 33, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"ordn")) }, - StyleClass { name: "Greek petite capitals", index: 34, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"pcap")) }, - StyleClass { name: "Greek ruby", index: 35, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"ruby")) }, - StyleClass { name: "Greek scientific inferiors", index: 36, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"sinf")) }, - StyleClass { name: "Greek small capitals", index: 37, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"smcp")) }, - StyleClass { name: "Greek subscript", index: 38, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"subs")) }, - StyleClass { name: "Greek superscript", index: 39, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"sups")) }, - StyleClass { name: "Greek titling", index: 40, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"titl")) }, - StyleClass { name: "Greek", index: 41, script: &SCRIPT_CLASSES[21], feature: None }, - StyleClass { name: "Gujarati", index: 42, script: &SCRIPT_CLASSES[22], feature: None }, - StyleClass { name: "Gurmukhi", index: 43, script: &SCRIPT_CLASSES[23], feature: None }, - StyleClass { name: "Hebrew", index: 44, script: &SCRIPT_CLASSES[24], feature: None }, - StyleClass { name: "Kayah Li", index: 45, script: &SCRIPT_CLASSES[25], feature: None }, - StyleClass { name: "Khmer", index: 46, script: &SCRIPT_CLASSES[26], feature: None }, - StyleClass { name: "Khmer Symbols", index: 47, script: &SCRIPT_CLASSES[27], feature: None }, - StyleClass { name: "Kannada", index: 48, script: &SCRIPT_CLASSES[28], feature: None }, - StyleClass { name: "Lao", index: 49, script: &SCRIPT_CLASSES[29], feature: None }, - StyleClass { name: "Latin petite capitals from capitals", index: 50, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"c2cp")) }, - StyleClass { name: "Latin small capitals from capitals", index: 51, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"c2sc")) }, - StyleClass { name: "Latin ordinals", index: 52, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"ordn")) }, - StyleClass { name: "Latin petite capitals", index: 53, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"pcap")) }, - StyleClass { name: "Latin ruby", index: 54, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"ruby")) }, - StyleClass { name: "Latin scientific inferiors", index: 55, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"sinf")) }, - StyleClass { name: "Latin small capitals", index: 56, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"smcp")) }, - StyleClass { name: "Latin subscript", index: 57, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"subs")) }, - StyleClass { name: "Latin superscript", index: 58, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"sups")) }, - StyleClass { name: "Latin titling", index: 59, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"titl")) }, - StyleClass { name: "Latin", index: 60, script: &SCRIPT_CLASSES[30], feature: None }, - StyleClass { name: "Latin Subscript Fallback", index: 61, script: &SCRIPT_CLASSES[31], feature: None }, - StyleClass { name: "Latin Superscript Fallback", index: 62, script: &SCRIPT_CLASSES[32], feature: None }, - StyleClass { name: "Lisu", index: 63, script: &SCRIPT_CLASSES[33], feature: None }, - StyleClass { name: "Malayalam", index: 64, script: &SCRIPT_CLASSES[34], feature: None }, - StyleClass { name: "Medefaidrin", index: 65, script: &SCRIPT_CLASSES[35], feature: None }, - StyleClass { name: "Mongolian", index: 66, script: &SCRIPT_CLASSES[36], feature: None }, - StyleClass { name: "Myanmar", index: 67, script: &SCRIPT_CLASSES[37], feature: None }, - StyleClass { name: "N'Ko", index: 68, script: &SCRIPT_CLASSES[38], feature: None }, - StyleClass { name: "no script", index: 69, script: &SCRIPT_CLASSES[39], feature: None }, - StyleClass { name: "Ol Chiki", index: 70, script: &SCRIPT_CLASSES[40], feature: None }, - StyleClass { name: "Old Turkic", index: 71, script: &SCRIPT_CLASSES[41], feature: None }, - StyleClass { name: "Osage", index: 72, script: &SCRIPT_CLASSES[42], feature: None }, - StyleClass { name: "Osmanya", index: 73, script: &SCRIPT_CLASSES[43], feature: None }, - StyleClass { name: "Hanifi Rohingya", index: 74, script: &SCRIPT_CLASSES[44], feature: None }, - StyleClass { name: "Saurashtra", index: 75, script: &SCRIPT_CLASSES[45], feature: None }, - StyleClass { name: "Shavian", index: 76, script: &SCRIPT_CLASSES[46], feature: None }, - StyleClass { name: "Sinhala", index: 77, script: &SCRIPT_CLASSES[47], feature: None }, - StyleClass { name: "Sundanese", index: 78, script: &SCRIPT_CLASSES[48], feature: None }, - StyleClass { name: "Tamil", index: 79, script: &SCRIPT_CLASSES[49], feature: None }, - StyleClass { name: "Tai Viet", index: 80, script: &SCRIPT_CLASSES[50], feature: None }, - StyleClass { name: "Telugu", index: 81, script: &SCRIPT_CLASSES[51], feature: None }, - StyleClass { name: "Tifinagh", index: 82, script: &SCRIPT_CLASSES[52], feature: None }, - StyleClass { name: "Thai", index: 83, script: &SCRIPT_CLASSES[53], feature: None }, - StyleClass { name: "Vai", index: 84, script: &SCRIPT_CLASSES[54], feature: None }, - StyleClass { name: "Limbu", index: 85, script: &SCRIPT_CLASSES[55], feature: None }, - StyleClass { name: "Oriya", index: 86, script: &SCRIPT_CLASSES[56], feature: None }, - StyleClass { name: "Syloti Nagri", index: 87, script: &SCRIPT_CLASSES[57], feature: None }, - StyleClass { name: "Tibetan", index: 88, script: &SCRIPT_CLASSES[58], feature: None }, - StyleClass { name: "CJKV ideographs", index: 89, script: &SCRIPT_CLASSES[59], feature: None }, -]; - -#[allow(unused)]impl StyleClass { - pub const ADLM: usize = 0; - pub const ARAB: usize = 1; - pub const ARMN: usize = 2; - pub const AVST: usize = 3; - pub const BAMU: usize = 4; - pub const BENG: usize = 5; - pub const BUHD: usize = 6; - pub const CAKM: usize = 7; - pub const CANS: usize = 8; - pub const CARI: usize = 9; - pub const CHER: usize = 10; - pub const COPT: usize = 11; - pub const CPRT: usize = 12; - pub const CYRL_C2CP: usize = 13; - pub const CYRL_C2SC: usize = 14; - pub const CYRL_ORDN: usize = 15; - pub const CYRL_PCAP: usize = 16; - pub const CYRL_RUBY: usize = 17; - pub const CYRL_SINF: usize = 18; - pub const CYRL_SMCP: usize = 19; - pub const CYRL_SUBS: usize = 20; - pub const CYRL_SUPS: usize = 21; - pub const CYRL_TITL: usize = 22; - pub const CYRL: usize = 23; - pub const DEVA: usize = 24; - pub const DSRT: usize = 25; - pub const ETHI: usize = 26; - pub const GEOR: usize = 27; - pub const GEOK: usize = 28; - pub const GLAG: usize = 29; - pub const GOTH: usize = 30; - pub const GREK_C2CP: usize = 31; - pub const GREK_C2SC: usize = 32; - pub const GREK_ORDN: usize = 33; - pub const GREK_PCAP: usize = 34; - pub const GREK_RUBY: usize = 35; - pub const GREK_SINF: usize = 36; - pub const GREK_SMCP: usize = 37; - pub const GREK_SUBS: usize = 38; - pub const GREK_SUPS: usize = 39; - pub const GREK_TITL: usize = 40; - pub const GREK: usize = 41; - pub const GUJR: usize = 42; - pub const GURU: usize = 43; - pub const HEBR: usize = 44; - pub const KALI: usize = 45; - pub const KHMR: usize = 46; - pub const KHMS: usize = 47; - pub const KNDA: usize = 48; - pub const LAOO: usize = 49; - pub const LATN_C2CP: usize = 50; - pub const LATN_C2SC: usize = 51; - pub const LATN_ORDN: usize = 52; - pub const LATN_PCAP: usize = 53; - pub const LATN_RUBY: usize = 54; - pub const LATN_SINF: usize = 55; - pub const LATN_SMCP: usize = 56; - pub const LATN_SUBS: usize = 57; - pub const LATN_SUPS: usize = 58; - pub const LATN_TITL: usize = 59; - pub const LATN: usize = 60; - pub const LATB: usize = 61; - pub const LATP: usize = 62; - pub const LISU: usize = 63; - pub const MLYM: usize = 64; - pub const MEDF: usize = 65; - pub const MONG: usize = 66; - pub const MYMR: usize = 67; - pub const NKOO: usize = 68; - pub const NONE: usize = 69; - pub const OLCK: usize = 70; - pub const ORKH: usize = 71; - pub const OSGE: usize = 72; - pub const OSMA: usize = 73; - pub const ROHG: usize = 74; - pub const SAUR: usize = 75; - pub const SHAW: usize = 76; - pub const SINH: usize = 77; - pub const SUND: usize = 78; - pub const TAML: usize = 79; - pub const TAVT: usize = 80; - pub const TELU: usize = 81; - pub const TFNG: usize = 82; - pub const THAI: usize = 83; - pub const VAII: usize = 84; - pub const LIMB: usize = 85; - pub const ORYA: usize = 86; - pub const SYLO: usize = 87; - pub const TIBT: usize = 88; - pub const HANI: usize = 89; -} - -#[rustfmt::skip] -pub(super) const STYLE_RANGES: &[StyleRange] = &[ - base_range(32, 93, 60), - non_base_range(94, 96, 60), - base_range(97, 125, 60), - non_base_range(126, 126, 60), - base_range(127, 127, 60), - base_range(160, 167, 60), - non_base_range(168, 169, 60), - base_range(170, 170, 62), - base_range(171, 173, 60), - non_base_range(174, 176, 60), - base_range(177, 177, 60), - base_range(178, 179, 62), - non_base_range(180, 180, 60), - base_range(181, 183, 60), - non_base_range(184, 184, 60), - base_range(185, 186, 62), - base_range(187, 187, 60), - non_base_range(188, 190, 60), - base_range(191, 687, 60), - base_range(688, 696, 62), - non_base_range(697, 735, 60), - base_range(736, 740, 62), - non_base_range(741, 879, 60), - base_range(880, 889, 41), - non_base_range(890, 890, 41), - base_range(891, 899, 41), - non_base_range(900, 901, 41), - base_range(902, 1023, 41), - base_range(1024, 1154, 23), - non_base_range(1155, 1161, 23), - base_range(1162, 1327, 23), - base_range(1328, 1368, 2), - non_base_range(1369, 1375, 2), - base_range(1376, 1423, 2), - base_range(1424, 1424, 44), - non_base_range(1425, 1471, 44), - base_range(1472, 1472, 44), - non_base_range(1473, 1474, 44), - base_range(1475, 1475, 44), - non_base_range(1476, 1477, 44), - base_range(1478, 1478, 44), - non_base_range(1479, 1479, 44), - base_range(1480, 1535, 44), - non_base_range(1536, 1541, 1), - base_range(1542, 1551, 1), - non_base_range(1552, 1562, 1), - base_range(1563, 1610, 1), - non_base_range(1611, 1631, 1), - base_range(1632, 1647, 1), - non_base_range(1648, 1648, 1), - base_range(1649, 1749, 1), - non_base_range(1750, 1756, 1), - base_range(1757, 1758, 1), - non_base_range(1759, 1764, 1), - base_range(1765, 1766, 1), - non_base_range(1767, 1768, 1), - base_range(1769, 1769, 1), - non_base_range(1770, 1773, 1), - base_range(1774, 1791, 1), - base_range(1872, 2047, 1), - base_range(2208, 2258, 1), - non_base_range(2259, 2303, 1), - non_base_range(2304, 2306, 24), - base_range(2307, 2361, 24), - non_base_range(2362, 2362, 24), - base_range(2363, 2363, 24), - base_range(2365, 2368, 24), - non_base_range(2369, 2376, 24), - base_range(2377, 2380, 24), - non_base_range(2381, 2381, 24), - base_range(2382, 2384, 24), - non_base_range(2387, 2391, 24), - base_range(2392, 2401, 24), - non_base_range(2402, 2403, 24), - base_range(2406, 2431, 24), - base_range(2432, 2432, 5), - non_base_range(2433, 2433, 5), - base_range(2434, 2491, 5), - non_base_range(2492, 2492, 5), - base_range(2493, 2496, 5), - non_base_range(2497, 2500, 5), - base_range(2501, 2508, 5), - non_base_range(2509, 2509, 5), - base_range(2510, 2529, 5), - non_base_range(2530, 2531, 5), - base_range(2532, 2557, 5), - non_base_range(2558, 2558, 5), - base_range(2559, 2559, 5), - base_range(2560, 2560, 43), - non_base_range(2561, 2562, 43), - base_range(2563, 2619, 43), - non_base_range(2620, 2620, 43), - base_range(2621, 2624, 43), - non_base_range(2625, 2641, 43), - base_range(2642, 2671, 43), - non_base_range(2672, 2673, 43), - base_range(2674, 2676, 43), - non_base_range(2677, 2677, 43), - base_range(2678, 2687, 43), - base_range(2688, 2688, 42), - non_base_range(2689, 2690, 42), - base_range(2691, 2747, 42), - non_base_range(2748, 2748, 42), - base_range(2749, 2752, 42), - non_base_range(2753, 2760, 42), - base_range(2761, 2764, 42), - non_base_range(2765, 2765, 42), - base_range(2766, 2785, 42), - non_base_range(2786, 2787, 42), - base_range(2788, 2809, 42), - non_base_range(2810, 2815, 42), - base_range(2816, 2816, 86), - non_base_range(2817, 2818, 86), - base_range(2819, 2875, 86), - non_base_range(2876, 2876, 86), - base_range(2877, 2878, 86), - non_base_range(2879, 2879, 86), - base_range(2880, 2880, 86), - non_base_range(2881, 2884, 86), - base_range(2885, 2892, 86), - non_base_range(2893, 2902, 86), - base_range(2903, 2913, 86), - non_base_range(2914, 2915, 86), - base_range(2916, 2943, 86), - base_range(2944, 2945, 79), - non_base_range(2946, 2946, 79), - base_range(2947, 3007, 79), - non_base_range(3008, 3010, 79), - base_range(3011, 3020, 79), - non_base_range(3021, 3021, 79), - base_range(3022, 3071, 79), - non_base_range(3072, 3072, 81), - base_range(3073, 3075, 81), - non_base_range(3076, 3076, 81), - base_range(3077, 3133, 81), - non_base_range(3134, 3136, 81), - base_range(3137, 3141, 81), - non_base_range(3142, 3158, 81), - base_range(3159, 3169, 81), - non_base_range(3170, 3171, 81), - base_range(3172, 3199, 81), - base_range(3200, 3200, 48), - non_base_range(3201, 3201, 48), - base_range(3202, 3259, 48), - non_base_range(3260, 3260, 48), - base_range(3261, 3262, 48), - non_base_range(3263, 3263, 48), - base_range(3264, 3269, 48), - non_base_range(3270, 3270, 48), - base_range(3271, 3275, 48), - non_base_range(3276, 3277, 48), - base_range(3278, 3297, 48), - non_base_range(3298, 3299, 48), - base_range(3300, 3327, 48), - non_base_range(3328, 3329, 64), - base_range(3330, 3386, 64), - non_base_range(3387, 3388, 64), - base_range(3389, 3404, 64), - non_base_range(3405, 3406, 64), - base_range(3407, 3425, 64), - non_base_range(3426, 3427, 64), - base_range(3428, 3455, 64), - base_range(3456, 3529, 77), - non_base_range(3530, 3530, 77), - base_range(3531, 3537, 77), - non_base_range(3538, 3542, 77), - base_range(3543, 3583, 77), - base_range(3584, 3632, 83), - non_base_range(3633, 3633, 83), - base_range(3634, 3635, 83), - non_base_range(3636, 3642, 83), - base_range(3643, 3654, 83), - non_base_range(3655, 3662, 83), - base_range(3663, 3711, 83), - base_range(3712, 3760, 49), - non_base_range(3761, 3761, 49), - base_range(3762, 3763, 49), - non_base_range(3764, 3772, 49), - base_range(3773, 3783, 49), - non_base_range(3784, 3789, 49), - base_range(3790, 3839, 49), - base_range(3840, 3863, 88), - non_base_range(3864, 3865, 88), - base_range(3866, 3892, 88), - non_base_range(3893, 3893, 88), - base_range(3894, 3894, 88), - non_base_range(3895, 3895, 88), - base_range(3896, 3896, 88), - non_base_range(3897, 3897, 88), - base_range(3898, 3901, 88), - non_base_range(3902, 3903, 88), - base_range(3904, 3952, 88), - non_base_range(3953, 3966, 88), - base_range(3967, 3967, 88), - non_base_range(3968, 3972, 88), - base_range(3973, 3973, 88), - non_base_range(3974, 3975, 88), - base_range(3976, 3980, 88), - non_base_range(3981, 4028, 88), - base_range(4029, 4095, 88), - base_range(4096, 4140, 67), - non_base_range(4141, 4144, 67), - base_range(4145, 4145, 67), - non_base_range(4146, 4151, 67), - base_range(4152, 4153, 67), - non_base_range(4154, 4154, 67), - base_range(4155, 4156, 67), - non_base_range(4157, 4158, 67), - base_range(4159, 4183, 67), - non_base_range(4184, 4185, 67), - base_range(4186, 4189, 67), - non_base_range(4190, 4192, 67), - base_range(4193, 4208, 67), - non_base_range(4209, 4212, 67), - base_range(4213, 4225, 67), - non_base_range(4226, 4226, 67), - base_range(4227, 4228, 67), - non_base_range(4229, 4230, 67), - base_range(4231, 4236, 67), - non_base_range(4237, 4237, 67), - base_range(4238, 4255, 67), - base_range(4256, 4301, 28), - base_range(4304, 4351, 27), - base_range(4352, 4607, 89), - base_range(4608, 4956, 26), - non_base_range(4957, 4959, 26), - base_range(4960, 5023, 26), - base_range(5024, 5119, 10), - base_range(5120, 5759, 8), - base_range(5952, 5969, 6), - non_base_range(5970, 5971, 6), - base_range(5972, 5983, 6), - base_range(6016, 6070, 46), - non_base_range(6071, 6077, 46), - base_range(6078, 6085, 46), - non_base_range(6086, 6086, 46), - base_range(6087, 6088, 46), - non_base_range(6089, 6099, 46), - base_range(6100, 6108, 46), - non_base_range(6109, 6109, 46), - base_range(6110, 6143, 46), - base_range(6144, 6276, 66), - non_base_range(6277, 6278, 66), - base_range(6279, 6312, 66), - non_base_range(6313, 6313, 66), - base_range(6314, 6319, 66), - base_range(6320, 6399, 8), - base_range(6400, 6431, 85), - non_base_range(6432, 6434, 85), - base_range(6435, 6438, 85), - non_base_range(6439, 6452, 85), - base_range(6453, 6454, 85), - non_base_range(6455, 6459, 85), - base_range(6460, 6479, 85), - base_range(6624, 6655, 47), - non_base_range(6832, 6846, 60), - non_base_range(7040, 7042, 78), - base_range(7043, 7072, 78), - non_base_range(7073, 7085, 78), - base_range(7086, 7103, 78), - base_range(7248, 7295, 70), - base_range(7296, 7311, 23), - base_range(7312, 7359, 27), - base_range(7360, 7375, 78), - base_range(7424, 7467, 60), - base_range(7468, 7521, 62), - base_range(7522, 7530, 61), - base_range(7531, 7543, 60), - base_range(7544, 7544, 62), - base_range(7545, 7578, 60), - base_range(7579, 7615, 62), - non_base_range(7616, 7679, 60), - base_range(7680, 7935, 60), - base_range(7936, 8124, 41), - non_base_range(8125, 8129, 41), - base_range(8130, 8140, 41), - non_base_range(8141, 8143, 41), - base_range(8144, 8156, 41), - non_base_range(8157, 8159, 41), - base_range(8160, 8172, 41), - non_base_range(8173, 8175, 41), - base_range(8176, 8188, 41), - non_base_range(8189, 8190, 41), - base_range(8191, 8191, 41), - base_range(8192, 8214, 60), - non_base_range(8215, 8215, 60), - base_range(8216, 8253, 60), - non_base_range(8254, 8254, 60), - base_range(8255, 8303, 60), - base_range(8304, 8319, 62), - base_range(8320, 8348, 61), - base_range(8352, 8376, 60), - base_range(8377, 8377, 24), - base_range(8378, 8399, 60), - base_range(8528, 8591, 60), - base_range(11264, 11359, 29), - base_range(11360, 11387, 60), - base_range(11388, 11388, 61), - base_range(11389, 11389, 62), - base_range(11390, 11391, 60), - base_range(11392, 11502, 11), - non_base_range(11503, 11505, 11), - base_range(11506, 11519, 11), - base_range(11520, 11565, 28), - base_range(11568, 11647, 82), - base_range(11648, 11743, 26), - non_base_range(11744, 11775, 23), - base_range(11776, 11903, 60), - base_range(11904, 12255, 89), - base_range(12272, 12329, 89), - non_base_range(12330, 12335, 89), - base_range(12336, 12687, 89), - non_base_range(12688, 12703, 89), - base_range(12704, 12799, 89), - base_range(13056, 40959, 89), - base_range(42192, 42239, 63), - base_range(42240, 42559, 84), - base_range(42560, 42606, 23), - non_base_range(42607, 42623, 23), - base_range(42624, 42653, 23), - non_base_range(42654, 42655, 23), - base_range(42656, 42735, 4), - non_base_range(42736, 42737, 4), - base_range(42738, 42751, 4), - base_range(42784, 42863, 60), - base_range(42864, 42864, 62), - base_range(42865, 42887, 60), - non_base_range(42888, 42888, 60), - base_range(42889, 42999, 60), - base_range(43000, 43001, 62), - non_base_range(43002, 43002, 60), - base_range(43003, 43007, 60), - base_range(43008, 43009, 87), - non_base_range(43010, 43010, 87), - base_range(43011, 43013, 87), - non_base_range(43014, 43014, 87), - base_range(43015, 43018, 87), - non_base_range(43019, 43019, 87), - base_range(43020, 43044, 87), - non_base_range(43045, 43046, 87), - base_range(43047, 43055, 87), - non_base_range(43136, 43137, 75), - base_range(43138, 43187, 75), - non_base_range(43188, 43205, 75), - base_range(43206, 43231, 75), - non_base_range(43232, 43249, 24), - base_range(43250, 43262, 24), - non_base_range(43263, 43263, 24), - base_range(43264, 43301, 45), - non_base_range(43302, 43309, 45), - base_range(43310, 43311, 45), - base_range(43360, 43391, 89), - base_range(43488, 43492, 67), - non_base_range(43493, 43493, 67), - base_range(43494, 43519, 67), - base_range(43616, 43643, 67), - non_base_range(43644, 43644, 67), - base_range(43645, 43647, 67), - base_range(43648, 43695, 80), - non_base_range(43696, 43696, 80), - base_range(43697, 43697, 80), - non_base_range(43698, 43700, 80), - base_range(43701, 43702, 80), - non_base_range(43703, 43704, 80), - base_range(43705, 43709, 80), - non_base_range(43710, 43711, 80), - base_range(43712, 43712, 80), - non_base_range(43713, 43713, 80), - base_range(43714, 43743, 80), - base_range(43776, 43823, 26), - base_range(43824, 43867, 60), - base_range(43868, 43871, 62), - base_range(43872, 43887, 60), - base_range(43888, 43967, 10), - base_range(44032, 55295, 89), - base_range(63744, 64255, 89), - base_range(64256, 64262, 60), - base_range(64275, 64279, 2), - base_range(64285, 64285, 44), - non_base_range(64286, 64286, 44), - base_range(64287, 64335, 44), - base_range(64336, 64433, 1), - non_base_range(64434, 64449, 1), - base_range(64450, 65023, 1), - base_range(65040, 65055, 89), - base_range(65072, 65103, 89), - non_base_range(65136, 65136, 1), - base_range(65137, 65137, 1), - non_base_range(65138, 65138, 1), - base_range(65139, 65139, 1), - non_base_range(65140, 65140, 1), - base_range(65141, 65141, 1), - non_base_range(65142, 65142, 1), - base_range(65143, 65143, 1), - non_base_range(65144, 65144, 1), - base_range(65145, 65145, 1), - non_base_range(65146, 65146, 1), - base_range(65147, 65147, 1), - non_base_range(65148, 65148, 1), - base_range(65149, 65149, 1), - non_base_range(65150, 65150, 1), - base_range(65151, 65279, 1), - base_range(65280, 65519, 89), - base_range(66208, 66271, 9), - base_range(66352, 66383, 30), - base_range(66560, 66639, 25), - base_range(66640, 66687, 76), - base_range(66688, 66735, 73), - base_range(66736, 66815, 72), - base_range(67584, 67647, 12), - base_range(68352, 68408, 3), - non_base_range(68409, 68415, 3), - base_range(68608, 68687, 71), - base_range(68864, 68927, 74), - non_base_range(69888, 69890, 7), - base_range(69891, 69926, 7), - non_base_range(69927, 69940, 7), - base_range(69941, 69957, 7), - non_base_range(69958, 69958, 7), - base_range(69959, 69967, 7), - base_range(71264, 71295, 66), - base_range(93760, 93855, 65), - base_range(110592, 110895, 89), - base_range(119552, 119647, 89), - base_range(119808, 120831, 60), - non_base_range(122880, 122927, 29), - non_base_range(125184, 125258, 0), - base_range(125259, 125279, 0), - base_range(126464, 126719, 1), - base_range(131072, 173791, 89), - base_range(173824, 191471, 89), - base_range(194560, 195103, 89), -]; - diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/scripts/gen_autohint_styles.py chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/scripts/gen_autohint_styles.py --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/scripts/gen_autohint_styles.py 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/scripts/gen_autohint_styles.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1476 +0,0 @@ -# Generates Rust tables that define Unicode "script classes" for the purposes -# of autohinting. -# -# For performance, we want to link various pieces of data by index. For ease of -# modification and to avoid errors, we want to define those links symbolically -# by name. Thus, this script exists which converts symbolic references to -# indices when generating code. -# -# The bottom of this file contains the Rust generation code. - -# Based on FreeType autofit coverage: -# https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afcover.h -STYLE_FEATURES = [ - { - "name": "petite capitals from capitals", - "tag": "c2cp", - }, - { - "name": "small capitals from capitals", - "tag": "c2sc", - }, - { - "name": "ordinals", - "tag": "ordn", - }, - { - "name": "petite capitals", - "tag": "pcap", - }, - { - "name": "ruby", - "tag": "ruby", - }, - { - "name": "scientific inferiors", - "tag": "sinf", - }, - { - "name": "small capitals", - "tag": "smcp", - }, - { - "name": "subscript", - "tag": "subs", - }, - { - "name": "superscript", - "tag": "sups", - }, - { - "name": "titling", - "tag": "titl", - }, -] - -# Scripts that generate styles with the extended feature set above -# FreeType refers to these as "meta latin" -SCRIPTS_WITH_FEATURES = ["CYRL", "GREK", "LATN"] - -# In relation to FreeType, this combines the AF_ScriptClass, -# AF_Script_UniRangeRec and AF_BlueStringset. -# Script definitions: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afscript.h -# Unicode ranges: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afranges.c -# Blues: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afblue.h -SCRIPT_CLASSES = [ - { - "name": "Adlam", - "tag": "ADLM", - "hint_top_to_bottom": False, - "std_chars": "𞤌 𞤮", # 𞤌 𞤮 - "base_ranges": [ - (0x1E900, 0x1E95F), # Adlam - ], - "non_base_ranges": [ - (0x1D944, 0x1E94A), - ], - "blues": [ - ("𞤌 𞤅 𞤈 𞤏 𞤔 𞤚", "TOP"), - ("𞤂 𞤖", "0"), - ("𞤬 𞤮 𞤻 𞤼 𞤾", "TOP | X_HEIGHT"), - ("𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀", "0"), - ], - }, - { - "name": "Arabic", - "tag": "ARAB", - "hint_top_to_bottom": False, - "std_chars": "ل ح ـ", # ل ح ـ - "base_ranges": [ - (0x0600, 0x06FF), # Arabic - (0x0750, 0x07FF), # Arabic Supplement - (0x08A0, 0x08FF), # Arabic Extended-A - (0xFB50, 0xFDFF), # Arabic Presentation Forms-A - (0xFE70, 0xFEFF), # Arabic Presentation Forms-B - (0x1EE00, 0x1EEFF), # Arabic Mathematical Alphabetic Symbols - ], - "non_base_ranges": [ - (0x0600, 0x0605), - (0x0610, 0x061A), - (0x064B, 0x065F), - (0x0670, 0x0670), - (0x06D6, 0x06DC), - (0x06DF, 0x06E4), - (0x06E7, 0x06E8), - (0x06EA, 0x06ED), - (0x08D4, 0x08E1), - (0x08D3, 0x08FF), - (0xFBB2, 0xFBC1), - (0xFE70, 0xFE70), - (0xFE72, 0xFE72), - (0xFE74, 0xFE74), - (0xFE76, 0xFE76), - (0xFE78, 0xFE78), - (0xFE7A, 0xFE7A), - (0xFE7C, 0xFE7C), - (0xFE7E, 0xFE7E), - ], - "blues": [ - ("ا إ ل ك ط ظ", "TOP"), - ("ت ث ط ظ ك", "0"), - ("ـ", "NEUTRAL"), - ], - }, - { - "name": "Armenian", - "tag": "ARMN", - "hint_top_to_bottom": False, - "std_chars": "ս Ս", # ս Ս - "base_ranges": [ - (0x0530, 0x058F), # Armenian - (0xFB13, 0xFB17), # Alphab. Present. Forms (Armenian) - ], - "non_base_ranges": [ - (0x0559, 0x055F), - ], - "blues": [ - ("Ա Մ Ւ Ս Բ Գ Դ Օ", "TOP"), - ("Ւ Ո Դ Ճ Շ Ս Տ Օ", "0"), - ("ե է ի մ վ ֆ ճ", "TOP"), - ("ա յ ւ ս գ շ ր օ", "TOP | X_HEIGHT"), - ("հ ո ճ ա ե ծ ս օ", "0"), - ("բ ը ի լ ղ պ փ ց", "0"), - ], - }, - { - "name": "Avestan", - "tag": "AVST", - "hint_top_to_bottom": False, - "std_chars": "𐬚", # 𐬚 - "base_ranges": [ - (0x10B00, 0x10B3F), # Avestan - ], - "non_base_ranges": [ - (0x10B39, 0x10B3F), - ], - "blues": [ - ("𐬀 𐬁 𐬐 𐬛", "TOP"), - ("𐬀 𐬁", "0"), - ], - }, - { - "name": "Bamum", - "tag": "BAMU", - "hint_top_to_bottom": False, - "std_chars": "ꛁ ꛯ", # ꛁ ꛯ - "base_ranges": [ - (0xA6A0, 0xA6FF), # Bamum - # This is commented out in FreeType - # (0x16800, 0x16A3F), # Bamum Supplement - ], - "non_base_ranges": [ - (0xA6F0, 0xA6F1), - ], - "blues": [ - ("ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ", "TOP"), - ("ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲", "0"), - ], - }, - { - "name": "Bengali", - "tag": "BENG", - "hint_top_to_bottom": True, - "std_chars": "০ ৪", # ০ ৪ - "base_ranges": [ - (0x0980, 0x09FF), # Bengali - ], - "non_base_ranges": [ - (0x0981, 0x0981), - (0x09BC, 0x09BC), - (0x09C1, 0x09C4), - (0x09CD, 0x09CD), - (0x09E2, 0x09E3), - (0x09FE, 0x09FE), - ], - "blues": [ - ("ই ট ঠ ি ী ৈ ৗ", "TOP"), - ("ও এ ড ত ন ব ল ক", "TOP"), - ("অ ড ত ন ব ভ ল ক", "TOP | NEUTRAL | X_HEIGHT"), - ("অ ড ত ন ব ভ ল ক", "0"), - ], - }, - { - "name": "Buhid", - "tag": "BUHD", - "hint_top_to_bottom": False, - "std_chars": "ᝋ ᝏ", # ᝋ ᝏ - "base_ranges": [ - (0x1740, 0x175F), # Buhid - ], - "non_base_ranges": [ - (0x1752, 0x1753), - ], - "blues": [ - ("ᝐ ᝈ", "TOP"), - ("ᝅ ᝊ ᝎ", "TOP"), - ("ᝂ ᝃ ᝉ ᝌ", "TOP | X_HEIGHT"), - ("ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ", "0"), - ], - }, - { - "name": "Chakma", - "tag": "CAKM", - "hint_top_to_bottom": False, - "std_chars": "𑄤 𑄉 𑄛", # 𑄤 𑄉 𑄛 - "base_ranges": [ - (0x11100, 0x1114F), # Chakma - ], - "non_base_ranges": [ - (0x11100, 0x11102), - (0x11127, 0x11134), - (0x11146, 0x11146), - ], - "blues": [ - ("𑄃 𑄅 𑄉 𑄙 𑄗", "TOP"), - ("𑄅 𑄛 𑄝 𑄗 𑄓", "0"), - ("𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢", "0"), - ], - }, - { - "name": "Canadian Syllabics", - "tag": "CANS", - "hint_top_to_bottom": False, - "std_chars": "ᑌ ᓚ", # ᑌ ᓚ - "base_ranges": [ - (0x1400, 0x167F), # Unified Canadian Aboriginal Syllabics - (0x18B0, 0x18FF), # Unified Canadian Aboriginal Syllabics Extended - ], - "non_base_ranges": [ - ], - "blues": [ - ("ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ", "TOP"), - ("ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ", "0"), - ("ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ", "TOP | X_HEIGHT"), - ("ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ", "0"), - ("ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ", "TOP"), - ("ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ", "0"), - ], - }, - { - "name": "Carian", - "tag": "CARI", - "hint_top_to_bottom": False, - "std_chars": "𐊫 𐋉", # 𐊫 𐋉 - "base_ranges": [ - (0x102A0, 0x102DF), # Carian - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿", "TOP"), - ("𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉", "0"), - ], - }, - { - "name": "Cherokee", - "tag": "CHER", - "hint_top_to_bottom": False, - "std_chars": "Ꭴ Ꮕ ꮕ", # Ꭴ Ꮕ ꮕ - "base_ranges": [ - (0x13A0, 0x13FF), # Cherokee - (0xAB70, 0xABBF), # Cherokee Supplement - ], - "non_base_ranges": [ - ], - "blues": [ - ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", "TOP"), - ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", "0"), - ("ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ", "TOP"), - ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", "TOP | X_HEIGHT"), - ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", "0"), - ("ᏸ ꮐ ꭹ ꭻ", "0"), - ], - }, - { - "name": "Coptic", - "tag": "COPT", - "hint_top_to_bottom": False, - "std_chars": "Ⲟ ⲟ", # Ⲟ ⲟ - "base_ranges": [ - (0x2C80, 0x2CFF), # Coptic - ], - "non_base_ranges": [ - (0x2CEF, 0x2CF1), - ], - "blues": [ - ("Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ", "TOP"), - ("Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ", "0"), - ("ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ", "TOP | X_HEIGHT"), - ("ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ", "0"), - ], - }, - { - "name": "Cypriot", - "tag": "CPRT", - "hint_top_to_bottom": False, - "std_chars": "𐠅 𐠣", # 𐠅 𐠣 - "base_ranges": [ - (0x10800, 0x1083F), # Cypriot - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦", "TOP"), - ("𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐", "0"), - ("𐠈 𐠏 𐠖", "TOP"), - ("𐠈 𐠏 𐠖", "0"), - ], - }, - { - "name": "Cyrillic", - "tag": "CYRL", - "hint_top_to_bottom": False, - "std_chars": "о О", # о О - "base_ranges": [ - (0x0400, 0x04FF), # Cyrillic - (0x0500, 0x052F), # Cyrillic Supplement - (0x2DE0, 0x2DFF), # Cyrillic Extended-A - (0xA640, 0xA69F), # Cyrillic Extended-B - (0x1C80, 0x1C8F), # Cyrillic Extended-C - ], - "non_base_ranges": [ - (0x0483, 0x0489), - (0x2DE0, 0x2DFF), - (0xA66F, 0xA67F), - (0xA69E, 0xA69F), - ], - "blues": [ - ("Б В Е П З О С Э", "TOP"), - ("Б В Е Ш З О С Э", "0"), - ("х п н ш е з о с", "TOP | X_HEIGHT"), - ("х п н ш е з о с", "0"), - ("р у ф", "0"), - ], - }, - { - "name": "Devanagari", - "tag": "DEVA", - "hint_top_to_bottom": True, - "std_chars": "ठ व ट", # ठ व ट - "base_ranges": [ - (0x0900, 0x093B), # Devanagari - (0x093D, 0x0950), # ... continued - (0x0953, 0x0963), # ... continued - (0x0966, 0x097F), # ... continued - (0x20B9, 0x20B9), # (new) Rupee sign - (0xA8E0, 0xA8FF), # Devanagari Extended - ], - "non_base_ranges": [ - (0x0900, 0x0902), - (0x093A, 0x093A), - (0x0941, 0x0948), - (0x094D, 0x094D), - (0x0953, 0x0957), - (0x0962, 0x0963), - (0xA8E0, 0xA8F1), - (0xA8FF, 0xA8FF), - ], - "blues": [ - ("ई ऐ ओ औ ि ी ो ौ", "TOP"), - ("क म अ आ थ ध भ श", "TOP"), - ("क न म उ छ ट ठ ड", "TOP | NEUTRAL | X_HEIGHT"), - ("क न म उ छ ट ठ ड", "0"), - ("ु ृ", "0"), - ], - }, - { - "name": "Deseret", - "tag": "DSRT", - "hint_top_to_bottom": False, - "std_chars": "𐐄 𐐬", # 𐐄 𐐬 - "base_ranges": [ - (0x10400, 0x1044F), # Deseret - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐐂 𐐄 𐐋 𐐗 𐐑", "TOP"), - ("𐐀 𐐂 𐐄 𐐗 𐐛", "0"), - ("𐐪 𐐬 𐐳 𐐿 𐐹", "TOP | X_HEIGHT"), - ("𐐨 𐐪 𐐬 𐐿 𐑃", "0"), - ], - }, - { - "name": "Ethiopic", - "tag": "ETHI", - "hint_top_to_bottom": False, - "std_chars": "ዐ", # ዐ - "base_ranges": [ - (0x1200, 0x137F), # Ethiopic - (0x1380, 0x139F), # Ethiopic Supplement - (0x2D80, 0x2DDF), # Ethiopic Extended - (0xAB00, 0xAB2F), # Ethiopic Extended-A - ], - "non_base_ranges": [ - (0x135D, 0x135F), - ], - "blues": [ - ("ሀ ሃ ዘ ፐ ማ በ ዋ ዐ", "TOP"), - ("ለ ሐ በ ዘ ሀ ሪ ዐ ጨ", "0"), - ], - }, - { - "name": "Georgian (Mkhedruli)", - "tag": "GEOR", - "hint_top_to_bottom": False, - "std_chars": "ი ე ა Ჿ", # ი ე ა Ი - "base_ranges": [ - (0x10D0, 0x10FF), # Georgian (Mkhedruli) - (0x1C90, 0x1CBF), # Georgian Extended (Mtavruli) - ], - "non_base_ranges": [ - ], - "blues": [ - ("გ დ ე ვ თ ი ო ღ", "TOP | X_HEIGHT"), - ("ა ზ მ ს შ ძ ხ პ", "0"), - ("ს ხ ქ ზ მ შ ჩ წ", "TOP"), - ("ე ვ ჟ ტ უ ფ ქ ყ", "0"), - ("Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ", "TOP"), - ("Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ", "0"), - ], - }, - { - "name": "Georgian (Khutsuri)", - "tag": "GEOK", - "hint_top_to_bottom": False, - "std_chars": "Ⴖ Ⴑ ⴙ", # Ⴖ Ⴑ ⴙ - "base_ranges": [ - (0x10A0, 0x10CD), # Georgian (Asomtavruli) - (0x2D00, 0x2D2D), # Georgian Supplement (Nuskhuri) - ], - "non_base_ranges": [ - ], - "blues": [ - ("Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ", "TOP"), - ("Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ", "0"), - ("ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ", "TOP | X_HEIGHT"), - ("ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ", "0"), - ("ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ", "TOP"), - ("ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ", "0"), - ], - }, - { - "name": "Glagolitic", - "tag": "GLAG", - "hint_top_to_bottom": False, - "std_chars": "Ⱅ ⱅ", # Ⱅ ⱅ - "base_ranges": [ - (0x2C00, 0x2C5F), # Glagolitic - (0x1E000, 0x1E02F), # Glagolitic Supplement - ], - "non_base_ranges": [ - (0x1E000, 0x1E02F), - ], - "blues": [ - ("Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ", "TOP"), - ("Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ", "0"), - ("ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ", "TOP | X_HEIGHT"), - ("ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ", "0"), - ], - }, - { - "name": "Gothic", - "tag": "GOTH", - "hint_top_to_bottom": True, - "std_chars": "𐌴 𐌾 𐍃", # 𐌴 𐌾 𐍃 - "base_ranges": [ - (0x10330, 0x1034F), # Gothic - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾", "TOP"), - ("𐌶 𐌴 𐍃 𐍈", "0"), - ], - }, - { - "name": "Greek", - "tag": "GREK", - "hint_top_to_bottom": False, - "std_chars": "ο Ο", # ο Ο - "base_ranges": [ - (0x0370, 0x03FF), # Greek and Coptic - (0x1F00, 0x1FFF), # Greek Extended - ], - "non_base_ranges": [ - (0x037A, 0x037A), - (0x0384, 0x0385), - (0x1FBD, 0x1FC1), - (0x1FCD, 0x1FCF), - (0x1FDD, 0x1FDF), - (0x1FED, 0x1FEF), - (0x1FFD, 0x1FFE), - ], - "blues": [ - ("Γ Β Ε Ζ Θ Ο Ω", "TOP"), - ("Β Δ Ζ Ξ Θ Ο", "0"), - ("β θ δ ζ λ ξ", "TOP"), - ("α ε ι ο π σ τ ω", "TOP | X_HEIGHT"), - ("α ε ι ο π σ τ ω", "0"), - ("β γ η μ ρ φ χ ψ", "0"), - ], - }, - { - "name": "Gujarati", - "tag": "GUJR", - "hint_top_to_bottom": False, - "std_chars": "ટ ૦", # ટ ૦ - "base_ranges": [ - (0x0A80, 0x0AFF), # Gujarati - ], - "non_base_ranges": [ - (0x0A81, 0x0A82), - (0x0ABC, 0x0ABC), - (0x0AC1, 0x0AC8), - (0x0ACD, 0x0ACD), - (0x0AE2, 0x0AE3), - (0x0AFA, 0x0AFF), - ], - "blues": [ - ("ત ન ઋ ઌ છ ટ ર ૦", "TOP | X_HEIGHT"), - ("ખ ગ ઘ ઞ ઇ ઈ ઠ જ", "0"), - ("ઈ ઊ િ ી લી શ્ચિ જિ સી", "TOP"), - ("ુ ૃ ૄ ખુ છૃ છૄ", "0"), - ("૦ ૧ ૨ ૩ ૭", "TOP"), - ], - }, - { - "name": "Gurmukhi", - "tag": "GURU", - "hint_top_to_bottom": True, - "std_chars": "ਠ ਰ ੦", # ਠ ਰ ੦ - "base_ranges": [ - (0x0A00, 0x0A7F), # Gurmukhi - ], - "non_base_ranges": [ - (0x0A01, 0x0A02), - (0x0A3C, 0x0A3C), - (0x0A41, 0x0A51), - (0x0A70, 0x0A71), - (0x0A75, 0x0A75), - ], - "blues": [ - ("ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ", "TOP"), - ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", "TOP"), - ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", "TOP | NEUTRAL | X_HEIGHT"), - ("ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ", "0"), - ("੦ ੧ ੨ ੩ ੭", "TOP"), - ], - }, - { - "name": "Hebrew", - "tag": "HEBR", - "hint_top_to_bottom": False, - "std_chars": "ם", # ם - "base_ranges": [ - (0x0590, 0x05FF), # Hebrew - (0xFB1D, 0xFB4F), # Alphab. Present. Forms (Hebrew) - ], - "non_base_ranges": [ - (0x0591, 0x05BF), - (0x05C1, 0x05C2), - (0x05C4, 0x05C5), - (0x05C7, 0x05C7), - (0xFB1E, 0xFB1E), - ], - "blues": [ - ("ב ד ה ח ך כ ם ס", "TOP | LONG"), - ("ב ט כ ם ס צ", "0"), - ("ק ך ן ף ץ", "0"), - ], - }, - { - "name": "Kayah Li", - "tag": "KALI", - "hint_top_to_bottom": False, - "std_chars": "ꤍ ꤀", # ꤍ ꤀ - "base_ranges": [ - (0xA900, 0xA92F), # Kayah Li - ], - "non_base_ranges": [ - (0xA926, 0xA92D), - ], - "blues": [ - ("꤅ ꤏ ꤁ ꤋ ꤀ ꤍ", "TOP | X_HEIGHT"), - ("꤈ ꤘ ꤀ ꤍ ꤢ", "0"), - ("ꤖ ꤡ", "TOP"), - ("ꤑ ꤜ ꤞ", "0"), - ("ꤑ꤬ ꤜ꤭ ꤔ꤬", "0"), - ], - }, - { - "name": "Khmer", - "tag": "KHMR", - "hint_top_to_bottom": False, - "std_chars": "០", # ០ - "base_ranges": [ - (0x1780, 0x17FF), # Khmer - ], - "non_base_ranges": [ - (0x17B7, 0x17BD), - (0x17C6, 0x17C6), - (0x17C9, 0x17D3), - (0x17DD, 0x17DD), - ], - "blues": [ - ("ខ ទ ន ឧ ឩ ា", "TOP | X_HEIGHT"), - ("ក្ក ក្ខ ក្គ ក្ថ", "SUB_TOP"), - ("ខ ឃ ច ឋ ប ម យ ឲ", "0"), - ("ត្រ រៀ ឲ្យ អឿ", "0"), - ("ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ", "0"), - ], - }, - { - "name": "Khmer Symbols", - "tag": "KHMS", - "hint_top_to_bottom": False, - "std_chars": "᧡ ᧪", # ᧡ ᧪ - "base_ranges": [ - (0x19E0, 0x19FF), # Khmer Symbols - ], - "non_base_ranges": [ - ], - "blues": [ - ("᧠ ᧡", "TOP | X_HEIGHT"), - ("᧶ ᧹", "0"), - ], - }, - { - "name": "Kannada", - "tag": "KNDA", - "hint_top_to_bottom": False, - "std_chars": "೦ ಬ", # ೦ ಬ - "base_ranges": [ - (0x0C80, 0x0CFF), # Kannada - ], - "non_base_ranges": [ - (0x0C81, 0x0C81), - (0x0CBC, 0x0CBC), - (0x0CBF, 0x0CBF), - (0x0CC6, 0x0CC6), - (0x0CCC, 0x0CCD), - (0x0CE2, 0x0CE3), - ], - "blues": [ - ("ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ", "TOP"), - ("ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭", "0"), - ], - }, - { - "name": "Lao", - "tag": "LAOO", - "hint_top_to_bottom": False, - "std_chars": "໐", # ໐ - "base_ranges": [ - (0x0E80, 0x0EFF), # Lao - ], - "non_base_ranges": [ - (0x0EB1, 0x0EB1), - (0x0EB4, 0x0EBC), - (0x0EC8, 0x0ECD), - ], - "blues": [ - ("າ ດ ອ ມ ລ ວ ຣ ງ", "TOP | X_HEIGHT"), - ("າ ອ ບ ຍ ຣ ຮ ວ ຢ", "0"), - ("ປ ຢ ຟ ຝ", "TOP"), - ("ໂ ໄ ໃ", "TOP"), - ("ງ ຊ ຖ ຽ ໆ ຯ", "0"), - ], - }, - { - "name": "Latin", - "tag": "LATN", - "hint_top_to_bottom": False, - "std_chars": "o O 0", - "base_ranges": [ - (0x0020, 0x007F), # Basic Latin (no control chars) - (0x00A0, 0x00A9), # Latin-1 Supplement (no control chars) - (0x00AB, 0x00B1), # ... continued - (0x00B4, 0x00B8), # ... continued - (0x00BB, 0x00FF), # ... continued - (0x0100, 0x017F), # Latin Extended-A - (0x0180, 0x024F), # Latin Extended-B - (0x0250, 0x02AF), # IPA Extensions - (0x02B9, 0x02DF), # Spacing Modifier Letters - (0x02E5, 0x02FF), # ... continued - (0x0300, 0x036F), # Combining Diacritical Marks - (0x1AB0, 0x1ABE), # Combining Diacritical Marks Extended - (0x1D00, 0x1D2B), # Phonetic Extensions - (0x1D6B, 0x1D77), # ... continued - (0x1D79, 0x1D7F), # ... continued - (0x1D80, 0x1D9A), # Phonetic Extensions Supplement - (0x1DC0, 0x1DFF), # Combining Diacritical Marks Supplement - (0x1E00, 0x1EFF), # Latin Extended Additional - (0x2000, 0x206F), # General Punctuation - (0x20A0, 0x20B8), # Currency Symbols ... - (0x20BA, 0x20CF), # ... except new Rupee sign - (0x2150, 0x218F), # Number Forms - (0x2C60, 0x2C7B), # Latin Extended-C - (0x2C7E, 0x2C7F), # ... continued - (0x2E00, 0x2E7F), # Supplemental Punctuation - (0xA720, 0xA76F), # Latin Extended-D - (0xA771, 0xA7F7), # ... continued - (0xA7FA, 0xA7FF), # ... continued - (0xAB30, 0xAB5B), # Latin Extended-E - (0xAB60, 0xAB6F), # ... continued - (0xFB00, 0xFB06), # Alphab. Present. Forms (Latin Ligs) - (0x1D400, 0x1D7FF), # Mathematical Alphanumeric Symbols - ], - "non_base_ranges": [ - (0x005E, 0x0060), - (0x007E, 0x007E), - (0x00A8, 0x00A9), - (0x00AE, 0x00B0), - (0x00B4, 0x00B4), - (0x00B8, 0x00B8), - (0x00BC, 0x00BE), - (0x02B9, 0x02DF), - (0x02E5, 0x02FF), - (0x0300, 0x036F), - (0x1AB0, 0x1ABE), - (0x1DC0, 0x1DFF), - (0x2017, 0x2017), - (0x203E, 0x203E), - (0xA788, 0xA788), - (0xA7F8, 0xA7FA), - ], - "blues": [ - ("T H E Z O C Q S", "TOP"), - ("H E Z L O C U S", "0"), - ("f i j k d b h", "TOP"), - ("u v x z o e s c", "TOP | X_HEIGHT"), - ("n r x z o e s c", "0"), - ("p q g j y", "0"), - ], - }, - { - "name": "Latin Subscript Fallback", - "tag": "LATB", - "hint_top_to_bottom": False, - "std_chars": "ₒ ₀", # ₒ ₀ - "base_ranges": [ - (0x1D62, 0x1D6A), # some small subscript letters - (0x2080, 0x209C), # subscript digits and letters - (0x2C7C, 0x2C7C), # latin subscript small letter j - ], - "non_base_ranges": [ - ], - "blues": [ - ("₀ ₃ ₅ ₇ ₈", "TOP"), - ("₀ ₁ ₂ ₃ ₈", "0"), - ("ᵢ ⱼ ₕ ₖ ₗ", "TOP"), - ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", "TOP | X_HEIGHT"), - ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", "0"), - ("ᵦ ᵧ ᵨ ᵩ ₚ", "0"), - ], - }, - { - "name": "Latin Superscript Fallback", - "tag": "LATP", - "hint_top_to_bottom": False, - "std_chars": "ᵒ ᴼ ⁰", # ᵒ ᴼ ⁰ - "base_ranges": [ - (0x00AA, 0x00AA), # feminine ordinal indicator - (0x00B2, 0x00B3), # superscript two and three - (0x00B9, 0x00BA), # superscript one, masc. ord. indic. - (0x02B0, 0x02B8), # some latin superscript mod. letters - (0x02E0, 0x02E4), # some IPA modifier letters - (0x1D2C, 0x1D61), # latin superscript modifier letters - (0x1D78, 0x1D78), # modifier letter cyrillic en - (0x1D9B, 0x1DBF), # more modifier letters - (0x2070, 0x207F), # superscript digits and letters - (0x2C7D, 0x2C7D), # modifier letter capital v - (0xA770, 0xA770), # modifier letter us - (0xA7F8, 0xA7F9), # more modifier letters - (0xAB5C, 0xAB5F), # more modifier letters - ], - "non_base_ranges": [ - ], - "blues": [ - ("⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ", "TOP"), - ("⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ", "0"), - ("ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ", "TOP"), - ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", "TOP | X_HEIGHT"), - ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", "0"), - ("ᵖ ʸ ᵍ", "0"), - ], - }, - { - "name": "Lisu", - "tag": "LISU", - "hint_top_to_bottom": False, - "std_chars": "ꓳ", # ꓳ - "base_ranges": [ - (0xA4D0, 0xA4FF), # Lisu - ], - "non_base_ranges": [ - ], - "blues": [ - ("ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ", "TOP"), - ("ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ", "0"), - ], - }, - { - "name": "Malayalam", - "tag": "MLYM", - "hint_top_to_bottom": False, - "std_chars": "ഠ റ", # ഠ റ - "base_ranges": [ - (0x0D00, 0x0D7F), # Malayalam - ], - "non_base_ranges": [ - (0x0D00, 0x0D01), - (0x0D3B, 0x0D3C), - (0x0D4D, 0x0D4E), - (0x0D62, 0x0D63), - ], - "blues": [ - ("ഒ ട ഠ റ ച പ ച്ച പ്പ", "TOP"), - ("ട ഠ ധ ശ ഘ ച ഥ ല", "0"), - ], - }, - { - "name": "Medefaidrin", - "tag": "MEDF", - "hint_top_to_bottom": False, - "std_chars": "𖹡 𖹛 𖹯", # 𖹡 𖹛 𖹯 - "base_ranges": [ - (0x16E40, 0x16E9F), # Medefaidrin - ], - "non_base_ranges": [ - ], - "blues": [ - ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟", "TOP"), - ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓", "0"), - ("𖹤 𖹬 𖹧 𖹴 𖹶 𖹾", "TOP"), - ("𖹠 𖹡 𖹢 𖹹 𖹳 𖹮", "TOP | X_HEIGHT"), - ("𖹠 𖹡 𖹢 𖹳 𖹭 𖹽", "0"), - ("𖹥 𖹨 𖹩", "0"), - ("𖺀 𖺅 𖺈 𖺄 𖺍", "TOP"), - ], - }, - { - "name": "Mongolian", - "tag": "MONG", - "hint_top_to_bottom": True, - "std_chars": "ᡂ ᠪ", # ᡂ ᠪ - "base_ranges": [ - (0x1800, 0x18AF), # Mongolian - (0x11660, 0x1167F), # Mongolian Supplement - ], - "non_base_ranges": [ - (0x1885, 0x1886), - (0x18A9, 0x18A9), - ], - "blues": [ - ("ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍", "TOP"), - ("ᡃ", "0"), - ], - }, - { - "name": "Myanmar", - "tag": "MYMR", - "hint_top_to_bottom": False, - "std_chars": "ဝ င ဂ", # ဝ င ဂ - "base_ranges": [ - (0x1000, 0x109F), # Myanmar - (0xA9E0, 0xA9FF), # Myanmar Extended-B - (0xAA60, 0xAA7F), # Myanmar Extended-A - ], - "non_base_ranges": [ - (0x102D, 0x1030), - (0x1032, 0x1037), - (0x103A, 0x103A), - (0x103D, 0x103E), - (0x1058, 0x1059), - (0x105E, 0x1060), - (0x1071, 0x1074), - (0x1082, 0x1082), - (0x1085, 0x1086), - (0x108D, 0x108D), - (0xA9E5, 0xA9E5), - (0xAA7C, 0xAA7C), - ], - "blues": [ - ("ခ ဂ င ဒ ဝ ၥ ၊ ။", "TOP | X_HEIGHT"), - ("င ဎ ဒ ပ ဗ ဝ ၊ ။", "0"), - ("ဩ ြ ၍ ၏ ၆ ါ ိ", "TOP"), - ("ဉ ည ဥ ဩ ဨ ၂ ၅ ၉", "0"), - ], - }, - { - "name": "N'Ko", - "tag": "NKOO", - "hint_top_to_bottom": False, - "std_chars": "ߋ ߀", # ߋ ߀ - "base_ranges": [ - (0x07C0, 0x07FF), # N'Ko - ], - "non_base_ranges": [ - (0x07EB, 0x07F5), - (0x07FD, 0x07FD), - ], - "blues": [ - ("ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ", "TOP"), - ("߀ ߘ ߡ ߠ ߥ", "0"), - ("ߏ ߛ ߋ", "TOP | X_HEIGHT"), - ("ߎ ߏ ߛ ߋ", "0"), - ], - }, - { - "name": "no script", - "tag": "NONE", - "hint_top_to_bottom": False, - "std_chars": "", - "base_ranges": [ - ], - "non_base_ranges": [ - ], - "blues": [ - ], - }, - { - "name": "Ol Chiki", - "tag": "OLCK", - "hint_top_to_bottom": False, - "std_chars": "ᱛ", # ᱛ - "base_ranges": [ - (0x1C50, 0x1C7F), # Ol Chiki - ], - "non_base_ranges": [ - ], - "blues": [ - ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", "TOP"), - ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", "0"), - ], - }, - { - "name": "Old Turkic", - "tag": "ORKH", - "hint_top_to_bottom": False, - "std_chars": "𐰗", # 𐰗 - "base_ranges": [ - (0x10C00, 0x10C4F), # Old Turkic - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐰗 𐰘 𐰧", "TOP"), - ("𐰉 𐰗 𐰦 𐰧", "0"), - ], - }, - { - "name": "Osage", - "tag": "OSGE", - "hint_top_to_bottom": False, - "std_chars": "𐓂 𐓪", # 𐓂 𐓪 - "base_ranges": [ - (0x104B0, 0x104FF), # Osage - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆", "TOP"), - ("𐒰 𐓍 𐓂 𐒿 𐓎 𐒹", "0"), - ("𐒼 𐒽 𐒾", "0"), - ("𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮", "TOP | X_HEIGHT"), - ("𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶", "0"), - ("𐓤 𐓦 𐓸 𐓹 𐓛", "TOP"), - ("𐓤 𐓥 𐓦", "0"), - ], - }, - { - "name": "Osmanya", - "tag": "OSMA", - "hint_top_to_bottom": False, - "std_chars": "𐒆 𐒠", # 𐒆 𐒠 - "base_ranges": [ - (0x10480, 0x104AF), # Osmanya - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣", "TOP"), - ("𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩", "0"), - ], - }, - { - "name": "Hanifi Rohingya", - "tag": "ROHG", - "hint_top_to_bottom": False, - "std_chars": "𐴰", # 𐴰 - "base_ranges": [ - (0x10D00, 0x10D3F), # Hanifi Rohingya - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐴃 𐴀 𐴆 𐴖 𐴕", "TOP"), - ("𐴔 𐴖 𐴕 𐴑 𐴐", "0"), - ("ـ", "NEUTRAL"), - ], - }, - { - "name": "Saurashtra", - "tag": "SAUR", - "hint_top_to_bottom": False, - "std_chars": "ꢝ ꣐", # ꢝ ꣐ - "base_ranges": [ - (0xA880, 0xA8DF), # Saurashtra - ], - "non_base_ranges": [ - (0xA880, 0xA881), - (0xA8B4, 0xA8C5), - ], - "blues": [ - ("ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ", "TOP"), - ("ꢂ ꢨ ꢺ ꢤ ꢎ", "0"), - ], - }, - { - "name": "Shavian", - "tag": "SHAW", - "hint_top_to_bottom": False, - "std_chars": "𐑴", # 𐑴 - "base_ranges": [ - (0x10450, 0x1047F), # Shavian - ], - "non_base_ranges": [ - ], - "blues": [ - ("𐑕 𐑙", "TOP"), - ("𐑔 𐑖 𐑗 𐑹 𐑻", "0"), - ("𐑟 𐑣", "0"), - ("𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼", "TOP | X_HEIGHT"), - ("𐑴 𐑻 𐑹", "0"), - ], - }, - { - "name": "Sinhala", - "tag": "SINH", - "hint_top_to_bottom": False, - "std_chars": "ට", # ට - "base_ranges": [ - (0x0D80, 0x0DFF), # Sinhala - ], - "non_base_ranges": [ - (0x0DCA, 0x0DCA), - (0x0DD2, 0x0DD6), - ], - "blues": [ - ("ඉ ක ඝ ඳ ප ය ල ෆ", "TOP"), - ("එ ඔ ඝ ජ ට ථ ධ ර", "0"), - ("ද ඳ උ ල තූ තු බු දු", "0"), - ], - }, - { - "name": "Sundanese", - "tag": "SUND", - "hint_top_to_bottom": False, - "std_chars": "᮰", # ᮰ - "base_ranges": [ - (0x1B80, 0x1BBF), # Sundanese - (0x1CC0, 0x1CCF), # Sundanese Supplement - ], - "non_base_ranges": [ - (0x1B80, 0x1B82), - (0x1BA1, 0x1BAD), - ], - "blues": [ - ("ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ", "TOP"), - ("ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ", "0"), - ("ᮼ ᳄", "0"), - ], - }, - { - "name": "Tamil", - "tag": "TAML", - "hint_top_to_bottom": False, - "std_chars": "௦", # ௦ - "base_ranges": [ - (0x0B80, 0x0BFF), # Tamil - ], - "non_base_ranges": [ - (0x0B82, 0x0B82), - (0x0BC0, 0x0BC2), - (0x0BCD, 0x0BCD), - ], - "blues": [ - ("உ ஒ ஓ ற ஈ க ங ச", "TOP"), - ("க ச ல ஶ உ ங ட ப", "0"), - ], - }, - { - "name": "Tai Viet", - "tag": "TAVT", - "hint_top_to_bottom": False, - "std_chars": "ꪒ ꪫ", # ꪒ ꪫ - "base_ranges": [ - (0xAA80, 0xAADF), # Tai Viet - ], - "non_base_ranges": [ - (0xAAB0, 0xAAB0), - (0xAAB2, 0xAAB4), - (0xAAB7, 0xAAB8), - (0xAABE, 0xAABF), - (0xAAC1, 0xAAC1), - ], - "blues": [ - ("ꪆ ꪔ ꪒ ꪖ ꪫ", "TOP"), - ("ꪉ ꪫ ꪮ", "0"), - ], - }, - { - "name": "Telugu", - "tag": "TELU", - "hint_top_to_bottom": False, - "std_chars": "౦ ౧", # ౦ ౧ - "base_ranges": [ - (0x0C00, 0x0C7F), # Telugu - ], - "non_base_ranges": [ - (0x0C00, 0x0C00), - (0x0C04, 0x0C04), - (0x0C3E, 0x0C40), - (0x0C46, 0x0C56), - (0x0C62, 0x0C63), - ], - "blues": [ - ("ఇ ఌ ఙ ఞ ణ ఱ ౯", "TOP"), - ("అ క చ ర ఽ ౨ ౬", "0"), - ], - }, - { - "name": "Tifinagh", - "tag": "TFNG", - "hint_top_to_bottom": False, - "std_chars": "ⵔ", # ⵔ - "base_ranges": [ - (0x2D30, 0x2D7F), # Tifinagh - ], - "non_base_ranges": [ - ], - "blues": [ - ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", "TOP"), - ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", "0"), - ], - }, - { - "name": "Thai", - "tag": "THAI", - "hint_top_to_bottom": False, - "std_chars": "า ๅ ๐", # า ๅ ๐ - "base_ranges": [ - (0x0E00, 0x0E7F), # Thai - ], - "non_base_ranges": [ - (0x0E31, 0x0E31), - (0x0E34, 0x0E3A), - (0x0E47, 0x0E4E), - ], - "blues": [ - ("บ เ แ อ ก า", "TOP | X_HEIGHT"), - ("บ ป ษ ฯ อ ย ฮ", "0"), - ("ป ฝ ฟ", "TOP"), - ("โ ใ ไ", "TOP"), - ("ฎ ฏ ฤ ฦ", "0"), - ("ญ ฐ", "0"), - ("๐ ๑ ๓", "0"), - ], - }, - { - "name": "Vai", - "tag": "VAII", - "hint_top_to_bottom": False, - "std_chars": "ꘓ ꖜ ꖴ", # ꘓ ꖜ ꖴ - "base_ranges": [ - (0xA500, 0xA63F), # Vai - ], - "non_base_ranges": [ - ], - "blues": [ - ("ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ", "TOP"), - ("ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ", "0"), - ], - }, - { - "name": "Limbu", - "tag": "LIMB", - "hint_top_to_bottom": False, - "std_chars": "o", # XXX - "base_ranges": [ - (0x1900, 0x194F), # Limbu - ], - "non_base_ranges": [ - (0x1920, 0x1922), - (0x1927, 0x1934), - (0x1937, 0x193B), - ], - "blues": [], - }, - { - "name": "Oriya", - "tag": "ORYA", - "hint_top_to_bottom": False, - "std_chars": "o", # XXX - "base_ranges": [ - (0x0B00, 0x0B7F), # Oriya - ], - "non_base_ranges": [ - (0x0B01, 0x0B02), - (0x0B3C, 0x0B3C), - (0x0B3F, 0x0B3F), - (0x0B41, 0x0B44), - (0x0B4D, 0x0B56), - (0x0B62, 0x0B63), - ], - "blues": [], - }, - { - "name": "Syloti Nagri", - "tag": "SYLO", - "hint_top_to_bottom": False, - "std_chars": "o", # XXX - "base_ranges": [ - (0xA800, 0xA82F), # Syloti Nagri - ], - "non_base_ranges": [ - (0xA802, 0xA802), - (0xA806, 0xA806), - (0xA80B, 0xA80B), - (0xA825, 0xA826), - ], - "blues": [], - }, - { - "name": "Tibetan", - "tag": "TIBT", - "hint_top_to_bottom": False, - "std_chars": "o", # XXX - "base_ranges": [ - (0x0F00, 0x0FFF), # Tibetan - ], - "non_base_ranges": [ - (0x0F18, 0x0F19), - (0x0F35, 0x0F35), - (0x0F37, 0x0F37), - (0x0F39, 0x0F39), - (0x0F3E, 0x0F3F), - (0x0F71, 0x0F7E), - (0x0F80, 0x0F84), - (0x0F86, 0x0F87), - (0x0F8D, 0x0FBC), - ], - "blues": [], - }, - { - "name": "CJKV ideographs", - "tag": "HANI", - "hint_top_to_bottom": False, - "std_chars": "田 囗", # 田 囗 - "base_ranges": [ - (0x1100, 0x11FF), # Hangul Jamo - (0x2E80, 0x2EFF), # CJK Radicals Supplement - (0x2F00, 0x2FDF), # Kangxi Radicals - (0x2FF0, 0x2FFF), # Ideographic Description Characters - (0x3000, 0x303F), # CJK Symbols and Punctuation - (0x3040, 0x309F), # Hiragana - (0x30A0, 0x30FF), # Katakana - (0x3100, 0x312F), # Bopomofo - (0x3130, 0x318F), # Hangul Compatibility Jamo - (0x3190, 0x319F), # Kanbun - (0x31A0, 0x31BF), # Bopomofo Extended - (0x31C0, 0x31EF), # CJK Strokes - (0x31F0, 0x31FF), # Katakana Phonetic Extensions - (0x3300, 0x33FF), # CJK Compatibility - (0x3400, 0x4DBF), # CJK Unified Ideographs Extension A - (0x4DC0, 0x4DFF), # Yijing Hexagram Symbols - (0x4E00, 0x9FFF), # CJK Unified Ideographs - (0xA960, 0xA97F), # Hangul Jamo Extended-A - (0xAC00, 0xD7AF), # Hangul Syllables - (0xD7B0, 0xD7FF), # Hangul Jamo Extended-B - (0xF900, 0xFAFF), # CJK Compatibility Ideographs - (0xFE10, 0xFE1F), # Vertical forms - (0xFE30, 0xFE4F), # CJK Compatibility Forms - (0xFF00, 0xFFEF), # Halfwidth and Fullwidth Forms - (0x1B000, 0x1B0FF), # Kana Supplement - (0x1B100, 0x1B12F), # Kana Extended-A - (0x1D300, 0x1D35F), # Tai Xuan Hing Symbols - (0x20000, 0x2A6DF), # CJK Unified Ideographs Extension B - (0x2A700, 0x2B73F), # CJK Unified Ideographs Extension C - (0x2B740, 0x2B81F), # CJK Unified Ideographs Extension D - (0x2B820, 0x2CEAF), # CJK Unified Ideographs Extension E - (0x2CEB0, 0x2EBEF), # CJK Unified Ideographs Extension F - (0x2F800, 0x2FA1F), # CJK Compatibility Ideographs Supplement - ], - "non_base_ranges": [ - (0x302A, 0x302F), - (0x3190, 0x319F), - ], - "blues": [ - ("他 们 你 來 們 到 和 地 对 對 就 席 我 时 時 會 来 為 能 舰 說 说 这 這 齊 | 军 同 已 愿 既 星 是 景 民 照 现 現 理 用 置 要 軍 那 配 里 開 雷 露 面 顾", "TOP"), - ("个 为 人 他 以 们 你 來 個 們 到 和 大 对 對 就 我 时 時 有 来 為 要 說 说 | 主 些 因 它 想 意 理 生 當 看 着 置 者 自 著 裡 过 还 进 進 過 道 還 里 面", "0"), - (" 些 们 你 來 們 到 和 地 她 将 將 就 年 得 情 最 样 樣 理 能 說 说 这 這 通 | 即 吗 吧 听 呢 品 响 嗎 师 師 收 断 斷 明 眼 間 间 际 陈 限 除 陳 随 際 隨", "HORIZONTAL"), - ("事 前 學 将 將 情 想 或 政 斯 新 样 樣 民 沒 没 然 特 现 現 球 第 經 谁 起 | 例 別 别 制 动 動 吗 嗎 增 指 明 朝 期 构 物 确 种 調 调 費 费 那 都 間 间", "HORIZONTAL | RIGHT"), - ], - }, -] - -CJK_GROUP = ["HANI"] -INDIC_GROUP = ["LIMB", "ORYA", "SYLO", "TIBT"] - -def generate() -> str: - buf = "" - buf += "// THIS FILE IS AUTOGENERATED.\n" - buf += "// Any changes to this file will be overwritten.\n" - buf += "// Use ../scripts/gen_autohint_scripts.py to regenerate.\n\n" - - char_map = {} - - buf += "#[rustfmt::skip]\n" - buf += "pub(super) const SCRIPT_CLASSES: &[ScriptClass] = &[\n" - # some scripts generate multiple styles so keep track of the style index - style_index = 0 - for i, script in enumerate(SCRIPT_CLASSES): - std_chars = script["std_chars"] - blues = script["blues"] - tag = script["tag"] - group = "Default" - if tag in CJK_GROUP: - group = "Cjk" - elif tag in INDIC_GROUP: - group = "Indic" - unicode_tag = tag.lower().capitalize() - has_features = tag in SCRIPTS_WITH_FEATURES - buf += " ScriptClass {\n" - buf += " name: \"{}\",\n".format(script["name"]) - buf += " group: ScriptGroup::{},\n".format(group) - buf += " tag: Tag::new(b\"{}\"),\n".format(unicode_tag) - buf += " hint_top_to_bottom: {},\n".format(str(script["hint_top_to_bottom"]).lower()) - # standard characters - buf += " std_chars: \"{}\",\n".format(script["std_chars"]) - # blue characters - buf += " blues: &[" - if len(blues) != 0: - buf += "\n"; - for blue in blues: - blue_zones = "BlueZones::NONE" - if blue[1] != "0": - zones = list("BlueZones::" + zone for zone in blue[1].split(" | ")) - blue_zones = zones[0]; - for flag in zones[1:]: - blue_zones += ".union(" + flag + ")" - buf += " (\"" + blue[0] + "\"" - buf += ", {}),\n".format(blue_zones) - buf += " ],\n" - else: - buf += "],\n" - buf += " },\n" - if has_features: - style_index += len(STYLE_FEATURES) - bases = set() - # build a char -> (script_ix, is_non_base) map for all ranges - for char_range in script["base_ranges"]: - first = char_range[0] - last = char_range[1] - # inclusive range - for ch in range(first, last + 1): - # Note: FT has overlapping ranges but we choose to keep - # the first one to match behavior - if not ch in char_map: - char_map[ch] = (style_index, False) - bases.add(ch) - for char_range in script["non_base_ranges"]: - first = char_range[0] - last = char_range[1] - # inclusive range - for ch in range(first, last + 1): - if ch in bases: - char_map[ch] = (style_index, True) # True for non-base character - style_index += 1 - buf += "];\n\n" - - # Add some symbolic indices for each script so they can be - # referenced by ScriptClass::LATN for example - buf += "#[allow(unused)]" - buf += "impl ScriptClass {\n" - for i, script in enumerate(SCRIPT_CLASSES): - buf += " pub const {}: usize = {};\n".format(script["tag"], i) - buf += "}\n\n" - - # Now run through scripts again and generate style classes - buf += "#[rustfmt::skip]\n" - buf += "pub(super) const STYLE_CLASSES: &[StyleClass] = &[\n" - style_class_tags = [] - style_index = 0 - for i, script in enumerate(SCRIPT_CLASSES): - tag = script["tag"] - has_features = tag in SCRIPTS_WITH_FEATURES - if has_features: - for feature in STYLE_FEATURES: - name = script["name"] + " " + feature["name"] - feature_tag = feature["tag"] - buf += " StyleClass {{ name: \"{}\", index: {}, script: &SCRIPT_CLASSES[{}], feature: Some(Tag::new(b\"{}\")) }},\n".format(name, style_index, i, feature_tag) - style_index += 1 - style_class_tags.append(tag + "_" + feature_tag.upper()) - name = script["name"] - buf += " StyleClass {{ name: \"{}\", index: {}, script: &SCRIPT_CLASSES[{}], feature: None }},\n".format(name, style_index, i) - style_index += 1 - style_class_tags.append(tag) - buf += "];\n\n"; - - # Symbolic indices for style classes - buf += "#[allow(unused)]" - buf += "impl StyleClass {\n" - for (i, tag) in enumerate(style_class_tags): - buf += " pub const {}: usize = {};\n".format(tag, i) - buf += "}\n\n" - - # build a sorted list from the map - char_list = [] - for ch in char_map: - char_list.append((ch, char_map[ch])) - char_list.sort(key=lambda entry: entry[0]) - - # and merge into ranges - ranges = [] - for entry in char_list: - ch = entry[0] - props = entry[1] - if len(ranges) != 0: - last = ranges[-1]; - # we can merge if same props and this character extends the range - # by 1 - if ch == last[1] + 1 and last[2] == props: - ranges[-1] = (last[0], ch, props) - continue - ranges.append((ch, ch, props)) - - # and finally output the ranges - buf += "#[rustfmt::skip]\n" - buf += "pub(super) const STYLE_RANGES: &[StyleRange] = &[\n" - for char_range in ranges: - first = char_range[0] - last = char_range[1] - props = char_range[2] - kind = "base_range" - if props[1]: - kind = "non_base_range" - buf += " {}({}, {}, {}),\n".format(kind, first, last, props[0]) - buf += "];\n\n" - return buf - -if __name__ == "__main__": - data = generate() - with open("../generated/generated_autohint_styles.rs", "w", encoding="utf-8") as f: - f.write(data) diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,277 +0,0 @@ -//! Primary attributes typically used for font classification and selection. - -use read_fonts::{ - tables::{ - head::{Head, MacStyle}, - os2::{Os2, SelectionFlags}, - post::Post, - }, - TableProvider, -}; - -/// Stretch, style and weight attributes of a font. -/// -/// Variable fonts may contain axes that modify these attributes. The -/// [new](Self::new) method on this type returns values for the default -/// instance. -/// -/// These are derived from values in the -/// [OS/2](https://learn.microsoft.com/en-us/typography/opentype/spec/os2) if -/// available. Otherwise, they are retrieved from the -/// [head](https://learn.microsoft.com/en-us/typography/opentype/spec/head) -/// table. -#[derive(Copy, Clone, PartialEq, Debug, Default)] -pub struct Attributes { - pub stretch: Stretch, - pub style: Style, - pub weight: Weight, -} - -impl Attributes { - /// Extracts the stretch, style and weight attributes for the default - /// instance of the given font. - pub fn new<'a>(font: &impl TableProvider<'a>) -> Self { - if let Ok(os2) = font.os2() { - // Prefer values from the OS/2 table if it exists. We also use - // the post table to extract the angle for oblique styles. - Self::from_os2_post(os2, font.post().ok()) - } else if let Ok(head) = font.head() { - // Otherwise, fall back to the macStyle field of the head table. - Self::from_head(head) - } else { - Self::default() - } - } - - fn from_os2_post(os2: Os2, post: Option) -> Self { - let stretch = Stretch::from_width_class(os2.us_width_class()); - // Bits 1 and 9 of the fsSelection field signify italic and - // oblique, respectively. - // See: - let fs_selection = os2.fs_selection(); - let style = if fs_selection.contains(SelectionFlags::ITALIC) { - Style::Italic - } else if fs_selection.contains(SelectionFlags::OBLIQUE) { - let angle = post.map(|post| post.italic_angle().to_f64() as f32); - Style::Oblique(angle) - } else { - Style::Normal - }; - // The usWeightClass field is specified with a 1-1000 range, but - // we don't clamp here because variable fonts could potentially - // have a value outside of that range. - // See - let weight = Weight(os2.us_weight_class() as f32); - Self { - stretch, - style, - weight, - } - } - - fn from_head(head: Head) -> Self { - let mac_style = head.mac_style(); - let style = mac_style - .contains(MacStyle::ITALIC) - .then_some(Style::Italic) - .unwrap_or_default(); - let weight = mac_style - .contains(MacStyle::BOLD) - .then_some(Weight::BOLD) - .unwrap_or_default(); - Self { - stretch: Stretch::default(), - style, - weight, - } - } -} - -/// Visual width of a font-- a relative change from the normal aspect -/// ratio, typically in the range 0.5 to 2.0. -/// -/// In variable fonts, this can be controlled with the `wdth` axis. -/// -/// See -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] -pub struct Stretch(f32); - -impl Stretch { - /// Width that is 50% of normal. - pub const ULTRA_CONDENSED: Self = Self(0.5); - - /// Width that is 62.5% of normal. - pub const EXTRA_CONDENSED: Self = Self(0.625); - - /// Width that is 75% of normal. - pub const CONDENSED: Self = Self(0.75); - - /// Width that is 87.5% of normal. - pub const SEMI_CONDENSED: Self = Self(0.875); - - /// Width that is 100% of normal. - pub const NORMAL: Self = Self(1.0); - - /// Width that is 112.5% of normal. - pub const SEMI_EXPANDED: Self = Self(1.125); - - /// Width that is 125% of normal. - pub const EXPANDED: Self = Self(1.25); - - /// Width that is 150% of normal. - pub const EXTRA_EXPANDED: Self = Self(1.5); - - /// Width that is 200% of normal. - pub const ULTRA_EXPANDED: Self = Self(2.0); -} - -impl Stretch { - /// Creates a new stretch attribute with the given ratio. - pub const fn new(ratio: f32) -> Self { - Self(ratio) - } - - /// Creates a new stretch attribute from the - /// [usWidthClass]() - /// field of the OS/2 table. - fn from_width_class(width_class: u16) -> Self { - // The specified range is 1-9 and Skia simply clamps out of range - // values. We follow. - // See - match width_class { - 0..=1 => Stretch::ULTRA_CONDENSED, - 2 => Stretch::EXTRA_CONDENSED, - 3 => Stretch::CONDENSED, - 4 => Stretch::SEMI_CONDENSED, - 5 => Stretch::NORMAL, - 6 => Stretch::SEMI_EXPANDED, - 7 => Stretch::EXPANDED, - 8 => Stretch::EXTRA_EXPANDED, - _ => Stretch::ULTRA_EXPANDED, - } - } - - /// Returns the stretch attribute as a ratio. - /// - /// This is a linear scaling factor with 1.0 being "normal" width. - pub const fn ratio(self) -> f32 { - self.0 - } - - /// Returns the stretch attribute as a percentage value. - /// - /// This is generally the value associated with the `wdth` axis. - pub fn percentage(self) -> f32 { - self.0 * 100.0 - } -} - -impl Default for Stretch { - fn default() -> Self { - Self::NORMAL - } -} - -/// Visual style or 'slope' of a font. -/// -/// In variable fonts, this can be controlled with the `ital` -/// and `slnt` axes for italic and oblique styles, respectively. -/// -/// See -#[derive(Copy, Clone, PartialEq, Default, Debug)] -pub enum Style { - /// An upright or "roman" style. - #[default] - Normal, - /// Generally a slanted style, originally based on semi-cursive forms. - /// This often has a different structure from the normal style. - Italic, - /// Oblique (or slanted) style with an optional angle in degrees, - /// counter-clockwise from the vertical. - Oblique(Option), -} - -/// Visual weight class of a font, typically on a scale from 1.0 to 1000.0. -/// -/// In variable fonts, this can be controlled with the `wght` axis. -/// -/// See -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] -pub struct Weight(f32); - -impl Weight { - /// Weight value of 100. - pub const THIN: Self = Self(100.0); - - /// Weight value of 200. - pub const EXTRA_LIGHT: Self = Self(200.0); - - /// Weight value of 300. - pub const LIGHT: Self = Self(300.0); - - /// Weight value of 350. - pub const SEMI_LIGHT: Self = Self(350.0); - - /// Weight value of 400. - pub const NORMAL: Self = Self(400.0); - - /// Weight value of 500. - pub const MEDIUM: Self = Self(500.0); - - /// Weight value of 600. - pub const SEMI_BOLD: Self = Self(600.0); - - /// Weight value of 700. - pub const BOLD: Self = Self(700.0); - - /// Weight value of 800. - pub const EXTRA_BOLD: Self = Self(800.0); - - /// Weight value of 900. - pub const BLACK: Self = Self(900.0); - - /// Weight value of 950. - pub const EXTRA_BLACK: Self = Self(950.0); -} - -impl Weight { - /// Creates a new weight attribute with the given value. - pub const fn new(weight: f32) -> Self { - Self(weight) - } - - /// Returns the underlying weight value. - pub const fn value(self) -> f32 { - self.0 - } -} - -impl Default for Weight { - fn default() -> Self { - Self::NORMAL - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::prelude::*; - - #[test] - fn missing_os2() { - let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); - let attrs = font.attributes(); - assert_eq!(attrs.stretch, Stretch::NORMAL); - assert_eq!(attrs.style, Style::Italic); - assert_eq!(attrs.weight, Weight::BOLD); - } - - #[test] - fn so_stylish() { - let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); - let attrs = font.attributes(); - assert_eq!(attrs.stretch, Stretch::SEMI_CONDENSED); - assert_eq!(attrs.style, Style::Oblique(Some(-14.0))); - assert_eq!(attrs.weight, Weight::EXTRA_BOLD); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,510 +0,0 @@ -//! Mapping of characters (codepoints, not graphemes) to nominal glyph identifiers. -//! -//! If you have never run into character to glyph mapping before -//! [Glyph IDs and the 'cmap' table](https://rsheeter.github.io/font101/#glyph-ids-and-the-cmap-table) -//! might be informative. -//! -//! The functionality in this module provides a 1-to-1 mapping from Unicode -//! characters (or [Unicode variation sequences](http://unicode.org/faq/vs.html)) to -//! nominal or "default" internal glyph identifiers for a given font. -//! This is a necessary first step, but generally insufficient for proper layout of -//! [complex text](https://en.wikipedia.org/wiki/Complex_text_layout) or even -//! simple text containing diacritics and ligatures. -//! -//! Comprehensive mapping of characters to positioned glyphs requires a process called -//! shaping. For more detail, see: [Why do I need a shaping engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html) - -use read_fonts::{ - tables::cmap::{ - self, Cmap, Cmap12, Cmap12Iter, Cmap14, Cmap14Iter, Cmap4, Cmap4Iter, CmapSubtable, - EncodingRecord, PlatformId, - }, - types::GlyphId, - FontData, TableProvider, -}; - -pub use read_fonts::tables::cmap::MapVariant; - -/// Mapping of characters to nominal glyph identifiers. -/// -/// The mappings are derived from the [cmap](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap) -/// table. -/// -/// ## Obtaining a Charmap -/// -/// Typically a Charmap is acquired by calling [charmap](crate::MetadataProvider::charmap) on a [FontRef](crate::FontRef). -/// -/// ## Selection strategy -/// -/// Fonts may contain multiple subtables in various formats supporting different encodings. The selection -/// strategy implemented here is designed to choose mappings that capture the broadest available Unicode -/// coverage: -/// -/// * Unicode characters: a symbol mapping subtable is selected if available. Otherwise, subtables supporting -/// the Unicode full repertoire or Basic Multilingual Plane (BMP) are preferred, in that order. Formats -/// [4](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values) -/// and [12](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage) are -/// supported. -/// -/// * Unicode variation sequences: these are provided by a format -/// [14](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences) -/// subtable. -/// -#[derive(Clone, Default)] -pub struct Charmap<'a> { - codepoint_subtable: Option>, - variant_subtable: Option>, -} - -impl<'a> Charmap<'a> { - /// Creates a new character map from the given font. - pub fn new(font: &impl TableProvider<'a>) -> Self { - let Ok(cmap) = font.cmap() else { - return Default::default(); - }; - let selection = MappingSelection::new(&cmap); - Self { - codepoint_subtable: selection - .codepoint_subtable - .map(|subtable| CodepointSubtable { - subtable, - is_symbol: selection.mapping_index.codepoint_subtable_is_symbol, - }), - variant_subtable: selection.variant_subtable, - } - } - - /// Returns true if a suitable Unicode character mapping is available. - pub fn has_map(&self) -> bool { - self.codepoint_subtable.is_some() - } - - /// Returns true if a symbol mapping was selected. - pub fn is_symbol(&self) -> bool { - self.codepoint_subtable - .as_ref() - .map(|x| x.is_symbol) - .unwrap_or(false) - } - - /// Returns true if a Unicode variation sequence mapping is available. - pub fn has_variant_map(&self) -> bool { - self.variant_subtable.is_some() - } - - /// Maps a character to a nominal glyph identifier. - /// - /// Returns `None` if a mapping does not exist. - pub fn map(&self, ch: impl Into) -> Option { - self.codepoint_subtable.as_ref()?.map(ch.into()) - } - - /// Returns an iterator over all mappings of codepoint to nominal glyph - /// identifiers in the character map. - pub fn mappings(&self) -> Mappings<'a> { - self.codepoint_subtable - .as_ref() - .map(|subtable| { - Mappings(match &subtable.subtable { - SupportedSubtable::Format4(cmap4) => MappingsInner::Format4(cmap4.iter()), - SupportedSubtable::Format12(cmap12) => MappingsInner::Format12(cmap12.iter()), - }) - }) - .unwrap_or(Mappings(MappingsInner::None)) - } - - /// Maps a character and variation selector to a nominal glyph identifier. - /// - /// Returns `None` if a mapping does not exist. - pub fn map_variant(&self, ch: impl Into, selector: impl Into) -> Option { - self.variant_subtable.as_ref()?.map_variant(ch, selector) - } - - /// Returns an iterator over all mappings of character and variation - /// selector to nominal glyph identifier in the character map. - pub fn variant_mappings(&self) -> VariantMappings<'a> { - VariantMappings(self.variant_subtable.clone().map(|cmap14| cmap14.iter())) - } -} - -/// Cacheable indices of selected mapping tables for materializing a character -/// map. -/// -/// Since [`Charmap`] carries a lifetime, it is difficult to store in a cache. -/// This type serves as an acceleration structure that allows for construction -/// of a character map while skipping the search for the most suitable Unicode -/// mappings. -#[derive(Copy, Clone, Default, Debug)] -pub struct MappingIndex { - /// Index of Unicode or symbol mapping subtable. - codepoint_subtable: Option, - /// True if the above is a symbol mapping. - codepoint_subtable_is_symbol: bool, - /// Index of Unicode variation selector subtable. - variant_subtable: Option, -} - -impl MappingIndex { - /// Finds the indices of the most suitable Unicode mapping tables in the - /// given font. - pub fn new<'a>(font: &impl TableProvider<'a>) -> Self { - let Ok(cmap) = font.cmap() else { - return Default::default(); - }; - MappingSelection::new(&cmap).mapping_index - } - - /// Creates a new character map for the given font using the tables referenced by - /// the precomputed indices. - /// - /// The font should be the same as the one used to construct this object. - pub fn charmap<'a>(&self, font: &impl TableProvider<'a>) -> Charmap<'a> { - let Ok(cmap) = font.cmap() else { - return Default::default(); - }; - let records = cmap.encoding_records(); - let data = cmap.offset_data(); - Charmap { - codepoint_subtable: self - .codepoint_subtable - .and_then(|index| get_subtable(data, records, index)) - .and_then(SupportedSubtable::new) - .map(|subtable| CodepointSubtable { - subtable, - is_symbol: self.codepoint_subtable_is_symbol, - }), - variant_subtable: self - .variant_subtable - .and_then(|index| get_subtable(data, records, index)) - .and_then(|subtable| match subtable { - CmapSubtable::Format14(cmap14) => Some(cmap14), - _ => None, - }), - } - } -} - -/// Iterator over all mappings of character to nominal glyph identifier -/// in a character map. -/// -/// This is created with the [`Charmap::mappings`] method. -#[derive(Clone)] -pub struct Mappings<'a>(MappingsInner<'a>); - -impl Iterator for Mappings<'_> { - type Item = (u32, GlyphId); - - fn next(&mut self) -> Option { - match &mut self.0 { - MappingsInner::None => None, - MappingsInner::Format4(iter) => iter.next(), - MappingsInner::Format12(iter) => iter.next(), - } - } -} - -#[derive(Clone)] -enum MappingsInner<'a> { - None, - Format4(Cmap4Iter<'a>), - Format12(Cmap12Iter<'a>), -} - -/// Iterator over all mappings of character and variation selector to -/// nominal glyph identifier in a character map. -/// -/// This is created with the [`Charmap::variant_mappings`] method. -#[derive(Clone)] -pub struct VariantMappings<'a>(Option>); - -impl Iterator for VariantMappings<'_> { - type Item = (u32, u32, MapVariant); - - fn next(&mut self) -> Option { - self.0.as_mut()?.next() - } -} - -fn get_subtable<'a>( - data: FontData<'a>, - records: &[EncodingRecord], - index: u16, -) -> Option> { - records - .get(index as usize) - .and_then(|record| record.subtable(data).ok()) -} - -#[derive(Clone)] -struct CodepointSubtable<'a> { - subtable: SupportedSubtable<'a>, - /// True if the subtable is a symbol mapping. - is_symbol: bool, -} - -impl CodepointSubtable<'_> { - fn map(&self, codepoint: u32) -> Option { - self.map_impl(codepoint).or_else(|| { - if self.is_symbol && codepoint <= 0x00FF { - // From HarfBuzz: - // For symbol-encoded OpenType fonts, we duplicate the - // U+F000..F0FF range at U+0000..U+00FF. That's what - // Windows seems to do, and that's hinted about at: - // https://docs.microsoft.com/en-us/typography/opentype/spec/recom - // under "Non-Standard (Symbol) Fonts". - // See - self.map_impl(codepoint + 0xF000) - } else { - None - } - }) - } - - fn map_impl(&self, codepoint: u32) -> Option { - match &self.subtable { - SupportedSubtable::Format4(subtable) => subtable.map_codepoint(codepoint), - SupportedSubtable::Format12(subtable) => subtable.map_codepoint(codepoint), - } - } -} - -#[derive(Clone)] -enum SupportedSubtable<'a> { - Format4(Cmap4<'a>), - Format12(Cmap12<'a>), -} - -impl<'a> SupportedSubtable<'a> { - fn new(subtable: CmapSubtable<'a>) -> Option { - Some(match subtable { - CmapSubtable::Format4(cmap4) => Self::Format4(cmap4), - CmapSubtable::Format12(cmap12) => Self::Format12(cmap12), - _ => return None, - }) - } - - fn from_cmap_record(cmap: &Cmap<'a>, record: &cmap::EncodingRecord) -> Option { - Self::new(record.subtable(cmap.offset_data()).ok()?) - } -} - -/// The mapping kind of a cmap subtable. -/// -/// The ordering is significant and determines the priority of subtable -/// selection (greater is better). -#[derive(Copy, Clone, PartialEq, PartialOrd)] -enum MappingKind { - None = 0, - UnicodeBmp = 1, - UnicodeFull = 2, - Symbol = 3, -} - -/// The result of searching the cmap table for the "best" available -/// subtables. -/// -/// For `codepoint_subtable`, best means either symbol (which is preferred) -/// or a Unicode subtable with the greatest coverage. -/// -/// For `variant_subtable`, best means a format 14 subtable. -struct MappingSelection<'a> { - /// The mapping index accelerator that holds indices of the following - /// subtables. - mapping_index: MappingIndex, - /// Either a symbol subtable or the Unicode subtable with the - /// greatest coverage. - codepoint_subtable: Option>, - /// Subtable that supports mapping Unicode variation sequences. - variant_subtable: Option>, -} - -impl<'a> MappingSelection<'a> { - fn new(cmap: &Cmap<'a>) -> Self { - const ENCODING_MS_SYMBOL: u16 = 0; - const ENCODING_MS_UNICODE_CS: u16 = 1; - const ENCODING_APPLE_ID_UNICODE_32: u16 = 4; - const ENCODING_APPLE_ID_VARIANT_SELECTOR: u16 = 5; - const ENCODING_MS_ID_UCS_4: u16 = 10; - let mut mapping_index = MappingIndex::default(); - let mut mapping_kind = MappingKind::None; - let mut codepoint_subtable = None; - let mut variant_subtable = None; - let mut maybe_choose_subtable = |kind, index, subtable| { - if kind > mapping_kind { - mapping_kind = kind; - mapping_index.codepoint_subtable_is_symbol = kind == MappingKind::Symbol; - mapping_index.codepoint_subtable = Some(index as u16); - codepoint_subtable = Some(subtable); - } - }; - // This generally follows the same strategy as FreeType, searching the encoding - // records in reverse and prioritizing UCS-4 subtables over UCS-2. - // See - // The exception is that we prefer a symbol subtable over all others which matches the behavior - // of HarfBuzz. - // See - for (i, record) in cmap.encoding_records().iter().enumerate().rev() { - match (record.platform_id(), record.encoding_id()) { - (PlatformId::Unicode, ENCODING_APPLE_ID_VARIANT_SELECTOR) => { - // Unicode variation sequences - if let Ok(CmapSubtable::Format14(subtable)) = - record.subtable(cmap.offset_data()) - { - if variant_subtable.is_none() { - mapping_index.variant_subtable = Some(i as u16); - variant_subtable = Some(subtable); - } - } - } - (PlatformId::Windows, ENCODING_MS_SYMBOL) => { - // Symbol - if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { - maybe_choose_subtable(MappingKind::Symbol, i, subtable); - } - } - (PlatformId::Windows, ENCODING_MS_ID_UCS_4) - | (PlatformId::Unicode, ENCODING_APPLE_ID_UNICODE_32) => { - // Unicode full repertoire - if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { - maybe_choose_subtable(MappingKind::UnicodeFull, i, subtable); - } - } - (PlatformId::ISO, _) - | (PlatformId::Unicode, _) - | (PlatformId::Windows, ENCODING_MS_UNICODE_CS) => { - // Unicode BMP only - if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { - maybe_choose_subtable(MappingKind::UnicodeBmp, i, subtable); - } - } - _ => {} - } - } - Self { - mapping_index, - codepoint_subtable, - variant_subtable, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::MetadataProvider; - use read_fonts::FontRef; - - #[test] - fn choose_format_12_over_4() { - let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); - let charmap = font.charmap(); - assert!(matches!( - charmap.codepoint_subtable.unwrap().subtable, - SupportedSubtable::Format12(..) - )); - } - - #[test] - fn choose_format_4() { - let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); - let charmap = font.charmap(); - assert!(matches!( - charmap.codepoint_subtable.unwrap().subtable, - SupportedSubtable::Format4(..) - )); - } - - #[test] - fn choose_symbol() { - let font = FontRef::new(font_test_data::CMAP4_SYMBOL_PUA).unwrap(); - let charmap = font.charmap(); - assert!(charmap.is_symbol()); - assert!(matches!( - charmap.codepoint_subtable.unwrap().subtable, - SupportedSubtable::Format4(..) - )); - } - - #[test] - fn map_format_4() { - let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); - let charmap = font.charmap(); - assert_eq!(charmap.map('A'), Some(GlyphId::new(1))); - assert_eq!(charmap.map('À'), Some(GlyphId::new(2))); - assert_eq!(charmap.map('`'), Some(GlyphId::new(3))); - assert_eq!(charmap.map('B'), None); - } - - #[test] - fn map_format_12() { - let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); - let charmap = font.charmap(); - assert_eq!(charmap.map(' '), None); - assert_eq!(charmap.map(0x101723_u32), Some(GlyphId::new(1))); - assert_eq!(charmap.map(0x101725_u32), Some(GlyphId::new(3))); - assert_eq!(charmap.map(0x102523_u32), Some(GlyphId::new(6))); - assert_eq!(charmap.map(0x102526_u32), Some(GlyphId::new(9))); - assert_eq!(charmap.map(0x102527_u32), Some(GlyphId::new(10))); - } - - #[test] - fn map_symbol_pua() { - let font = FontRef::new(font_test_data::CMAP4_SYMBOL_PUA).unwrap(); - let charmap = font.charmap(); - assert!(charmap.codepoint_subtable.as_ref().unwrap().is_symbol); - assert_eq!(charmap.map(0xF001_u32), Some(GlyphId::new(1))); - assert_eq!(charmap.map(0xF002_u32), Some(GlyphId::new(2))); - assert_eq!(charmap.map(0xF003_u32), Some(GlyphId::new(3))); - assert_eq!(charmap.map(0xF0FE_u32), Some(GlyphId::new(4))); - // The following don't exist in the cmap table and are remapped into the U+F000..F0FF range - // due to the selection of a symbol mapping subtable. - assert_eq!(charmap.map(0x1_u32), Some(GlyphId::new(1))); - assert_eq!(charmap.map(0x2_u32), Some(GlyphId::new(2))); - assert_eq!(charmap.map(0x3_u32), Some(GlyphId::new(3))); - assert_eq!(charmap.map(0xFE_u32), Some(GlyphId::new(4))); - } - - #[test] - fn map_variants() { - use super::MapVariant::*; - let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); - let charmap = font.charmap(); - let selector = '\u{e0100}'; - assert_eq!(charmap.map_variant('a', selector), None); - assert_eq!(charmap.map_variant('\u{4e00}', selector), Some(UseDefault)); - assert_eq!(charmap.map_variant('\u{4e06}', selector), Some(UseDefault)); - assert_eq!( - charmap.map_variant('\u{4e08}', selector), - Some(Variant(GlyphId::new(25))) - ); - assert_eq!( - charmap.map_variant('\u{4e09}', selector), - Some(Variant(GlyphId::new(26))) - ); - } - - #[test] - fn mappings() { - for font_data in [ - font_test_data::VAZIRMATN_VAR, - font_test_data::CMAP12_FONT1, - font_test_data::SIMPLE_GLYF, - font_test_data::CMAP4_SYMBOL_PUA, - ] { - let font = FontRef::new(font_data).unwrap(); - let charmap = font.charmap(); - for (codepoint, glyph_id) in charmap.mappings() { - assert_eq!(charmap.map(codepoint), Some(glyph_id)); - } - } - } - - #[test] - fn variant_mappings() { - let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); - let charmap = font.charmap(); - for (codepoint, selector, variant) in charmap.variant_mappings() { - assert_eq!(charmap.map_variant(codepoint, selector), Some(variant)); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,352 +0,0 @@ -//! Internal "small" style collection types. - -use alloc::vec::Vec; -use core::hash::{Hash, Hasher}; - -/// A growable vector type with inline storage optimization. -/// -/// Note that unlike the real `SmallVec`, this only works with types that -/// are `Copy + Default` to simplify our implementation. -#[derive(Clone)] -pub(crate) struct SmallVec(Storage); - -impl SmallVec -where - T: Copy + Default, -{ - /// Creates a new, empty `SmallVec`. - pub fn new() -> Self { - Self(Storage::Inline([T::default(); N], 0)) - } - - /// Creates a new `SmallVec` of the given length with each element - /// containing a copy of `value`. - pub fn with_len(len: usize, value: T) -> Self { - if len <= N { - Self(Storage::Inline([value; N], len)) - } else { - let mut vec = Vec::new(); - vec.resize(len, value); - Self(Storage::Heap(vec)) - } - } - - /// Clears the vector, removing all values. - pub fn clear(&mut self) { - match &mut self.0 { - Storage::Inline(_buf, len) => *len = 0, - Storage::Heap(vec) => vec.clear(), - } - } - - /// Tries to reserve capacity for at least `additional` more elements. - pub fn try_reserve(&mut self, additional: usize) -> bool { - match &mut self.0 { - Storage::Inline(buf, len) => { - let new_cap = *len + additional; - if new_cap > N { - let mut vec = Vec::new(); - if vec.try_reserve(new_cap).is_err() { - return false; - } - vec.extend_from_slice(&buf[..*len]); - self.0 = Storage::Heap(vec); - } - } - Storage::Heap(vec) => { - if vec.try_reserve(additional).is_err() { - return false; - } - } - } - true - } - - /// Appends an element to the back of the collection. - pub fn push(&mut self, value: T) { - match &mut self.0 { - Storage::Inline(buf, len) => { - if *len + 1 > N { - let mut vec = Vec::with_capacity(*len + 1); - vec.extend_from_slice(&buf[..*len]); - vec.push(value); - self.0 = Storage::Heap(vec); - } else { - buf[*len] = value; - *len += 1; - } - } - Storage::Heap(vec) => vec.push(value), - } - } - - /// Removes and returns the value at the back of the collection. - pub fn pop(&mut self) -> Option { - match &mut self.0 { - Storage::Inline(buf, len) => { - if *len > 0 { - *len -= 1; - Some(buf[*len]) - } else { - None - } - } - Storage::Heap(vec) => vec.pop(), - } - } - - /// Shortens the vector, keeping the first `len` elements. - pub fn truncate(&mut self, len: usize) { - match &mut self.0 { - Storage::Inline(_buf, inline_len) => { - *inline_len = len.min(*inline_len); - } - Storage::Heap(vec) => vec.truncate(len), - } - } -} - -impl SmallVec { - /// Extracts a slice containing the entire vector. - pub fn as_slice(&self) -> &[T] { - match &self.0 { - Storage::Inline(buf, len) => &buf[..*len], - Storage::Heap(vec) => vec.as_slice(), - } - } - - /// Extracts a mutable slice containing the entire vector. - pub fn as_mut_slice(&mut self) -> &mut [T] { - match &mut self.0 { - Storage::Inline(buf, len) => &mut buf[..*len], - Storage::Heap(vec) => vec.as_mut_slice(), - } - } -} - -impl Default for SmallVec -where - T: Copy + Default, -{ - fn default() -> Self { - Self::new() - } -} - -impl core::ops::Deref for SmallVec { - type Target = [T]; - - fn deref(&self) -> &Self::Target { - self.as_slice() - } -} - -impl core::ops::DerefMut for SmallVec { - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut_slice() - } -} - -impl Hash for SmallVec -where - T: Hash, -{ - fn hash(&self, state: &mut H) { - self.as_slice().hash(state); - } -} - -impl PartialEq for SmallVec -where - T: PartialEq, -{ - fn eq(&self, other: &Self) -> bool { - self.as_slice() == other.as_slice() - } -} - -impl PartialEq<[T]> for SmallVec -where - T: PartialEq, -{ - fn eq(&self, other: &[T]) -> bool { - self.as_slice() == other - } -} - -impl Eq for SmallVec where T: Eq {} - -impl core::fmt::Debug for SmallVec -where - T: core::fmt::Debug, -{ - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.debug_list().entries(self.as_slice().iter()).finish() - } -} - -impl<'a, T, const N: usize> IntoIterator for &'a SmallVec { - type IntoIter = core::slice::Iter<'a, T>; - type Item = &'a T; - - fn into_iter(self) -> Self::IntoIter { - self.as_slice().iter() - } -} - -impl<'a, T, const N: usize> IntoIterator for &'a mut SmallVec { - type IntoIter = core::slice::IterMut<'a, T>; - type Item = &'a mut T; - - fn into_iter(self) -> Self::IntoIter { - self.as_mut_slice().iter_mut() - } -} - -impl IntoIterator for SmallVec -where - T: Copy, -{ - type IntoIter = IntoIter; - type Item = T; - - fn into_iter(self) -> Self::IntoIter { - IntoIter { vec: self, pos: 0 } - } -} - -#[derive(Clone)] -pub(crate) struct IntoIter { - vec: SmallVec, - pos: usize, -} - -impl Iterator for IntoIter -where - T: Copy, -{ - type Item = T; - - fn next(&mut self) -> Option { - let value = self.vec.get(self.pos)?; - self.pos += 1; - Some(*value) - } -} - -#[derive(Clone)] -enum Storage { - Inline([T; N], usize), - Heap(Vec), -} - -#[cfg(test)] -mod test { - use super::{SmallVec, Storage}; - - #[test] - fn choose_inline() { - let vec = SmallVec::<_, 4>::with_len(4, 0); - assert!(matches!(vec.0, Storage::Inline(..))); - assert_eq!(vec.len(), 4); - } - - #[test] - fn choose_heap() { - let vec = SmallVec::<_, 4>::with_len(5, 0); - assert!(matches!(vec.0, Storage::Heap(..))); - assert_eq!(vec.len(), 5); - } - - #[test] - fn store_and_read_inline() { - let mut vec = SmallVec::<_, 8>::with_len(8, 0); - for (i, value) in vec.iter_mut().enumerate() { - *value = i * 2; - } - let expected = [0, 2, 4, 6, 8, 10, 12, 14]; - assert_eq!(vec.as_slice(), &expected); - assert_eq!(format!("{vec:?}"), format!("{expected:?}")); - } - - #[test] - fn store_and_read_heap() { - let mut vec = SmallVec::<_, 4>::with_len(8, 0); - for (i, value) in vec.iter_mut().enumerate() { - *value = i * 2; - } - let expected = [0, 2, 4, 6, 8, 10, 12, 14]; - assert_eq!(vec.as_slice(), &expected); - assert_eq!(format!("{vec:?}"), format!("{expected:?}")); - } - - #[test] - fn spill_to_heap() { - let mut vec = SmallVec::<_, 4>::new(); - for i in 0..4 { - vec.push(i); - } - assert!(matches!(vec.0, Storage::Inline(..))); - vec.push(4); - assert!(matches!(vec.0, Storage::Heap(..))); - let expected = [0, 1, 2, 3, 4]; - assert_eq!(vec.as_slice(), &expected); - } - - #[test] - fn clear_inline() { - let mut vec = SmallVec::<_, 4>::new(); - for i in 0..4 { - vec.push(i); - } - assert!(matches!(vec.0, Storage::Inline(..))); - assert_eq!(vec.len(), 4); - vec.clear(); - assert_eq!(vec.len(), 0); - } - - #[test] - fn clear_heap() { - let mut vec = SmallVec::<_, 3>::new(); - for i in 0..4 { - vec.push(i); - } - assert!(matches!(vec.0, Storage::Heap(..))); - assert_eq!(vec.len(), 4); - vec.clear(); - assert_eq!(vec.len(), 0); - } - - #[test] - fn reserve() { - let mut vec = SmallVec::<_, 3>::new(); - for i in 0..2 { - vec.push(i); - } - assert!(matches!(vec.0, Storage::Inline(..))); - assert!(vec.try_reserve(1)); - // still inline after reserving 1 - assert!(matches!(vec.0, Storage::Inline(..))); - assert!(vec.try_reserve(2)); - // reserving 2 spills to heap - assert!(matches!(vec.0, Storage::Heap(..))); - } - - #[test] - fn iter() { - let mut vec = SmallVec::<_, 3>::new(); - for i in 0..3 { - vec.push(i); - } - assert!(&[0, 1, 2].iter().eq(vec.iter())); - } - - #[test] - fn into_iter() { - let mut vec = SmallVec::<_, 3>::new(); - for i in 0..3 { - vec.push(i); - } - assert!([0, 1, 2].into_iter().eq(vec.into_iter())); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,597 +0,0 @@ -//! COLR table instance. - -use read_fonts::{ - tables::{ - colr::*, - variations::{ - DeltaSetIndex, DeltaSetIndexMap, FloatItemDelta, FloatItemDeltaTarget, - ItemVariationStore, - }, - }, - types::{BoundingBox, F2Dot14, GlyphId16, Point}, - ReadError, -}; - -use core::ops::{Deref, Range}; - -/// Unique paint identifier used for detecting cycles in the paint graph. -pub type PaintId = usize; - -/// Combination of a `COLR` table and a location in variation space for -/// resolving paints. -/// -/// See [`resolve_paint`], [`ColorStops::resolve`] and [`resolve_clip_box`]. -#[derive(Clone)] -pub struct ColrInstance<'a> { - colr: Colr<'a>, - index_map: Option>, - var_store: Option>, - coords: &'a [F2Dot14], -} - -impl<'a> ColrInstance<'a> { - /// Creates a new instance for the given `COLR` table and normalized variation - /// coordinates. - pub fn new(colr: Colr<'a>, coords: &'a [F2Dot14]) -> Self { - let index_map = colr.var_index_map().and_then(|res| res.ok()); - let var_store = colr.item_variation_store().and_then(|res| res.ok()); - Self { - colr, - coords, - index_map, - var_store, - } - } - - /// Computes a sequence of N variation deltas starting at the given - /// `var_base` index. - fn var_deltas(&self, var_index_base: u32) -> [FloatItemDelta; N] { - // Magic value that indicates deltas should not be applied. - const NO_VARIATION_DELTAS: u32 = 0xFFFFFFFF; - // Note: FreeType never returns an error for these lookups, so - // we do the same and just `unwrap_or_default` on var store - // errors. - // See - let mut deltas = [FloatItemDelta::ZERO; N]; - if self.coords.is_empty() - || self.var_store.is_none() - || var_index_base == NO_VARIATION_DELTAS - { - return deltas; - } - let var_store = self.var_store.as_ref().unwrap(); - if let Some(index_map) = self.index_map.as_ref() { - for (i, delta) in deltas.iter_mut().enumerate() { - let var_index = var_index_base + i as u32; - if let Ok(delta_ix) = index_map.get(var_index) { - *delta = var_store - .compute_float_delta(delta_ix, self.coords) - .unwrap_or_default(); - } - } - } else { - for (i, delta) in deltas.iter_mut().enumerate() { - let var_index = var_index_base + i as u32; - // If we don't have a var index map, use our index as the inner - // component and set the outer to 0. - let delta_ix = DeltaSetIndex { - outer: 0, - inner: var_index as u16, - }; - *delta = var_store - .compute_float_delta(delta_ix, self.coords) - .unwrap_or_default(); - } - } - deltas - } -} - -impl<'a> Deref for ColrInstance<'a> { - type Target = Colr<'a>; - - fn deref(&self) -> &Self::Target { - &self.colr - } -} - -/// Resolves a clip box, applying variation deltas using the given -/// instance. -pub fn resolve_clip_box(instance: &ColrInstance, clip_box: &ClipBox) -> BoundingBox { - match clip_box { - ClipBox::Format1(cbox) => BoundingBox { - x_min: cbox.x_min().to_i16() as f32, - y_min: cbox.y_min().to_i16() as f32, - x_max: cbox.x_max().to_i16() as f32, - y_max: cbox.y_max().to_i16() as f32, - }, - ClipBox::Format2(cbox) => { - let deltas = instance.var_deltas::<4>(cbox.var_index_base()); - BoundingBox { - x_min: cbox.x_min().apply_float_delta(deltas[0]), - y_min: cbox.y_min().apply_float_delta(deltas[1]), - x_max: cbox.x_max().apply_float_delta(deltas[2]), - y_max: cbox.y_max().apply_float_delta(deltas[3]), - } - } - } -} - -/// Simplified version of a [`ColorStop`] or [`VarColorStop`] with applied -/// variation deltas. -#[derive(Clone, Debug)] -pub struct ResolvedColorStop { - pub offset: f32, - pub palette_index: u16, - pub alpha: f32, -} - -/// Collection of [`ColorStop`] or [`VarColorStop`]. -// Note: only one of these fields is used at any given time, but this structure -// was chosen over the obvious enum approach for simplicity in generating a -// single concrete type for the `impl Iterator` return type of the `resolve` -// method. -#[derive(Clone)] -pub struct ColorStops<'a> { - stops: &'a [ColorStop], - var_stops: &'a [VarColorStop], -} - -impl ColorStops<'_> { - pub fn len(&self) -> usize { - self.stops.len() + self.var_stops.len() - } - - pub fn is_empty(&self) -> bool { - self.stops.is_empty() && self.var_stops.is_empty() - } -} - -impl<'a> From> for ColorStops<'a> { - fn from(value: ColorLine<'a>) -> Self { - Self { - stops: value.color_stops(), - var_stops: &[], - } - } -} - -impl<'a> From> for ColorStops<'a> { - fn from(value: VarColorLine<'a>) -> Self { - Self { - stops: &[], - var_stops: value.color_stops(), - } - } -} - -impl<'a> ColorStops<'a> { - /// Returns an iterator yielding resolved color stops with variation deltas - /// applied. - pub fn resolve( - &self, - instance: &'a ColrInstance<'a>, - ) -> impl Iterator + 'a { - self.stops - .iter() - .map(|stop| ResolvedColorStop { - offset: stop.stop_offset().to_f32(), - palette_index: stop.palette_index(), - alpha: stop.alpha().to_f32(), - }) - .chain(self.var_stops.iter().map(|stop| { - let deltas = instance.var_deltas::<2>(stop.var_index_base()); - ResolvedColorStop { - offset: stop.stop_offset().apply_float_delta(deltas[0]), - palette_index: stop.palette_index(), - alpha: stop.alpha().apply_float_delta(deltas[1]), - } - })) - } -} - -/// Simplified version of `Paint` with applied variation deltas. -/// -/// These are constructed with the [`resolve_paint`] function. -/// -/// This is roughly equivalent to FreeType's -/// [`FT_COLR_Paint`](https://freetype.org/freetype2/docs/reference/ft2-layer_management.html#ft_colr_paint) -/// type. -pub enum ResolvedPaint<'a> { - ColrLayers { - range: Range, - }, - Solid { - palette_index: u16, - alpha: f32, - }, - LinearGradient { - x0: f32, - y0: f32, - x1: f32, - y1: f32, - x2: f32, - y2: f32, - color_stops: ColorStops<'a>, - extend: Extend, - }, - RadialGradient { - x0: f32, - y0: f32, - radius0: f32, - x1: f32, - y1: f32, - radius1: f32, - color_stops: ColorStops<'a>, - extend: Extend, - }, - SweepGradient { - center_x: f32, - center_y: f32, - start_angle: f32, - end_angle: f32, - color_stops: ColorStops<'a>, - extend: Extend, - }, - Glyph { - glyph_id: GlyphId16, - paint: Paint<'a>, - }, - ColrGlyph { - glyph_id: GlyphId16, - }, - Transform { - xx: f32, - yx: f32, - xy: f32, - yy: f32, - dx: f32, - dy: f32, - paint: Paint<'a>, - }, - Translate { - dx: f32, - dy: f32, - paint: Paint<'a>, - }, - Scale { - scale_x: f32, - scale_y: f32, - around_center: Option>, - paint: Paint<'a>, - }, - Rotate { - angle: f32, - around_center: Option>, - paint: Paint<'a>, - }, - Skew { - x_skew_angle: f32, - y_skew_angle: f32, - around_center: Option>, - paint: Paint<'a>, - }, - Composite { - source_paint: Paint<'a>, - mode: CompositeMode, - backdrop_paint: Paint<'a>, - }, -} - -/// Resolves this paint with the given instance. -/// -/// Resolving means that all numeric values are converted to 32-bit floating -/// point, variation deltas are applied (also computed fully in floating -/// point), and the various transform paints are collapsed into a single value -/// for their category (transform, translate, scale, rotate and skew). -/// -/// This provides a simpler type for consumers that are more interested -/// in extracting the semantics of the graph rather than working with the -/// raw encoded structures. -pub fn resolve_paint<'a>( - instance: &ColrInstance<'a>, - paint: &Paint<'a>, -) -> Result, ReadError> { - Ok(match paint { - Paint::ColrLayers(layers) => { - let start = layers.first_layer_index() as usize; - ResolvedPaint::ColrLayers { - range: start..start + layers.num_layers() as usize, - } - } - Paint::Solid(solid) => ResolvedPaint::Solid { - palette_index: solid.palette_index(), - alpha: solid.alpha().to_f32(), - }, - Paint::VarSolid(solid) => { - let deltas = instance.var_deltas::<1>(solid.var_index_base()); - ResolvedPaint::Solid { - palette_index: solid.palette_index(), - alpha: solid.alpha().apply_float_delta(deltas[0]), - } - } - Paint::LinearGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - ResolvedPaint::LinearGradient { - x0: gradient.x0().to_i16() as f32, - y0: gradient.y0().to_i16() as f32, - x1: gradient.x1().to_i16() as f32, - y1: gradient.y1().to_i16() as f32, - x2: gradient.x2().to_i16() as f32, - y2: gradient.y2().to_i16() as f32, - color_stops: color_line.into(), - extend, - } - } - Paint::VarLinearGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - let deltas = instance.var_deltas::<6>(gradient.var_index_base()); - ResolvedPaint::LinearGradient { - x0: gradient.x0().apply_float_delta(deltas[0]), - y0: gradient.y0().apply_float_delta(deltas[1]), - x1: gradient.x1().apply_float_delta(deltas[2]), - y1: gradient.y1().apply_float_delta(deltas[3]), - x2: gradient.x2().apply_float_delta(deltas[4]), - y2: gradient.y2().apply_float_delta(deltas[5]), - color_stops: color_line.into(), - extend, - } - } - Paint::RadialGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - ResolvedPaint::RadialGradient { - x0: gradient.x0().to_i16() as f32, - y0: gradient.y0().to_i16() as f32, - radius0: gradient.radius0().to_u16() as f32, - x1: gradient.x1().to_i16() as f32, - y1: gradient.y1().to_i16() as f32, - radius1: gradient.radius1().to_u16() as f32, - color_stops: color_line.into(), - extend, - } - } - Paint::VarRadialGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - let deltas = instance.var_deltas::<6>(gradient.var_index_base()); - ResolvedPaint::RadialGradient { - x0: gradient.x0().apply_float_delta(deltas[0]), - y0: gradient.y0().apply_float_delta(deltas[1]), - radius0: gradient.radius0().apply_float_delta(deltas[2]), - x1: gradient.x1().apply_float_delta(deltas[3]), - y1: gradient.y1().apply_float_delta(deltas[4]), - radius1: gradient.radius1().apply_float_delta(deltas[5]), - color_stops: color_line.into(), - extend, - } - } - Paint::SweepGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - ResolvedPaint::SweepGradient { - center_x: gradient.center_x().to_i16() as f32, - center_y: gradient.center_y().to_i16() as f32, - start_angle: gradient.start_angle().to_f32(), - end_angle: gradient.end_angle().to_f32(), - color_stops: color_line.into(), - extend, - } - } - Paint::VarSweepGradient(gradient) => { - let color_line = gradient.color_line()?; - let extend = color_line.extend(); - let deltas = instance.var_deltas::<4>(gradient.var_index_base()); - ResolvedPaint::SweepGradient { - center_x: gradient.center_x().apply_float_delta(deltas[0]), - center_y: gradient.center_y().apply_float_delta(deltas[1]), - start_angle: gradient.start_angle().apply_float_delta(deltas[2]), - end_angle: gradient.end_angle().apply_float_delta(deltas[3]), - color_stops: color_line.into(), - extend, - } - } - Paint::Glyph(glyph) => ResolvedPaint::Glyph { - glyph_id: glyph.glyph_id(), - paint: glyph.paint()?, - }, - Paint::ColrGlyph(glyph) => ResolvedPaint::ColrGlyph { - glyph_id: glyph.glyph_id(), - }, - Paint::Transform(transform) => { - let affine = transform.transform()?; - let paint = transform.paint()?; - ResolvedPaint::Transform { - xx: affine.xx().to_f32(), - yx: affine.yx().to_f32(), - xy: affine.xy().to_f32(), - yy: affine.yy().to_f32(), - dx: affine.dx().to_f32(), - dy: affine.dy().to_f32(), - paint, - } - } - Paint::VarTransform(transform) => { - let affine = transform.transform()?; - let paint = transform.paint()?; - let deltas = instance.var_deltas::<6>(affine.var_index_base()); - ResolvedPaint::Transform { - xx: affine.xx().apply_float_delta(deltas[0]), - yx: affine.yx().apply_float_delta(deltas[1]), - xy: affine.xy().apply_float_delta(deltas[2]), - yy: affine.yy().apply_float_delta(deltas[3]), - dx: affine.dx().apply_float_delta(deltas[4]), - dy: affine.dy().apply_float_delta(deltas[5]), - paint, - } - } - Paint::Translate(transform) => ResolvedPaint::Translate { - dx: transform.dx().to_i16() as f32, - dy: transform.dy().to_i16() as f32, - paint: transform.paint()?, - }, - Paint::VarTranslate(transform) => { - let deltas = instance.var_deltas::<2>(transform.var_index_base()); - ResolvedPaint::Translate { - dx: transform.dx().apply_float_delta(deltas[0]), - dy: transform.dy().apply_float_delta(deltas[1]), - paint: transform.paint()?, - } - } - Paint::Scale(transform) => ResolvedPaint::Scale { - scale_x: transform.scale_x().to_f32(), - scale_y: transform.scale_y().to_f32(), - around_center: None, - paint: transform.paint()?, - }, - Paint::VarScale(transform) => { - let deltas = instance.var_deltas::<2>(transform.var_index_base()); - ResolvedPaint::Scale { - scale_x: transform.scale_x().apply_float_delta(deltas[0]), - scale_y: transform.scale_y().apply_float_delta(deltas[1]), - around_center: None, - paint: transform.paint()?, - } - } - Paint::ScaleAroundCenter(transform) => ResolvedPaint::Scale { - scale_x: transform.scale_x().to_f32(), - scale_y: transform.scale_y().to_f32(), - around_center: Some(Point::new( - transform.center_x().to_i16() as f32, - transform.center_y().to_i16() as f32, - )), - paint: transform.paint()?, - }, - Paint::VarScaleAroundCenter(transform) => { - let deltas = instance.var_deltas::<4>(transform.var_index_base()); - ResolvedPaint::Scale { - scale_x: transform.scale_x().apply_float_delta(deltas[0]), - scale_y: transform.scale_y().apply_float_delta(deltas[1]), - around_center: Some(Point::new( - transform.center_x().apply_float_delta(deltas[2]), - transform.center_y().apply_float_delta(deltas[3]), - )), - paint: transform.paint()?, - } - } - Paint::ScaleUniform(transform) => { - let scale = transform.scale().to_f32(); - ResolvedPaint::Scale { - scale_x: scale, - scale_y: scale, - around_center: None, - paint: transform.paint()?, - } - } - Paint::VarScaleUniform(transform) => { - let deltas = instance.var_deltas::<1>(transform.var_index_base()); - let scale = transform.scale().apply_float_delta(deltas[0]); - ResolvedPaint::Scale { - scale_x: scale, - scale_y: scale, - around_center: None, - paint: transform.paint()?, - } - } - Paint::ScaleUniformAroundCenter(transform) => { - let scale = transform.scale().to_f32(); - ResolvedPaint::Scale { - scale_x: scale, - scale_y: scale, - around_center: Some(Point::new( - transform.center_x().to_i16() as f32, - transform.center_y().to_i16() as f32, - )), - paint: transform.paint()?, - } - } - Paint::VarScaleUniformAroundCenter(transform) => { - let deltas = instance.var_deltas::<3>(transform.var_index_base()); - let scale = transform.scale().apply_float_delta(deltas[0]); - ResolvedPaint::Scale { - scale_x: scale, - scale_y: scale, - around_center: Some(Point::new( - transform.center_x().apply_float_delta(deltas[1]), - transform.center_y().apply_float_delta(deltas[2]), - )), - paint: transform.paint()?, - } - } - Paint::Rotate(transform) => ResolvedPaint::Rotate { - angle: transform.angle().to_f32(), - around_center: None, - paint: transform.paint()?, - }, - Paint::VarRotate(transform) => { - let deltas = instance.var_deltas::<1>(transform.var_index_base()); - ResolvedPaint::Rotate { - angle: transform.angle().apply_float_delta(deltas[0]), - around_center: None, - paint: transform.paint()?, - } - } - Paint::RotateAroundCenter(transform) => ResolvedPaint::Rotate { - angle: transform.angle().to_f32(), - around_center: Some(Point::new( - transform.center_x().to_i16() as f32, - transform.center_y().to_i16() as f32, - )), - paint: transform.paint()?, - }, - Paint::VarRotateAroundCenter(transform) => { - let deltas = instance.var_deltas::<3>(transform.var_index_base()); - ResolvedPaint::Rotate { - angle: transform.angle().apply_float_delta(deltas[0]), - around_center: Some(Point::new( - transform.center_x().apply_float_delta(deltas[1]), - transform.center_y().apply_float_delta(deltas[2]), - )), - paint: transform.paint()?, - } - } - Paint::Skew(transform) => ResolvedPaint::Skew { - x_skew_angle: transform.x_skew_angle().to_f32(), - y_skew_angle: transform.y_skew_angle().to_f32(), - around_center: None, - paint: transform.paint()?, - }, - Paint::VarSkew(transform) => { - let deltas = instance.var_deltas::<2>(transform.var_index_base()); - ResolvedPaint::Skew { - x_skew_angle: transform.x_skew_angle().apply_float_delta(deltas[0]), - y_skew_angle: transform.y_skew_angle().apply_float_delta(deltas[1]), - around_center: None, - paint: transform.paint()?, - } - } - Paint::SkewAroundCenter(transform) => ResolvedPaint::Skew { - x_skew_angle: transform.x_skew_angle().to_f32(), - y_skew_angle: transform.y_skew_angle().to_f32(), - around_center: Some(Point::new( - transform.center_x().to_i16() as f32, - transform.center_y().to_i16() as f32, - )), - paint: transform.paint()?, - }, - Paint::VarSkewAroundCenter(transform) => { - let deltas = instance.var_deltas::<4>(transform.var_index_base()); - ResolvedPaint::Skew { - x_skew_angle: transform.x_skew_angle().apply_float_delta(deltas[0]), - y_skew_angle: transform.y_skew_angle().apply_float_delta(deltas[1]), - around_center: Some(Point::new( - transform.center_x().apply_float_delta(deltas[2]), - transform.center_y().apply_float_delta(deltas[3]), - )), - paint: transform.paint()?, - } - } - Paint::Composite(composite) => ResolvedPaint::Composite { - source_paint: composite.source_paint()?, - mode: composite.composite_mode(), - backdrop_paint: composite.backdrop_paint()?, - }, - }) -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,535 +0,0 @@ -//! Drawing color glyphs. -//! -//! # Examples -//! ## Retrieve the clip box of a COLRv1 glyph if it has one: -//! -//! ``` -//! # use core::result::Result; -//! # use skrifa::{instance::{Size, Location}, color::{ColorGlyphFormat, ColorPainter, PaintError}, GlyphId, MetadataProvider}; -//! # fn get_colr_bb(font: read_fonts::FontRef, color_painter_impl : &mut impl ColorPainter, glyph_id : GlyphId, size: Size) -> Result<(), PaintError> { -//! match font.color_glyphs() -//! .get_with_format(glyph_id, ColorGlyphFormat::ColrV1) -//! .expect("Glyph not found.") -//! .bounding_box(&Location::default(), size) -//! { -//! Some(bounding_box) => { -//! println!("Bounding box is {:?}", bounding_box); -//! } -//! None => { -//! println!("Glyph has no clip box."); -//! } -//! } -//! # Ok(()) -//! # } -//! ``` -//! -//! ## Paint a COLRv1 glyph given a font, and a glyph id and a [`ColorPainter`] implementation: -//! ``` -//! # use core::result::Result; -//! # use skrifa::{instance::{Size, Location}, color::{ColorGlyphFormat, ColorPainter, PaintError}, GlyphId, MetadataProvider}; -//! # fn paint_colr(font: read_fonts::FontRef, color_painter_impl : &mut impl ColorPainter, glyph_id : GlyphId) -> Result<(), PaintError> { -//! let color_glyph = font.color_glyphs() -//! .get_with_format(glyph_id, ColorGlyphFormat::ColrV1) -//! .expect("Glyph not found"); -//! color_glyph.paint(&Location::default(), color_painter_impl) -//! # } -//! ``` -//! -mod instance; -mod transform; -mod traversal; - -#[cfg(test)] -mod traversal_tests; - -use raw::tables::colr; -#[cfg(test)] -use serde::{Deserialize, Serialize}; - -pub use read_fonts::tables::colr::{CompositeMode, Extend}; - -use read_fonts::{ - types::{BoundingBox, GlyphId, Point}, - ReadError, TableProvider, -}; - -use std::{fmt::Debug, ops::Range}; - -use traversal::{get_clipbox_font_units, traverse_v0_range, traverse_with_callbacks, VisitedSet}; - -pub use transform::Transform; - -use crate::prelude::{LocationRef, Size}; - -use self::instance::{resolve_paint, PaintId}; - -/// An error during drawing a COLR glyph. -/// -/// This covers inconsistencies in the COLRv1 paint graph as well as downstream -/// parse errors from read-fonts. -#[derive(Debug, Clone)] -pub enum PaintError { - ParseError(ReadError), - GlyphNotFound(GlyphId), - PaintCycleDetected, - DepthLimitExceeded, -} - -impl std::fmt::Display for PaintError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - PaintError::ParseError(read_error) => { - write!(f, "Error parsing font data: {read_error}") - } - PaintError::GlyphNotFound(glyph_id) => { - write!(f, "No COLRv1 glyph found for glyph id: {glyph_id}") - } - PaintError::PaintCycleDetected => write!(f, "Paint cycle detected in COLRv1 glyph."), - PaintError::DepthLimitExceeded => write!(f, "Depth limit exceeded in COLRv1 glyph."), - } - } -} - -impl From for PaintError { - fn from(value: ReadError) -> Self { - PaintError::ParseError(value) - } -} - -/// A color stop of a gradient. -/// -/// All gradient callbacks of [`ColorPainter`] normalize color stops to be in the range of 0 -/// to 1. -#[derive(Clone, PartialEq, Debug, Default)] -#[cfg_attr(test, derive(Serialize, Deserialize))] -// This repr(C) is required so that C-side FFI's -// are able to cast the ColorStop slice to a C-side array pointer. -#[repr(C)] -pub struct ColorStop { - pub offset: f32, - /// Specifies a color from the `CPAL` table. - pub palette_index: u16, - /// Additional alpha value, to be multiplied with the color above before use. - pub alpha: f32, -} - -// Design considerations for choosing a slice of ColorStops as `color_stop` -// type: In principle, a local `Vec` allocation would not required if -// we're willing to walk the `ResolvedColorStop` iterator to find the minimum -// and maximum color stops. Then we could scale the color stops based on the -// minimum and maximum. But performing the min/max search would require -// re-applying the deltas at least once, after which we would pass the scaled -// stops to client side and have the client sort the collected items once -// again. If we do want to pre-ort them, and still use use an -// `Iterator` instead as the `color_stops` field, then we would -// need a Fontations-side allocations to sort, and an extra allocation on the -// client side to `.collect()` from the provided iterator before passing it to -// drawing API. -// -/// A fill type of a COLRv1 glyph (solid fill or various gradient types). -/// -/// The client receives the information about the fill type in the -/// [`fill`](ColorPainter::fill) callback of the [`ColorPainter`] trait. -#[derive(Debug, PartialEq)] -pub enum Brush<'a> { - /// A solid fill with the color specified by `palette_index`. The respective - /// color from the CPAL table then needs to be multiplied with `alpha`. - Solid { palette_index: u16, alpha: f32 }, - /// A linear gradient, normalized from the P0, P1 and P2 representation in - /// the COLRv1 table to a linear gradient between two points `p0` and - /// `p1`. If there is only one color stop, the client should draw a solid - /// fill with that color. The `color_stops` are normalized to the range from - /// 0 to 1. - LinearGradient { - p0: Point, - p1: Point, - color_stops: &'a [ColorStop], - extend: Extend, - }, - /// A radial gradient, with color stops normalized to the range of 0 to 1. - /// Caution: This normalization can mean that negative radii occur. It is - /// the client's responsibility to truncate the color line at the 0 - /// position, interpolating between `r0` and `r1` and compute an - /// interpolated color at that position. - RadialGradient { - c0: Point, - r0: f32, - c1: Point, - r1: f32, - color_stops: &'a [ColorStop], - extend: Extend, - }, - /// A sweep gradient, also called conical gradient. The color stops are - /// normalized to the range from 0 to 1 and the returned angles are to be - /// interpreted in _clockwise_ direction (swapped from the meaning in the - /// font file). The stop normalization may mean that the angles may be - /// larger or smaller than the range of 0 to 360. Note that only the range - /// from 0 to 360 degrees is to be drawn, see - /// . - SweepGradient { - c0: Point, - start_angle: f32, - end_angle: f32, - color_stops: &'a [ColorStop], - extend: Extend, - }, -} - -/// Signals success of request to draw a COLRv1 sub glyph from cache. -/// -/// Result of [`paint_cached_color_glyph`](ColorPainter::paint_cached_color_glyph) -/// through which the client signals whether a COLRv1 glyph referenced by -/// another COLRv1 glyph was drawn from cache or whether the glyph's subgraph -/// should be traversed by the skria side COLRv1 implementation. -pub enum PaintCachedColorGlyph { - /// The specified COLRv1 glyph has been successfully painted client side. - Ok, - /// The client does not implement drawing COLRv1 glyphs from cache and the - /// Fontations side COLRv1 implementation is asked to traverse the - /// respective PaintColorGlyph sub graph. - Unimplemented, -} - -/// A group of required painting callbacks to be provided by the client. -/// -/// Each callback is executing a particular drawing or canvas transformation -/// operation. The trait's callback functions are invoked when -/// [`paint`](ColorGlyph::paint) is called with a [`ColorPainter`] trait -/// object. The documentation for each function describes what actions are to be -/// executed using the client side 2D graphics API, usually by performing some -/// kind of canvas operation. -pub trait ColorPainter { - /// Push the specified transform by concatenating it to the current - /// transformation matrix. - fn push_transform(&mut self, transform: Transform); - - /// Restore the transformation matrix to the state before the previous - /// [`push_transform`](ColorPainter::push_transform) call. - fn pop_transform(&mut self); - - /// Apply a clip path in the shape of glyph specified by `glyph_id`. - fn push_clip_glyph(&mut self, glyph_id: GlyphId); - - /// Apply a clip rectangle specified by `clip_rect`. - fn push_clip_box(&mut self, clip_box: BoundingBox); - - /// Restore the clip state to the state before a previous - /// [`push_clip_glyph`](ColorPainter::push_clip_glyph) or - /// [`push_clip_box`](ColorPainter::push_clip_box) call. - fn pop_clip(&mut self); - - /// Fill the current clip area with the specified gradient fill. - fn fill(&mut self, brush: Brush<'_>); - - /// Combined clip and fill operation. - /// - /// Apply the clip path determined by the specified `glyph_id`, then fill it - /// with the specified [`brush`](Brush), applying the `_brush_transform` - /// transformation matrix to the brush. The default implementation works - /// based on existing methods in this trait. It is recommended for clients - /// to override the default implementaition with a custom combined clip and - /// fill operation. In this way overriding likely results in performance - /// gains depending on performance characteristics of the 2D graphics stack - /// that these calls are mapped to. - fn fill_glyph( - &mut self, - glyph_id: GlyphId, - brush_transform: Option, - brush: Brush<'_>, - ) { - self.push_clip_glyph(glyph_id); - if let Some(wrap_in_transform) = brush_transform { - self.push_transform(wrap_in_transform); - self.fill(brush); - self.pop_transform(); - } else { - self.fill(brush); - } - self.pop_clip(); - } - - /// Optionally implement this method: Draw an unscaled COLRv1 glyph given - /// the current transformation matrix (as accumulated by - /// [`push_transform`](ColorPainter::push_transform) calls). - fn paint_cached_color_glyph( - &mut self, - _glyph: GlyphId, - ) -> Result { - Ok(PaintCachedColorGlyph::Unimplemented) - } - - /// Open a new layer, and merge the layer down using `composite_mode` when - /// [`pop_layer`](ColorPainter::pop_layer) is called, signalling that this layer is done drawing. - fn push_layer(&mut self, composite_mode: CompositeMode); - fn pop_layer(&mut self); -} - -/// Distinguishes available color glyph formats. -#[derive(Clone, Copy)] -pub enum ColorGlyphFormat { - ColrV0, - ColrV1, -} - -/// A representation of a color glyph that can be painted through a sequence of [`ColorPainter`] callbacks. -#[derive(Clone)] -pub struct ColorGlyph<'a> { - colr: colr::Colr<'a>, - root_paint_ref: ColorGlyphRoot<'a>, -} - -#[derive(Clone)] -enum ColorGlyphRoot<'a> { - V0Range(Range), - V1Paint(colr::Paint<'a>, PaintId, GlyphId, Result), -} - -impl<'a> ColorGlyph<'a> { - /// Returns the version of the color table from which this outline was - /// selected. - pub fn format(&self) -> ColorGlyphFormat { - match &self.root_paint_ref { - ColorGlyphRoot::V0Range(_) => ColorGlyphFormat::ColrV0, - ColorGlyphRoot::V1Paint(..) => ColorGlyphFormat::ColrV1, - } - } - - /// Returns the bounding box. - /// - /// For COLRv1 glyphs, this is the clip box of the specified COLRv1 glyph, - /// or `None` if clip boxes are not present or if there is none for the - /// particular glyph. - /// - /// Always returns `None` for COLRv0 glyphs because precomputed clip boxes - /// are never available. - /// - /// The `size` argument can optionally be used to scale the bounding box - /// to a particular font size and `location` allows specifying a variation - /// instance. - pub fn bounding_box( - &self, - location: impl Into>, - size: Size, - ) -> Option> { - match &self.root_paint_ref { - ColorGlyphRoot::V1Paint(_paint, _paint_id, glyph_id, upem) => { - let instance = - instance::ColrInstance::new(self.colr.clone(), location.into().coords()); - let resolved_bounding_box = get_clipbox_font_units(&instance, *glyph_id); - resolved_bounding_box.map(|bounding_box| { - let scale_factor = size.linear_scale((*upem).clone().unwrap_or(0)); - bounding_box.scale(scale_factor) - }) - } - _ => None, - } - } - - /// Evaluates the paint graph at the specified location in variation space - /// and emits the results to the given painter. - /// - /// - /// For a COLRv1 glyph, traverses the COLRv1 paint graph and invokes drawing callbacks on a - /// specified [`ColorPainter`] trait object. The traversal operates in font - /// units and will call `ColorPainter` methods with font unit values. This - /// means, if you want to draw a COLRv1 glyph at a particular font size, the - /// canvas needs to have a transformation matrix applied so that it scales down - /// the drawing operations to `font_size / upem`. - /// - /// # Arguments - /// - /// * `glyph_id` the `GlyphId` to be drawn. - /// * `location` coordinates for specifying a variation instance. This can be empty. - /// * `painter` a client-provided [`ColorPainter`] implementation receiving drawing callbacks. - /// - pub fn paint( - &self, - location: impl Into>, - painter: &mut impl ColorPainter, - ) -> Result<(), PaintError> { - let instance = instance::ColrInstance::new(self.colr.clone(), location.into().coords()); - match &self.root_paint_ref { - ColorGlyphRoot::V1Paint(paint, paint_id, glyph_id, _) => { - let clipbox = get_clipbox_font_units(&instance, *glyph_id); - - if let Some(rect) = clipbox { - painter.push_clip_box(rect); - } - - let mut visited_set = VisitedSet::default(); - visited_set.insert(*paint_id); - traverse_with_callbacks( - &resolve_paint(&instance, paint)?, - &instance, - painter, - &mut visited_set, - 0, - )?; - - if clipbox.is_some() { - painter.pop_clip(); - } - Ok(()) - } - ColorGlyphRoot::V0Range(range) => { - traverse_v0_range(range, &instance, painter)?; - Ok(()) - } - } - } -} - -/// Collection of color glyphs. -#[derive(Clone)] -pub struct ColorGlyphCollection<'a> { - colr: Option>, - upem: Result, -} - -impl<'a> ColorGlyphCollection<'a> { - /// Creates a new collection of paintable color glyphs for the given font. - pub fn new(font: &impl TableProvider<'a>) -> Self { - let colr = font.colr().ok(); - let upem = font.head().map(|h| h.units_per_em()); - - Self { colr, upem } - } - - /// Returns the color glyph representation for the given glyph identifier, - /// given a specific format. - pub fn get_with_format( - &self, - glyph_id: GlyphId, - glyph_format: ColorGlyphFormat, - ) -> Option> { - let colr = self.colr.clone()?; - - let root_paint_ref = match glyph_format { - ColorGlyphFormat::ColrV0 => { - let layer_range = colr.v0_base_glyph(glyph_id).ok()??; - ColorGlyphRoot::V0Range(layer_range) - } - ColorGlyphFormat::ColrV1 => { - let (paint, paint_id) = colr.v1_base_glyph(glyph_id).ok()??; - ColorGlyphRoot::V1Paint(paint, paint_id, glyph_id, self.upem.clone()) - } - }; - Some(ColorGlyph { - colr, - root_paint_ref, - }) - } - - /// Returns a color glyph representation for the given glyph identifier if - /// available, preferring a COLRv1 representation over a COLRv0 - /// representation. - pub fn get(&self, glyph_id: GlyphId) -> Option> { - self.get_with_format(glyph_id, ColorGlyphFormat::ColrV1) - .or_else(|| self.get_with_format(glyph_id, ColorGlyphFormat::ColrV0)) - } -} - -#[cfg(test)] -mod tests { - - use crate::{ - color::traversal_tests::test_glyph_defs::PAINTCOLRGLYPH_CYCLE, - prelude::{LocationRef, Size}, - MetadataProvider, - }; - - use read_fonts::{types::BoundingBox, FontRef}; - - use super::{Brush, ColorPainter, CompositeMode, GlyphId, Transform}; - use crate::color::traversal_tests::test_glyph_defs::{COLORED_CIRCLES_V0, COLORED_CIRCLES_V1}; - - #[test] - fn has_colrv1_glyph_test() { - let colr_font = font_test_data::COLRV0V1_VARIABLE; - let font = FontRef::new(colr_font).unwrap(); - let get_colrv1_glyph = |codepoint: &[char]| { - font.charmap().map(codepoint[0]).and_then(|glyph_id| { - font.color_glyphs() - .get_with_format(glyph_id, crate::color::ColorGlyphFormat::ColrV1) - }) - }; - - assert!(get_colrv1_glyph(COLORED_CIRCLES_V0).is_none()); - assert!(get_colrv1_glyph(COLORED_CIRCLES_V1).is_some()); - } - struct DummyColorPainter {} - - impl DummyColorPainter { - pub fn new() -> Self { - Self {} - } - } - - impl Default for DummyColorPainter { - fn default() -> Self { - Self::new() - } - } - - impl ColorPainter for DummyColorPainter { - fn push_transform(&mut self, _transform: Transform) {} - fn pop_transform(&mut self) {} - fn push_clip_glyph(&mut self, _glyph: GlyphId) {} - fn push_clip_box(&mut self, _clip_box: BoundingBox) {} - fn pop_clip(&mut self) {} - fn fill(&mut self, _brush: Brush) {} - fn push_layer(&mut self, _composite_mode: CompositeMode) {} - fn pop_layer(&mut self) {} - } - - #[test] - fn paintcolrglyph_cycle_test() { - let colr_font = font_test_data::COLRV0V1_VARIABLE; - let font = FontRef::new(colr_font).unwrap(); - let cycle_glyph_id = font.charmap().map(PAINTCOLRGLYPH_CYCLE[0]).unwrap(); - let colrv1_glyph = font - .color_glyphs() - .get_with_format(cycle_glyph_id, crate::color::ColorGlyphFormat::ColrV1); - - assert!(colrv1_glyph.is_some()); - let mut color_painter = DummyColorPainter::new(); - - let result = colrv1_glyph - .unwrap() - .paint(LocationRef::default(), &mut color_painter); - // Expected to fail with an error as the glyph contains a paint cycle. - assert!(result.is_err()); - } - - #[test] - fn no_cliplist_test() { - let colr_font = font_test_data::COLRV1_NO_CLIPLIST; - let font = FontRef::new(colr_font).unwrap(); - let cycle_glyph_id = GlyphId::new(1); - let colrv1_glyph = font - .color_glyphs() - .get_with_format(cycle_glyph_id, crate::color::ColorGlyphFormat::ColrV1); - - assert!(colrv1_glyph.is_some()); - let mut color_painter = DummyColorPainter::new(); - - let result = colrv1_glyph - .unwrap() - .paint(LocationRef::default(), &mut color_painter); - assert!(result.is_ok()); - } - - #[test] - fn colrv0_no_bbox_test() { - let colr_font = font_test_data::COLRV0V1; - let font = FontRef::new(colr_font).unwrap(); - let colrv0_glyph_id = GlyphId::new(168); - let colrv0_glyph = font - .color_glyphs() - .get_with_format(colrv0_glyph_id, super::ColorGlyphFormat::ColrV0) - .unwrap(); - assert!(colrv0_glyph - .bounding_box(LocationRef::default(), Size::unscaled()) - .is_none()); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -//! Contains a [`Transform`] object holding values of an affine transformation matrix. -use std::ops::{Mul, MulAssign}; - -use read_fonts::ReadError; - -use super::instance::ResolvedPaint; - -#[cfg(feature = "libm")] -#[allow(unused_imports)] -use core_maths::*; - -#[cfg(test)] -use serde::{Deserialize, Serialize}; - -#[derive(Clone, Debug, PartialEq)] -#[cfg_attr(test, derive(Serialize, Deserialize))] -/// A transformation matrix to be applied to the drawing canvas. -/// -/// Factors are specified in column-order, meaning that -/// for a vector `(x,y)` the transformed position `x'` of the vector -/// is calculated by -/// `x' = xx * x + xy * y + dx`, -/// and the transformed position y' is calculated by -/// `y' = yx * x + yy * y + dy`. -#[derive(Copy)] -pub struct Transform { - pub xx: f32, - pub yx: f32, - pub xy: f32, - pub yy: f32, - pub dx: f32, - pub dy: f32, -} - -impl MulAssign for Transform { - fn mul_assign(&mut self, rhs: Self) { - *self = *self * rhs; - } -} - -impl Mul for Transform { - type Output = Self; - - fn mul(self, rhs: Self) -> Self::Output { - fn muladdmul(a: f32, b: f32, c: f32, d: f32) -> f32 { - a * b + c * d - } - Self { - xx: muladdmul(self.xx, rhs.xx, self.xy, rhs.yx), - xy: muladdmul(self.xx, rhs.xy, self.xy, rhs.yy), - dx: muladdmul(self.xx, rhs.dx, self.xy, rhs.dy) + self.dx, - yx: muladdmul(self.yx, rhs.xx, self.yy, rhs.yx), - yy: muladdmul(self.yx, rhs.xy, self.yy, rhs.yy), - dy: muladdmul(self.yx, rhs.dx, self.yy, rhs.dy) + self.dy, - } - } -} - -impl Default for Transform { - fn default() -> Self { - Transform { - xx: 1.0, - yx: 0.0, - xy: 0.0, - yy: 1.0, - dx: 0.0, - dy: 0.0, - } - } -} - -impl TryFrom<&ResolvedPaint<'_>> for Transform { - type Error = ReadError; - - fn try_from(paint: &ResolvedPaint<'_>) -> Result { - match paint { - ResolvedPaint::Rotate { - angle, - around_center, - .. - } => { - let sin_v = (angle * 180.0).to_radians().sin(); - let cos_v = (angle * 180.0).to_radians().cos(); - let mut out_transform = Transform { - xx: cos_v, - xy: -sin_v, - yx: sin_v, - yy: cos_v, - ..Default::default() - }; - - fn scalar_dot_product(a: f32, b: f32, c: f32, d: f32) -> f32 { - a * b + c * d - } - - if let Some(center) = around_center { - out_transform.dx = scalar_dot_product(sin_v, center.y, 1.0 - cos_v, center.x); - out_transform.dy = scalar_dot_product(-sin_v, center.x, 1.0 - cos_v, center.y); - } - Ok(out_transform) - } - ResolvedPaint::Scale { - scale_x, - scale_y, - around_center, - paint: _, - } => { - let mut out_transform = Transform { - xx: *scale_x, - yy: *scale_y, - ..Transform::default() - }; - - if let Some(center) = around_center { - out_transform.dx = center.x - scale_x * center.x; - out_transform.dy = center.y - scale_y * center.y; - } - Ok(out_transform) - } - ResolvedPaint::Skew { - x_skew_angle, - y_skew_angle, - around_center, - paint: _, - } => { - let tan_x = (x_skew_angle * 180.0).to_radians().tan(); - let tan_y = (y_skew_angle * 180.0).to_radians().tan(); - let mut out_transform = Transform { - xy: -tan_x, - yx: tan_y, - ..Transform::default() - }; - - if let Some(center) = around_center { - out_transform.dx = tan_x * center.y; - out_transform.dy = -tan_y * center.x; - } - Ok(out_transform) - } - ResolvedPaint::Transform { - xx, - yx, - xy, - yy, - dx, - dy, - paint: _, - } => Ok(Transform { - xx: *xx, - yx: *yx, - xy: *xy, - yy: *yy, - dx: *dx, - dy: *dy, - }), - ResolvedPaint::Translate { dx, dy, .. } => Ok(Transform { - dx: *dx, - dy: *dy, - ..Default::default() - }), - _ => Err(ReadError::MalformedData( - "ResolvedPaint cannot be converted into a transform.", - )), - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,753 +0,0 @@ -use std::{cmp::Ordering, ops::Range}; - -use read_fonts::{ - tables::colr::{CompositeMode, Extend}, - types::{BoundingBox, GlyphId, Point}, -}; - -use super::{ - instance::{ - resolve_clip_box, resolve_paint, ColorStops, ColrInstance, ResolvedColorStop, ResolvedPaint, - }, - Brush, ColorPainter, ColorStop, PaintCachedColorGlyph, PaintError, Transform, -}; - -use alloc::vec::Vec; - -#[cfg(feature = "libm")] -#[allow(unused_imports)] -use core_maths::*; - -#[cfg(any(test, feature = "std"))] -mod visited_set { - pub type VisitedSet = std::collections::HashSet; -} - -#[cfg(not(any(test, feature = "std")))] -mod visited_set { - /// A subset of the HashSet type that pretends every insertion is - /// new. - /// - /// This is used in `no_std` builds to represent a visited set that never - /// detects cycles. We rely only on a traversal depth check to avoid - /// infinite recursion instead. - #[derive(Default)] - pub struct VisitedSet {} - - impl VisitedSet { - /// Like HashSet, returns true if the value doesn't already exist in - /// the set. In our case, that's always. - pub fn insert(&mut self, _value: usize) -> bool { - true - } - - pub fn remove(&mut self, _value: &usize) {} - } -} - -pub use visited_set::VisitedSet; - -/// Depth at which we will stop traversing and return an error. -/// -/// Used to prevent stack overflows. Also allows us to avoid using a HashSet -/// in no_std builds. -/// -/// This limit matches the one used in HarfBuzz: -/// HB_MAX_NESTING_LEVEL: -/// hb_paint_context_t: -const MAX_TRAVERSAL_DEPTH: u32 = 64; - -pub(crate) fn get_clipbox_font_units( - colr_instance: &ColrInstance, - glyph_id: GlyphId, -) -> Option> { - let maybe_clipbox = (*colr_instance).v1_clip_box(glyph_id).ok().flatten()?; - Some(resolve_clip_box(colr_instance, &maybe_clipbox)) -} - -impl From for ColorStop { - fn from(resolved_stop: ResolvedColorStop) -> Self { - ColorStop { - offset: resolved_stop.offset, - alpha: resolved_stop.alpha, - palette_index: resolved_stop.palette_index, - } - } -} - -fn make_sorted_resolved_stops(stops: &ColorStops, instance: &ColrInstance) -> Vec { - let color_stop_iter = stops.resolve(instance).map(|stop| stop.into()); - let mut collected: Vec = color_stop_iter.collect(); - collected.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap_or(Ordering::Equal)); - collected -} - -struct CollectFillGlyphPainter<'a> { - brush_transform: Option, - glyph_id: GlyphId, - parent_painter: &'a mut dyn ColorPainter, - pub optimization_success: bool, -} - -impl<'a> CollectFillGlyphPainter<'a> { - fn new(parent_painter: &'a mut dyn ColorPainter, glyph_id: GlyphId) -> Self { - Self { - brush_transform: None, - glyph_id, - parent_painter, - optimization_success: true, - } - } -} - -impl ColorPainter for CollectFillGlyphPainter<'_> { - fn push_transform(&mut self, transform: Transform) { - if self.optimization_success { - match self.brush_transform { - None => { - self.brush_transform = Some(transform); - } - Some(ref mut existing_transform) => { - *existing_transform *= transform; - } - } - } - } - - fn pop_transform(&mut self) { - // Since we only support fill and and transform operations, we need to - // ignore a popped transform, as this would be called after traversing - // the graph backup after a fill was performed, but we want to preserve - // the transform in order to be able to return it. - } - - fn fill(&mut self, brush: Brush<'_>) { - if self.optimization_success { - self.parent_painter - .fill_glyph(self.glyph_id, self.brush_transform, brush); - } - } - - fn push_clip_glyph(&mut self, _: GlyphId) { - self.optimization_success = false; - } - - fn push_clip_box(&mut self, _: BoundingBox) { - self.optimization_success = false; - } - - fn pop_clip(&mut self) { - self.optimization_success = false; - } - - fn push_layer(&mut self, _: CompositeMode) { - self.optimization_success = false; - } - - fn pop_layer(&mut self) { - self.optimization_success = false; - } -} - -pub(crate) fn traverse_with_callbacks( - paint: &ResolvedPaint, - instance: &ColrInstance, - painter: &mut impl ColorPainter, - visited_set: &mut VisitedSet, - recurse_depth: u32, -) -> Result<(), PaintError> { - if recurse_depth >= MAX_TRAVERSAL_DEPTH { - return Err(PaintError::DepthLimitExceeded); - } - match paint { - ResolvedPaint::ColrLayers { range } => { - for layer_index in range.clone() { - // Perform cycle detection with paint id here, second part of the tuple. - let (layer_paint, paint_id) = (*instance).v1_layer(layer_index)?; - if !visited_set.insert(paint_id) { - return Err(PaintError::PaintCycleDetected); - } - traverse_with_callbacks( - &resolve_paint(instance, &layer_paint)?, - instance, - painter, - visited_set, - recurse_depth + 1, - )?; - visited_set.remove(&paint_id); - } - Ok(()) - } - ResolvedPaint::Solid { - palette_index, - alpha, - } => { - painter.fill(Brush::Solid { - palette_index: *palette_index, - alpha: *alpha, - }); - Ok(()) - } - ResolvedPaint::LinearGradient { - x0, - y0, - x1, - y1, - x2, - y2, - color_stops, - extend, - } => { - let mut p0 = Point::new(*x0, *y0); - let p1 = Point::new(*x1, *y1); - let p2 = Point::new(*x2, *y2); - - let dot_product = |a: Point, b: Point| -> f32 { a.x * b.x + a.y * b.y }; - let cross_product = |a: Point, b: Point| -> f32 { a.x * b.y - a.y * b.x }; - let project_onto = |vector: Point, point: Point| -> Point { - let length = (point.x * point.x + point.y * point.y).sqrt(); - if length == 0.0 { - return Point::default(); - } - let mut point_normalized = point / length; - point_normalized *= dot_product(vector, point) / length; - point_normalized - }; - - let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); - - // If p0p1 or p0p2 are degenerate probably nothing should be drawn. - // If p0p1 and p0p2 are parallel then one side is the first color and the other side is - // the last color, depending on the direction. - // For now, just use the first color. - if p1 == p0 || p2 == p0 || cross_product(p1 - p0, p2 - p0) == 0.0 { - if let Some(stop) = resolved_stops.first() { - painter.fill(Brush::Solid { - palette_index: stop.palette_index, - alpha: stop.alpha, - }); - }; - return Ok(()); - } - - // Follow implementation note in nanoemoji: - // https://github.com/googlefonts/nanoemoji/blob/0ac6e7bb4d8202db692574d8530a9b643f1b3b3c/src/nanoemoji/svg.py#L188 - // to compute a new gradient end point P3 as the orthogonal - // projection of the vector from p0 to p1 onto a line perpendicular - // to line p0p2 and passing through p0. - let mut perpendicular_to_p2 = p2 - p0; - perpendicular_to_p2 = Point::new(perpendicular_to_p2.y, -perpendicular_to_p2.x); - let mut p3 = p0 + project_onto(p1 - p0, perpendicular_to_p2); - - match ( - resolved_stops.first().cloned(), - resolved_stops.last().cloned(), - ) { - (None, _) | (_, None) => {} - (Some(first_stop), Some(last_stop)) => { - let mut color_stop_range = last_stop.offset - first_stop.offset; - - // Nothing can be drawn for this situation. - if color_stop_range == 0.0 && extend != &Extend::Pad { - return Ok(()); - } - - // In the Pad case, for providing normalized stops in the 0 to 1 range to the client, - // insert a color stop at the end. Adding this stop will paint the equivalent gradient, - // because: All font-specified color stops are in the same spot, mode is pad, so - // everything before this spot is painted with the first color, everything after this spot - // is painted with the last color. Not adding this stop would skip the projection below along - // the p0-p3 axis and result in specifying non-normalized color stops to the shader. - - if color_stop_range == 0.0 && extend == &Extend::Pad { - let mut extra_stop = last_stop.clone(); - extra_stop.offset += 1.0; - resolved_stops.push(extra_stop); - - color_stop_range = 1.0; - } - - debug_assert!(color_stop_range != 0.0); - - if color_stop_range != 1.0 || first_stop.offset != 0.0 { - let p0_p3 = p3 - p0; - let p0_offset = p0_p3 * first_stop.offset; - let p3_offset = p0_p3 * last_stop.offset; - - p3 = p0 + p3_offset; - p0 += p0_offset; - - let scale_factor = 1.0 / color_stop_range; - let start_offset = first_stop.offset; - - for stop in &mut resolved_stops { - stop.offset = (stop.offset - start_offset) * scale_factor; - } - } - - painter.fill(Brush::LinearGradient { - p0, - p1: p3, - color_stops: resolved_stops.as_slice(), - extend: *extend, - }); - } - } - - Ok(()) - } - ResolvedPaint::RadialGradient { - x0, - y0, - radius0, - x1, - y1, - radius1, - color_stops, - extend, - } => { - let mut c0 = Point::new(*x0, *y0); - let mut c1 = Point::new(*x1, *y1); - let mut radius0 = *radius0; - let mut radius1 = *radius1; - - let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); - - match ( - resolved_stops.first().cloned(), - resolved_stops.last().cloned(), - ) { - (None, _) | (_, None) => {} - (Some(first_stop), Some(last_stop)) => { - let mut color_stop_range = last_stop.offset - first_stop.offset; - // Nothing can be drawn for this situation. - if color_stop_range == 0.0 && extend != &Extend::Pad { - return Ok(()); - } - - // In the Pad case, for providing normalized stops in the 0 to 1 range to the client, - // insert a color stop at the end. See LinearGradient for more details. - - if color_stop_range == 0.0 && extend == &Extend::Pad { - let mut extra_stop = last_stop.clone(); - extra_stop.offset += 1.0; - resolved_stops.push(extra_stop); - color_stop_range = 1.0; - } - - debug_assert!(color_stop_range != 0.0); - - // If the colorStopRange is 0 at this point, the default behavior of the shader is to - // clamp to 1 color stops that are above 1, clamp to 0 for color stops that are below 0, - // and repeat the outer color stops at 0 and 1 if the color stops are inside the - // range. That will result in the correct rendering. - if color_stop_range != 1.0 || first_stop.offset != 0.0 { - let c0_to_c1 = c1 - c0; - let radius_diff = radius1 - radius0; - let scale_factor = 1.0 / color_stop_range; - - let c0_offset = c0_to_c1 * first_stop.offset; - let c1_offset = c0_to_c1 * last_stop.offset; - let stops_start_offset = first_stop.offset; - - // Order of reassignments is important to avoid shadowing variables. - c1 = c0 + c1_offset; - c0 += c0_offset; - radius1 = radius0 + radius_diff * last_stop.offset; - radius0 += radius_diff * first_stop.offset; - - for stop in &mut resolved_stops { - stop.offset = (stop.offset - stops_start_offset) * scale_factor; - } - } - - painter.fill(Brush::RadialGradient { - c0, - r0: radius0, - c1, - r1: radius1, - color_stops: resolved_stops.as_slice(), - extend: *extend, - }); - } - } - Ok(()) - } - ResolvedPaint::SweepGradient { - center_x, - center_y, - start_angle, - end_angle, - color_stops, - extend, - } => { - // OpenType 1.9.1 adds a shift to the angle to ease specification of a 0 to 360 - // degree sweep. - let sweep_angle_to_degrees = |angle| angle * 180.0 + 180.0; - - let start_angle = sweep_angle_to_degrees(start_angle); - let end_angle = sweep_angle_to_degrees(end_angle); - - // Stop normalization for sweep: - - let sector_angle = end_angle - start_angle; - - let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); - if resolved_stops.is_empty() { - return Ok(()); - } - - match ( - resolved_stops.first().cloned(), - resolved_stops.last().cloned(), - ) { - (None, _) | (_, None) => {} - (Some(first_stop), Some(last_stop)) => { - let mut color_stop_range = last_stop.offset - first_stop.offset; - - let mut start_angle_scaled = start_angle + sector_angle * first_stop.offset; - let mut end_angle_scaled = start_angle + sector_angle * last_stop.offset; - - let start_offset = first_stop.offset; - - // Nothing can be drawn for this situation. - if color_stop_range == 0.0 && extend != &Extend::Pad { - return Ok(()); - } - - // In the Pad case, if the color_stop_range is 0 insert a color stop at the end before - // normalizing. Adding this stop will paint the equivalent gradient, because: All font - // specified color stops are in the same spot, mode is pad, so everything before this - // spot is painted with the first color, everything after this spot is painted with - // the last color. Not adding this stop will skip the projection and result in - // specifying non-normalized color stops to the shader. - if color_stop_range == 0.0 && extend == &Extend::Pad { - let mut offset_last = last_stop.clone(); - offset_last.offset += 1.0; - resolved_stops.push(offset_last); - color_stop_range = 1.0; - } - - debug_assert!(color_stop_range != 0.0); - - let scale_factor = 1.0 / color_stop_range; - - for shift_stop in &mut resolved_stops { - shift_stop.offset = (shift_stop.offset - start_offset) * scale_factor; - } - - // /* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients - // * "The angles are expressed in counter-clockwise degrees from - // * the direction of the positive x-axis on the design - // * grid. [...] The color line progresses from the start angle - // * to the end angle in the counter-clockwise direction;" - - // * Convert angles and stops from counter-clockwise to clockwise - // * for the shader if the gradient is not already reversed due to - // * start angle being larger than end angle. */ - start_angle_scaled = 360.0 - start_angle_scaled; - end_angle_scaled = 360.0 - end_angle_scaled; - - if start_angle_scaled >= end_angle_scaled { - (start_angle_scaled, end_angle_scaled) = - (end_angle_scaled, start_angle_scaled); - resolved_stops.reverse(); - for stop in &mut resolved_stops { - stop.offset = 1.0 - stop.offset; - } - } - - // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients - // "If the color line's extend mode is reflect or repeat - // and start and end angle are equal, nothing shall be drawn." - if start_angle_scaled == end_angle_scaled && extend != &Extend::Pad { - return Ok(()); - } - - painter.fill(Brush::SweepGradient { - c0: Point::new(*center_x, *center_y), - start_angle: start_angle_scaled, - end_angle: end_angle_scaled, - color_stops: resolved_stops.as_slice(), - extend: *extend, - }); - } - } - Ok(()) - } - - ResolvedPaint::Glyph { glyph_id, paint } => { - let glyph_id = (*glyph_id).into(); - let mut optimizer = CollectFillGlyphPainter::new(painter, glyph_id); - let mut result = traverse_with_callbacks( - &resolve_paint(instance, paint)?, - instance, - &mut optimizer, - visited_set, - recurse_depth + 1, - ); - - // In case the optimization was not successful, just push a clip, and continue unoptimized traversal. - if !optimizer.optimization_success { - painter.push_clip_glyph(glyph_id); - result = traverse_with_callbacks( - &resolve_paint(instance, paint)?, - instance, - painter, - visited_set, - recurse_depth + 1, - ); - painter.pop_clip(); - } - - result - } - ResolvedPaint::ColrGlyph { glyph_id } => { - let glyph_id = (*glyph_id).into(); - match (*instance).v1_base_glyph(glyph_id)? { - Some((base_glyph, base_glyph_paint_id)) => { - if !visited_set.insert(base_glyph_paint_id) { - return Err(PaintError::PaintCycleDetected); - } - - let draw_result = painter.paint_cached_color_glyph(glyph_id)?; - let result = match draw_result { - PaintCachedColorGlyph::Ok => Ok(()), - PaintCachedColorGlyph::Unimplemented => { - let clipbox = get_clipbox_font_units(instance, glyph_id); - - if let Some(rect) = clipbox { - painter.push_clip_box(rect); - } - - let result = traverse_with_callbacks( - &resolve_paint(instance, &base_glyph)?, - instance, - painter, - visited_set, - recurse_depth + 1, - ); - if clipbox.is_some() { - painter.pop_clip(); - } - result - } - }; - visited_set.remove(&base_glyph_paint_id); - result - } - None => Err(PaintError::GlyphNotFound(glyph_id)), - } - } - ResolvedPaint::Transform { - paint: next_paint, .. - } - | ResolvedPaint::Translate { - paint: next_paint, .. - } - | ResolvedPaint::Scale { - paint: next_paint, .. - } - | ResolvedPaint::Rotate { - paint: next_paint, .. - } - | ResolvedPaint::Skew { - paint: next_paint, .. - } => { - painter.push_transform(paint.try_into()?); - let result = traverse_with_callbacks( - &resolve_paint(instance, next_paint)?, - instance, - painter, - visited_set, - recurse_depth + 1, - ); - painter.pop_transform(); - result - } - ResolvedPaint::Composite { - source_paint, - mode, - backdrop_paint, - } => { - painter.push_layer(CompositeMode::SrcOver); - let mut result = traverse_with_callbacks( - &resolve_paint(instance, backdrop_paint)?, - instance, - painter, - visited_set, - recurse_depth + 1, - ); - result?; - painter.push_layer(*mode); - result = traverse_with_callbacks( - &resolve_paint(instance, source_paint)?, - instance, - painter, - visited_set, - recurse_depth + 1, - ); - painter.pop_layer(); - painter.pop_layer(); - result - } - } -} - -pub(crate) fn traverse_v0_range( - range: &Range, - instance: &ColrInstance, - painter: &mut impl ColorPainter, -) -> Result<(), PaintError> { - for layer_index in range.clone() { - let (layer_glyph, palette_index) = (*instance).v0_layer(layer_index)?; - painter.fill_glyph( - layer_glyph.into(), - None, - Brush::Solid { - palette_index, - alpha: 1.0, - }, - ); - } - Ok(()) -} - -#[cfg(test)] -mod tests { - use raw::types::GlyphId; - use read_fonts::{types::BoundingBox, FontRef, TableProvider}; - - use crate::{ - color::{ - instance::ColrInstance, traversal::get_clipbox_font_units, - traversal_tests::test_glyph_defs::CLIPBOX, Brush, ColorGlyphFormat, ColorPainter, - CompositeMode, Transform, - }, - prelude::LocationRef, - MetadataProvider, - }; - - #[test] - fn clipbox_test() { - let colr_font = font_test_data::COLRV0V1_VARIABLE; - let font = FontRef::new(colr_font).unwrap(); - let test_glyph_id = font.charmap().map(CLIPBOX[0]).unwrap(); - let upem = font.head().unwrap().units_per_em(); - - let base_bounding_box = BoundingBox { - x_min: 0.0, - x_max: upem as f32 / 2.0, - y_min: upem as f32 / 2.0, - y_max: upem as f32, - }; - // Fractional value needed to match variation scaling of clipbox. - const CLIPBOX_SHIFT: f32 = 200.0122; - - macro_rules! test_entry { - ($axis:literal, $shift:expr, $field:ident) => { - ( - $axis, - $shift, - BoundingBox { - $field: base_bounding_box.$field + ($shift), - ..base_bounding_box - }, - ) - }; - } - - let test_data_expectations = [ - ("", 0.0, base_bounding_box), - test_entry!("CLXI", CLIPBOX_SHIFT, x_min), - test_entry!("CLXA", -CLIPBOX_SHIFT, x_max), - test_entry!("CLYI", CLIPBOX_SHIFT, y_min), - test_entry!("CLYA", -CLIPBOX_SHIFT, y_max), - ]; - - for axis_test in test_data_expectations { - let axis_coordinate = (axis_test.0, axis_test.1); - let location = font.axes().location([axis_coordinate]); - let color_instance = ColrInstance::new(font.colr().unwrap(), location.coords()); - let clip_box = get_clipbox_font_units(&color_instance, test_glyph_id); - assert!(clip_box.is_some()); - assert!( - clip_box.unwrap() == axis_test.2, - "Clip boxes do not match. Actual: {:?}, expected: {:?}", - clip_box.unwrap(), - axis_test.2 - ); - } - } - - struct NopPainter; - - impl ColorPainter for NopPainter { - fn push_transform(&mut self, _transform: Transform) { - // nop - } - - fn pop_transform(&mut self) { - // nop - } - - fn push_clip_glyph(&mut self, _glyph_id: GlyphId) { - // nop - } - - fn push_clip_box(&mut self, _clip_box: BoundingBox) { - // nop - } - - fn pop_clip(&mut self) { - // nop - } - - fn fill(&mut self, _brush: Brush<'_>) { - // nop - } - - fn push_layer(&mut self, _composite_mode: CompositeMode) { - // nop - } - - fn pop_layer(&mut self) { - // nop - } - } - - #[test] - fn no_panic_on_empty_colorline() { - // Minimized test case from . - let test_case = &[ - 0, 1, 0, 0, 0, 3, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, - 32, 32, 32, 32, 32, 67, 79, 76, 82, 32, 32, 32, 32, 0, 0, 0, 229, 0, 0, 0, 178, 99, - 109, 97, 112, 32, 32, 32, 32, 0, 0, 0, 10, 0, 0, 1, 32, 32, 32, 32, 255, 32, 32, 32, 0, - 4, 32, 255, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 32, 0, 0, - 32, 32, 0, 0, 0, 57, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 4, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 0, 0, 0, 1, 32, 32, 32, 32, 32, 32, 255, 0, 0, 0, 40, 32, 32, 32, 32, 32, 32, - 32, 255, 255, 32, 32, 32, 4, 0, 0, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 32, 32, 32, 255, 255, - 255, 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - ]; - - let font = FontRef::new(test_case).unwrap(); - font.cmap().unwrap(); - font.colr().unwrap(); - - let color_glyph = font - .color_glyphs() - .get_with_format(GlyphId::new(8447), ColorGlyphFormat::ColrV1) - .unwrap(); - let _ = color_glyph.paint(LocationRef::default(), &mut NopPainter); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,403 +0,0 @@ -#[cfg(test)] -pub mod test_glyph_defs; - -use read_fonts::{ - tables::colr::{CompositeMode, Extend}, - types::{BoundingBox, GlyphId, Point}, - FontRef, -}; -use serde::{Deserialize, Serialize}; - -use std::{ - env, - fs::OpenOptions, - io::{self, BufRead, Write}, - string::String, -}; - -use crate::{ - alloc::vec::Vec, - color::{ - transform::Transform, traversal_tests::test_glyph_defs::*, Brush, ColorPainter, ColorStop, - }, - setting::VariationSetting, - MetadataProvider, -}; - -#[derive(Serialize, Deserialize, Default, PartialEq)] -struct PaintDump { - glyph_id: u32, - ops: Vec, -} - -impl From> for BrushParams { - fn from(brush: Brush) -> Self { - match brush { - Brush::Solid { - palette_index, - alpha, - } => BrushParams::Solid { - palette_index, - alpha, - }, - Brush::LinearGradient { - p0, - p1, - color_stops, - extend, - } => BrushParams::LinearGradient { - p0, - p1, - color_stops: color_stops.to_vec(), - extend, - }, - Brush::RadialGradient { - c0, - r0, - c1, - r1, - color_stops, - extend, - } => BrushParams::RadialGradient { - c0, - r0, - c1, - r1, - color_stops: color_stops.to_vec(), - extend, - }, - Brush::SweepGradient { - c0, - start_angle, - end_angle, - color_stops, - extend, - } => BrushParams::SweepGradient { - c0, - start_angle, - end_angle, - color_stops: color_stops.to_vec(), - extend, - }, - } - } -} - -// Needed as a mirror struct with owned ColorStops for serialization, deserialization. -#[derive(Serialize, Deserialize, PartialEq)] -pub enum BrushParams { - Solid { - palette_index: u16, - alpha: f32, - }, - // Normalized to a straight line between points p0 and p1, - // color stops normalized to align with both points. - LinearGradient { - p0: Point, - p1: Point, - color_stops: Vec, - extend: Extend, - }, - RadialGradient { - c0: Point, - r0: f32, - c1: Point, - r1: f32, - color_stops: Vec, - extend: Extend, - }, - SweepGradient { - c0: Point, - start_angle: f32, - end_angle: f32, - color_stops: Vec, - extend: Extend, - }, -} - -// Wrapping Transform for tests, as the results of trigonometric functions, in -// particular the tan() cases in PaintSkew need floating point PartialEq -// comparisons with an epsilon because the result of the tan() function differs -// on different platforms/archictectures. -#[derive(Serialize, Deserialize)] -struct DumpTransform(Transform); - -// Using the same value as in SK_ScalarNearlyZero from Skia (see SkScalar.h). -const NEARLY_EQUAL_TOLERANCE: f32 = 1.0 / (1 << 12) as f32; - -fn nearly_equal(a: f32, b: f32) -> bool { - (a - b).abs() < NEARLY_EQUAL_TOLERANCE -} - -impl PartialEq for DumpTransform { - fn eq(&self, other: &DumpTransform) -> bool { - nearly_equal(self.0.xx, other.0.xx) - && nearly_equal(self.0.xy, other.0.xy) - && nearly_equal(self.0.yx, other.0.yx) - && nearly_equal(self.0.yy, other.0.yy) - && nearly_equal(self.0.dx, other.0.dx) - && nearly_equal(self.0.dy, other.0.dy) - } -} - -impl From for DumpTransform { - fn from(value: Transform) -> Self { - Self(value) - } -} - -#[derive(Serialize, Deserialize, PartialEq)] -enum PaintOps { - PushTransform { - transform: DumpTransform, - }, - PopTransform, - PushClipGlyph { - gid: u32, - }, - PushClipBox { - clip_box: BoundingBox, - }, - PopClip, - FillBrush { - brush: BrushParams, - }, - FillGlyph { - gid: u32, - transform: DumpTransform, - brush: BrushParams, - }, - PushLayer { - composite_mode: u8, - }, - PopLayer, -} - -impl ColorPainter for PaintDump { - fn push_transform(&mut self, transform: Transform) { - self.ops.push(PaintOps::PushTransform { - transform: transform.into(), - }); - } - fn pop_transform(&mut self) { - self.ops.push(PaintOps::PopTransform); - } - - fn push_clip_glyph(&mut self, glyph: GlyphId) { - self.ops.push(PaintOps::PushClipGlyph { - gid: glyph.to_u32(), - }); - } - - fn push_clip_box(&mut self, clip_box: BoundingBox) { - self.ops.push(PaintOps::PushClipBox { clip_box }); - } - - fn pop_clip(&mut self) { - self.ops.push(PaintOps::PopClip); - } - - fn fill(&mut self, brush: Brush) { - self.ops.push(PaintOps::FillBrush { - brush: brush.into(), - }); - } - - fn fill_glyph(&mut self, glyph_id: GlyphId, transform: Option, brush: Brush) { - self.ops.push(PaintOps::FillGlyph { - gid: glyph_id.to_u32(), - transform: transform.unwrap_or_default().into(), - brush: brush.into(), - }); - } - - fn push_layer(&mut self, composite_mode: CompositeMode) { - self.ops.push(PaintOps::PushLayer { - composite_mode: composite_mode as u8, - }); - } - fn pop_layer(&mut self) { - self.ops.push(PaintOps::PopLayer); - } -} - -impl PaintDump { - pub fn new(gid: u32) -> Self { - Self { - glyph_id: gid, - ..Default::default() - } - } -} - -fn location_to_filename(set_name: &str, settings: I) -> String -where - I: IntoIterator, - I::Item: Into, -{ - let formatted_settings: Vec = settings - .into_iter() - .map(|entry| { - let entry_setting = entry.into(); - format!("{:}_{:}", entry_setting.selector, entry_setting.value) - }) - .collect(); - let suffix = match formatted_settings.len() { - 0 => String::new(), - _ => format!("_{}", formatted_settings.join("_")), - }; - format!("colrv1_{}{}", set_name.to_lowercase(), suffix) -} - -fn should_rebaseline() -> bool { - env::var("REBASELINE_COLRV1_TESTS").is_ok() -} - -// To regenerate the baselines, set the environment variable `REBASELINE_COLRV1_TESTS` -// when running tests, for example like this: -// $ REBASELINE_COLRV1_TESTS=1 cargo test color::traversal -fn colrv1_traversal_test( - set_name: &str, - test_chars: &[char], - settings: &[(&str, f32)], - required_format: crate::color::ColorGlyphFormat, -) { - let colr_font = font_test_data::COLRV0V1_VARIABLE; - let font = FontRef::new(colr_font).unwrap(); - - let location = font.axes().location(settings); - - let dumpfile_path = format!( - "../font-test-data/test_data/colrv1_json/{}", - location_to_filename(set_name, settings) - ); - - let test_gids = test_chars - .iter() - .map(|codepoint| font.charmap().map(*codepoint).unwrap()); - - let paint_dumps_iter = test_gids.map(|gid| { - let mut color_painter = PaintDump::new(gid.to_u32()); - - let color_glyph = font.color_glyphs().get_with_format(gid, required_format); - - assert!(color_glyph.is_some()); - - let result = color_glyph - .unwrap() - .paint(location.coords(), &mut color_painter); - - assert!(result.is_ok()); - - color_painter - }); - - if should_rebaseline() { - let mut file = OpenOptions::new() - .write(true) - .create(true) - .truncate(true) - .open(dumpfile_path) - .unwrap(); - - paint_dumps_iter.for_each(|dump| { - writeln!(file, "{}", serde_json::to_string(&dump).unwrap()) - .expect("Writing to file failed.") - }); - } else { - let expected = font_test_data::colrv1_json::expected(set_name, settings); - let mut lines = io::BufReader::new(expected.as_bytes()).lines(); - for dump in paint_dumps_iter { - match lines.next() { - Some(line) => { - assert!( - dump == serde_json::from_str( - line.as_ref().expect("Failed to read expectations line from file.") - ) - .expect("Failed to parse expectations line."), - "Result did not match expectation for glyph id: {}\nActual: {}\nExpected: {}\n", - dump.glyph_id, serde_json::to_string(&dump).unwrap(), &line.unwrap() - ) - } - None => panic!("Expectation not found for glyph id: {}", dump.glyph_id), - } - } - } -} - -macro_rules! colrv1_traversal_tests { - ($($test_name:ident: $glyph_set:ident, $settings:expr,)*) => { - $( - #[test] - fn $test_name() { - colrv1_traversal_test(stringify!($glyph_set), $glyph_set, $settings, crate::color::ColorGlyphFormat::ColrV1); - } - )* - } -} - -colrv1_traversal_tests!( -clipbox_default:CLIPBOX,&[], -clipbox_var_1:CLIPBOX, &[("CLIO", 200.0)], -comp_mode_default:COMPOSITE_MODE,&[], -extend_mode_default:EXTEND_MODE,&[], -extend_mode_var1:EXTEND_MODE,&[("COL1", -0.25), ("COL3", 0.25)], -extend_mode_var2:EXTEND_MODE,&[("COL1", 0.5), ("COL3", -0.5)], -extend_mode_var3:EXTEND_MODE,&[("COL3", 0.5)], -extend_mode_var4:EXTEND_MODE,&[("COL3", 1.0)], -extend_mode_var5:EXTEND_MODE,&[("COL1", -1.5)], -extend_mode_var6:EXTEND_MODE,&[("GRR0", -200.0), ("GRR1", -300.0)], -extend_mode_var7:EXTEND_MODE,&[("GRX0", -1000.0), ("GRX1", -1000.0), ("GRR0", -1000.0), ("GRR1", -900.0)], -extend_mode_var8:EXTEND_MODE,&[("GRX0", 1000.0), ("GRX1", -1000.0), ("GRR0", -1000.0), ("GRR1", 200.0)], -extend_mode_var9:EXTEND_MODE,&[("GRR0", -50.0), ("COL3", -2.0), ("COL2", -2.0), ("COL1", -0.9)], -extend_mode_var10:EXTEND_MODE,&[("GRR0", -50.0), ("COL3", -2.0), ("COL2", -2.0), ("COL1", -1.1)], -extend_mode_var11:EXTEND_MODE,&[("COL3", 1.0), ("COL2", 1.5), ("COL1", 2.0)], -extend_mode_var12:EXTEND_MODE,&[("COL2", -0.3)], -extend_mode_var13:EXTEND_MODE,&[("GRR0", 430.0), ("GRR1", 40.0)], -foreground_color_default:FOREGROUND_COLOR,&[], -gradient_skewed:GRADIENT_P2_SKEWED,&[], -gradient_stops_repeat:GRADIENT_STOPS_REPEAT,&[], -paint_rotate_default:PAINT_ROTATE,&[], -paint_rotate_var1:PAINT_ROTATE,&[("ROTA", 40.0)], -paint_rotate_var2:PAINT_ROTATE,&[("ROTX", -250.0), ("ROTY", -250.0)], -paint_scale_default:PAINT_SCALE,&[], -paint_scale_var1:PAINT_SCALE,&[("SCOX", 200.0), ("SCOY", 200.0)], -paint_scale_var2:PAINT_SCALE,&[("SCSX", 0.25), ("SCOY", 0.25)], -paint_scale_var3:PAINT_SCALE,&[("SCSX", -1.0), ("SCOY", -1.0)], -paint_skew_default:PAINT_SKEW,&[], -paint_skew_var1:PAINT_SKEW,&[("SKXA", 20.0)], -paint_skew_var2:PAINT_SKEW,&[("SKYA", 20.0)], -paint_skew_var3:PAINT_SKEW,&[("SKCX", 200.0),("SKCY", 200.0)], -paint_transform_default:PAINT_TRANSFORM,&[], -paint_translate_default:PAINT_TRANSLATE,&[], -paint_translate_var_1:PAINT_TRANSLATE,&[("TLDX", 100.0), ("TLDY", 100.0)], -paint_sweep_default:SWEEP_VARSWEEP,&[], -paint_sweep_var1:SWEEP_VARSWEEP,&[("SWPS", 0.0)], -paint_sweep_var2:SWEEP_VARSWEEP,&[("SWPS", 90.0)], -paint_sweep_var3:SWEEP_VARSWEEP,&[("SWPE", -90.0)], -paint_sweep_var4:SWEEP_VARSWEEP,&[("SWPE", -45.0)], -paint_sweep_var5:SWEEP_VARSWEEP,&[("SWPS", -45.0),("SWPE", 45.0)], -paint_sweep_var6:SWEEP_VARSWEEP,&[("SWC1", -0.25), ("SWC2", 0.083333333), ("SWC3", 0.083333333), ("SWC4", 0.25)], -paint_sweep_var7:SWEEP_VARSWEEP,&[("SWPS", 45.0), ("SWPE", -45.0), ("SWC1", -0.25), ("SWC2", -0.416687), ("SWC3", -0.583313), ("SWC4", -0.75)], -variable_alpha_default:VARIABLE_ALPHA,&[], -variable_alpha_var1:VARIABLE_ALPHA,&[("APH1", -0.7)], -variable_alpha_var2:VARIABLE_ALPHA,&[("APH2", -0.7), ("APH3", -0.2)], -nocycle_multi_colrglyph:NO_CYCLE_MULTI_COLRGLYPH,&[], -sweep_coincident:SWEEP_COINCIDENT,&[], -paint_glyph_nested:PAINT_GLYPH_NESTED,&[], -); - -macro_rules! colrv0_traversal_tests { - ($($test_name:ident: $glyph_set:ident,)*) => { - $( - #[test] - fn $test_name() { - colrv1_traversal_test(stringify!($glyph_set), $glyph_set, &[], crate::color::ColorGlyphFormat::ColrV0); - } - )* -} -} - -colrv0_traversal_tests!( - colored_circles:COLORED_CIRCLES_V0, -); diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,214 +0,0 @@ -pub(crate) const GRADIENT_STOPS_REPEAT: &[char] = - &['\u{f0100}', '\u{f0101}', '\u{f0102}', '\u{f0103}']; -pub(crate) const SWEEP_VARSWEEP: &[char] = &[ - '\u{f0200}', - '\u{f0201}', - '\u{f0202}', - '\u{f0203}', - '\u{f0204}', - '\u{f0205}', - '\u{f0206}', - '\u{f0207}', - '\u{f0208}', - '\u{f0209}', - '\u{f020a}', - '\u{f020b}', - '\u{f020c}', - '\u{f020d}', - '\u{f020e}', - '\u{f020f}', - '\u{f0210}', - '\u{f0211}', - '\u{f0212}', - '\u{f0213}', - '\u{f0214}', - '\u{f0215}', - '\u{f0216}', - '\u{f0217}', - '\u{f0218}', - '\u{f0219}', - '\u{f021a}', - '\u{f021b}', - '\u{f021c}', - '\u{f021d}', - '\u{f021e}', - '\u{f021f}', - '\u{f0220}', - '\u{f0221}', - '\u{f0222}', - '\u{f0223}', - '\u{f0224}', - '\u{f0225}', - '\u{f0226}', - '\u{f0227}', - '\u{f0228}', - '\u{f0229}', - '\u{f022a}', - '\u{f022b}', - '\u{f022c}', - '\u{f022d}', - '\u{f022e}', - '\u{f022f}', - '\u{f0230}', - '\u{f0231}', - '\u{f0232}', - '\u{f0233}', - '\u{f0234}', - '\u{f0235}', - '\u{f0236}', - '\u{f0237}', - '\u{f0238}', - '\u{f0239}', - '\u{f023a}', - '\u{f023b}', - '\u{f023c}', - '\u{f023d}', - '\u{f023e}', - '\u{f023f}', - '\u{f0240}', - '\u{f0241}', - '\u{f0242}', - '\u{f0243}', - '\u{f0244}', - '\u{f0245}', - '\u{f0246}', - '\u{f0247}', -]; -pub(crate) const PAINT_SCALE: &[char] = &[ - '\u{f0300}', - '\u{f0301}', - '\u{f0302}', - '\u{f0303}', - '\u{f0304}', - '\u{f0305}', -]; -pub(crate) const EXTEND_MODE: &[char] = &[ - '\u{f0500}', - '\u{f0501}', - '\u{f0502}', - '\u{f0503}', - '\u{f0504}', - '\u{f0505}', - '\u{f0506}', - '\u{f0507}', - '\u{f0508}', -]; -pub(crate) const PAINT_ROTATE: &[char] = &['\u{f0600}', '\u{f0601}', '\u{f0602}', '\u{f0603}']; -pub(crate) const PAINT_SKEW: &[char] = &[ - '\u{f0700}', - '\u{f0701}', - '\u{f0702}', - '\u{f0703}', - '\u{f0704}', - '\u{f0705}', -]; -pub(crate) const PAINT_TRANSFORM: &[char] = &['\u{f0800}', '\u{f0801}', '\u{f0802}', '\u{f0803}']; -pub(crate) const PAINT_TRANSLATE: &[char] = &[ - '\u{f0900}', - '\u{f0901}', - '\u{f0902}', - '\u{f0903}', - '\u{f0904}', - '\u{f0905}', - '\u{f0906}', -]; -pub(crate) const COMPOSITE_MODE: &[char] = &[ - '\u{f0a00}', - '\u{f0a01}', - '\u{f0a02}', - '\u{f0a03}', - '\u{f0a04}', - '\u{f0a05}', - '\u{f0a06}', - '\u{f0a07}', - '\u{f0a08}', - '\u{f0a09}', - '\u{f0a0a}', - '\u{f0a0b}', - '\u{f0a0c}', - '\u{f0a0d}', - '\u{f0a0e}', - '\u{f0a0f}', - '\u{f0a10}', - '\u{f0a11}', - '\u{f0a12}', - '\u{f0a13}', - '\u{f0a14}', - '\u{f0a15}', - '\u{f0a16}', - '\u{f0a17}', - '\u{f0a18}', - '\u{f0a19}', - '\u{f0a1a}', - '\u{f0a1b}', -]; -pub(crate) const FOREGROUND_COLOR: &[char] = &[ - '\u{f0b00}', - '\u{f0b01}', - '\u{f0b02}', - '\u{f0b03}', - '\u{f0b04}', - '\u{f0b05}', - '\u{f0b06}', - '\u{f0b07}', -]; -pub(crate) const CLIPBOX: &[char] = &[ - '\u{f0c00}', - '\u{f0c01}', - '\u{f0c02}', - '\u{f0c03}', - '\u{f0c04}', -]; -pub(crate) const GRADIENT_P2_SKEWED: &[char] = &['\u{f0d00}']; -pub(crate) const VARIABLE_ALPHA: &[char] = &['\u{f1000}']; -pub(crate) const NO_CYCLE_MULTI_COLRGLYPH: &[char] = &['\u{f1200}']; -pub(crate) const SWEEP_COINCIDENT: &[char] = &[ - '\u{f1300}', - '\u{f1301}', - '\u{f1302}', - '\u{f1303}', - '\u{f1304}', - '\u{f1305}', - '\u{f1306}', - '\u{f1307}', - '\u{f1308}', - '\u{f1309}', - '\u{f130a}', - '\u{f130b}', - '\u{f130c}', - '\u{f130d}', - '\u{f130e}', - '\u{f130f}', - '\u{f1310}', - '\u{f1311}', - '\u{f1312}', - '\u{f1313}', - '\u{f1314}', - '\u{f1315}', - '\u{f1316}', - '\u{f1317}', -]; -pub(crate) const COLORED_CIRCLES_V0: &[char] = &['\u{F0E00}']; - -pub(crate) const COLORED_CIRCLES_V1: &[char] = &['\u{F0E01}']; - -pub(crate) const PAINTCOLRGLYPH_CYCLE: &[char] = &['\u{f1100}', '\u{f1101}', '\u{f1200}']; - -pub(crate) const PAINT_GLYPH_NESTED: &[char] = &[ - '\u{f1400}', - '\u{f1401}', - '\u{f1402}', - '\u{f1403}', - '\u{f1404}', - '\u{f1405}', - '\u{f1406}', - '\u{f1407}', - '\u{f1408}', - '\u{f1409}', - '\u{f140a}', - '\u{f140b}', - '\u{f140c}', - '\u{f140d}', - '\u{f140e}', - '\u{f140f}', -]; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -//! Basic representation of an in-memory font resource. - -pub use read_fonts::FontRef; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,201 +0,0 @@ -//! Helpers for selecting a font size and location in variation space. - -use read_fonts::types::Fixed; - -use crate::collections::SmallVec; - -/// Type for a normalized variation coordinate. -pub type NormalizedCoord = read_fonts::types::F2Dot14; - -/// Font size in pixels per em units. -/// -/// Sizes in this crate are represented as a ratio of pixels to the size of -/// the em square defined by the font. This is equivalent to the `px` unit -/// in CSS (assuming a DPI scale factor of 1.0). -/// -/// To retrieve metrics and outlines in font units, use the [unscaled](Self::unscaled) -/// constructor on this type. -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] -pub struct Size(Option); - -impl Size { - /// Creates a new font size from the given value in pixels per em units. - pub fn new(ppem: f32) -> Self { - Self(Some(ppem)) - } - - /// Creates a new font size for generating unscaled metrics or outlines in - /// font units. - pub fn unscaled() -> Self { - Self(None) - } - - /// Returns the raw size in pixels per em units. - /// - /// Results in `None` if the size is unscaled. - pub fn ppem(self) -> Option { - self.0 - } - - /// Computes a linear scale factor for this font size and the given units - /// per em value which can be retrieved from the [Metrics](crate::metrics::Metrics) - /// type or from the [head](read_fonts::tables::head::Head) table. - /// - /// Returns 1.0 for an unscaled size or when `units_per_em` is 0. - pub fn linear_scale(self, units_per_em: u16) -> f32 { - match self.0 { - Some(ppem) if units_per_em != 0 => ppem / units_per_em as f32, - _ => 1.0, - } - } - - /// Computes a fixed point linear scale factor that matches FreeType. - pub(crate) fn fixed_linear_scale(self, units_per_em: u16) -> Fixed { - // FreeType computes a 16.16 scale factor that converts to 26.6. - // This is done in two steps, assuming use of FT_Set_Pixel_Size: - // 1) height is multiplied by 64: - // - // 2) this value is divided by UPEM: - // (here, scaled_h=height and h=upem) - // - match self.0 { - Some(ppem) if units_per_em > 0 => { - Fixed::from_bits((ppem * 64.) as i32) / Fixed::from_bits(units_per_em as i32) - } - _ => { - // This is an identity scale for the pattern - // `mul_div(value, scale, 64)` - Fixed::from_bits(0x10000 * 64) - } - } - } -} - -/// Reference to an ordered sequence of normalized variation coordinates. -/// -/// To convert from user coordinates see [`crate::AxisCollection::location`]. -/// -/// This type represents a position in the variation space where each -/// coordinate corresponds to an axis (in the same order as the `fvar` table) -/// and is a normalized value in the range `[-1..1]`. -/// -/// See [Coordinate Scales and Normalization](https://learn.microsoft.com/en-us/typography/opentype/spec/otvaroverview#coordinate-scales-and-normalization) -/// for further details. -/// -/// If the array is larger in length than the number of axes, extraneous -/// values are ignored. If it is smaller, unrepresented axes are assumed to be -/// at their default positions (i.e. 0). -/// -/// A value of this type constructed with `default()` represents the default -/// position for each axis. -/// -/// Normalized coordinates are ignored for non-variable fonts. -#[derive(Copy, Clone, Default, Debug)] -pub struct LocationRef<'a>(&'a [NormalizedCoord]); - -impl<'a> LocationRef<'a> { - /// Creates a new sequence of normalized coordinates from the given array. - pub fn new(coords: &'a [NormalizedCoord]) -> Self { - Self(coords) - } - - /// Returns the underlying array of normalized coordinates. - pub fn coords(&self) -> &'a [NormalizedCoord] { - self.0 - } -} - -impl<'a> From<&'a [NormalizedCoord]> for LocationRef<'a> { - fn from(value: &'a [NormalizedCoord]) -> Self { - Self(value) - } -} - -impl<'a> IntoIterator for LocationRef<'a> { - type IntoIter = core::slice::Iter<'a, NormalizedCoord>; - type Item = &'a NormalizedCoord; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter() - } -} - -impl<'a> IntoIterator for &'_ LocationRef<'a> { - type IntoIter = core::slice::Iter<'a, NormalizedCoord>; - type Item = &'a NormalizedCoord; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter() - } -} - -/// Maximum number of coords to store inline in a `Location` object. -/// -/// This value was chosen to maximize use of space in the underlying -/// `SmallVec` storage. -const MAX_INLINE_COORDS: usize = 8; - -/// Ordered sequence of normalized variation coordinates. -/// -/// To produce from user coordinates see [`crate::AxisCollection::location`]. -/// -/// This is an owned version of [`LocationRef`]. See the documentation on that -/// type for more detail. -#[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct Location { - coords: SmallVec, -} - -impl Location { - /// Creates a new location with the given number of normalized coordinates. - /// - /// Each element will be initialized to the default value (0.0). - pub fn new(len: usize) -> Self { - Self { - coords: SmallVec::with_len(len, NormalizedCoord::default()), - } - } - - /// Returns the underlying slice of normalized coordinates. - pub fn coords(&self) -> &[NormalizedCoord] { - self.coords.as_slice() - } - - /// Returns a mutable reference to the underlying slice of normalized - /// coordinates. - pub fn coords_mut(&mut self) -> &mut [NormalizedCoord] { - self.coords.as_mut_slice() - } -} - -impl Default for Location { - fn default() -> Self { - Self { - coords: SmallVec::new(), - } - } -} - -impl<'a> From<&'a Location> for LocationRef<'a> { - fn from(value: &'a Location) -> Self { - LocationRef(value.coords()) - } -} - -impl<'a> IntoIterator for &'a Location { - type IntoIter = core::slice::Iter<'a, NormalizedCoord>; - type Item = &'a NormalizedCoord; - - fn into_iter(self) -> Self::IntoIter { - self.coords().iter() - } -} - -impl<'a> IntoIterator for &'a mut Location { - type IntoIter = core::slice::IterMut<'a, NormalizedCoord>; - type Item = &'a mut NormalizedCoord; - - fn into_iter(self) -> Self::IntoIter { - self.coords_mut().iter_mut() - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -//! A robust, ergonomic, high performance crate for OpenType fonts. -//! -//! Skrifa is a mid level library that provides access to various types -//! of [`metadata`](MetadataProvider) contained in a font as well as support -//! for loading glyph [`outlines`](outline). -//! -//! It is described as "mid level" because the library is designed to sit -//! above low level font parsing (provided by [`read-fonts`](https://crates.io/crates/read-fonts)) -//! and below a higher level text layout engine. -//! -//! See the [readme](https://github.com/googlefonts/fontations/blob/main/skrifa/README.md) -//! for additional details. - -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![forbid(unsafe_code)] -#![cfg_attr(not(any(test, feature = "std")), no_std)] - -#[cfg(not(any(feature = "libm", feature = "std")))] -compile_error!("Either feature \"std\" or \"libm\" must be enabled for this crate."); - -#[cfg(not(any(test, feature = "std")))] -#[macro_use] -extern crate core as std; - -#[macro_use] -extern crate alloc; - -/// Expose our "raw" underlying parser crate. -pub extern crate read_fonts as raw; - -pub mod attribute; -pub mod charmap; -pub mod color; -pub mod font; -pub mod instance; -pub mod metrics; -pub mod outline; - -pub mod setting; -pub mod string; - -mod collections; -mod provider; -mod variation; - -#[doc(inline)] -pub use outline::{OutlineGlyph, OutlineGlyphCollection}; -pub use variation::{Axis, AxisCollection, NamedInstance, NamedInstanceCollection}; - -/// Useful collection of common types suitable for glob importing. -pub mod prelude { - #[doc(no_inline)] - pub use super::{ - font::FontRef, - instance::{LocationRef, NormalizedCoord, Size}, - GlyphId, MetadataProvider, Tag, - }; -} - -pub use read_fonts::{ - types::{GlyphId, GlyphId16, Tag}, - FontRef, -}; - -#[doc(inline)] -pub use provider::MetadataProvider; - -/// Limit for recursion when loading TrueType composite glyphs. -const GLYF_COMPOSITE_RECURSION_LIMIT: usize = 32; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,584 +0,0 @@ -//! Global font and glyph specific metrics. -//! -//! Metrics are various measurements that define positioning and layout -//! characteristics for a font. They come in two flavors: -//! -//! * Global metrics: these are applicable to all glyphs in a font and generally -//! define values that are used for the layout of a collection of glyphs. For example, -//! the ascent, descent and leading values determine the position of the baseline where -//! a glyph should be rendered as well as the suggested spacing above and below it. -//! -//! * Glyph metrics: these apply to single glyphs. For example, the advance -//! width value describes the distance between two consecutive glyphs on a line. -//! -//! ### Selecting an "instance" -//! Both global and glyph specific metrics accept two additional pieces of information -//! to select the desired instance of a font: -//! * Size: represented by the [Size] type, this determines the scaling factor that is -//! applied to all metrics. -//! * Normalized variation coordinates: represented by the [LocationRef] type, -//! these define the position in design space for a variable font. For a non-variable -//! font, these coordinates are ignored and you can pass [LocationRef::default()] -//! as an argument for this parameter. -//! - -use read_fonts::{ - tables::{ - glyf::Glyf, gvar::Gvar, hmtx::LongMetric, hvar::Hvar, loca::Loca, os2::SelectionFlags, - }, - types::{BigEndian, Fixed, GlyphId}, - TableProvider, -}; - -use super::instance::{LocationRef, NormalizedCoord, Size}; - -/// Type for a bounding box with single precision floating point coordinates. -pub type BoundingBox = read_fonts::types::BoundingBox; - -/// Metrics for a text decoration. -/// -/// This represents the suggested offset and thickness of an underline -/// or strikeout text decoration. -#[derive(Copy, Clone, PartialEq, Default, Debug)] -pub struct Decoration { - /// Offset to the top of the decoration from the baseline. - pub offset: f32, - /// Thickness of the decoration. - pub thickness: f32, -} - -/// Metrics that apply to all glyphs in a font. -/// -/// These are retrieved for a specific position in the design space. -/// -/// This metrics here are derived from the following tables: -/// * [head](https://learn.microsoft.com/en-us/typography/opentype/spec/head): `units_per_em`, `bounds` -/// * [maxp](https://learn.microsoft.com/en-us/typography/opentype/spec/maxp): `glyph_count` -/// * [post](https://learn.microsoft.com/en-us/typography/opentype/spec/post): `is_monospace`, `italic_angle`, `underline` -/// * [OS/2](https://learn.microsoft.com/en-us/typography/opentype/spec/os2): `average_width`, `cap_height`, -/// `x_height`, `strikeout`, as well as the line metrics: `ascent`, `descent`, `leading` if the `USE_TYPOGRAPHIC_METRICS` -/// flag is set or the `hhea` line metrics are zero (the Windows metrics are used as a last resort). -/// * [hhea](https://learn.microsoft.com/en-us/typography/opentype/spec/hhea): `max_width`, as well as the line metrics: -/// `ascent`, `descent`, `leading` if they are non-zero and the `USE_TYPOGRAPHIC_METRICS` flag is not set in the OS/2 table -/// -/// For variable fonts, deltas are computed using the [MVAR](https://learn.microsoft.com/en-us/typography/opentype/spec/MVAR) -/// table. -#[derive(Copy, Clone, PartialEq, Default, Debug)] -pub struct Metrics { - /// Number of font design units per em unit. - pub units_per_em: u16, - /// Number of glyphs in the font. - pub glyph_count: u16, - /// True if the font is not proportionally spaced. - pub is_monospace: bool, - /// Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, - /// negative for text that leans to the right. - pub italic_angle: f32, - /// Distance from the baseline to the top of the alignment box. - pub ascent: f32, - /// Distance from the baseline to the bottom of the alignment box. - pub descent: f32, - /// Recommended additional spacing between lines. - pub leading: f32, - /// Distance from the baseline to the top of a typical English capital. - pub cap_height: Option, - /// Distance from the baseline to the top of the lowercase "x" or - /// similar character. - pub x_height: Option, - /// Average width of all non-zero width characters in the font. - pub average_width: Option, - /// Maximum advance width of all characters in the font. - pub max_width: Option, - /// Metrics for an underline decoration. - pub underline: Option, - /// Metrics for a strikeout decoration. - pub strikeout: Option, - /// Union of minimum and maximum extents for all glyphs in the font. - pub bounds: Option, -} - -impl Metrics { - /// Creates new metrics for the given font, size, and location in - /// normalized variation space. - pub fn new<'a>( - font: &impl TableProvider<'a>, - size: Size, - location: impl Into>, - ) -> Self { - let head = font.head(); - let mut metrics = Metrics { - units_per_em: head.map(|head| head.units_per_em()).unwrap_or_default(), - ..Default::default() - }; - let coords = location.into().coords(); - let scale = size.linear_scale(metrics.units_per_em); - if let Ok(head) = font.head() { - metrics.bounds = Some(BoundingBox { - x_min: head.x_min() as f32 * scale, - y_min: head.y_min() as f32 * scale, - x_max: head.x_max() as f32 * scale, - y_max: head.y_max() as f32 * scale, - }); - } - if let Ok(maxp) = font.maxp() { - metrics.glyph_count = maxp.num_glyphs(); - } - if let Ok(post) = font.post() { - metrics.is_monospace = post.is_fixed_pitch() != 0; - metrics.italic_angle = post.italic_angle().to_f64() as f32; - metrics.underline = Some(Decoration { - offset: post.underline_position().to_i16() as f32 * scale, - thickness: post.underline_thickness().to_i16() as f32 * scale, - }); - } - let hhea = font.hhea(); - if let Ok(hhea) = &hhea { - metrics.max_width = Some(hhea.advance_width_max().to_u16() as f32 * scale); - } - // Choosing proper line metrics is a challenge due to the changing - // spec, backward compatibility and broken fonts. - // - // We use the same strategy as FreeType: - // 1. Use the OS/2 metrics if the table exists and the USE_TYPO_METRICS - // flag is set. - // 2. Otherwise, use the hhea metrics. - // 3. If hhea metrics are zero and the OS/2 table exists: - // 3a. Use the typo metrics if they are non-zero - // 3b. Otherwise, use the win metrics - // - // See: https://github.com/freetype/freetype/blob/5c37b6406258ec0d7ab64b8619c5ea2c19e3c69a/src/sfnt/sfobjs.c#L1311 - let os2 = font.os2().ok(); - let mut used_typo_metrics = false; - if let Some(os2) = &os2 { - if os2 - .fs_selection() - .contains(SelectionFlags::USE_TYPO_METRICS) - { - metrics.ascent = os2.s_typo_ascender() as f32 * scale; - metrics.descent = os2.s_typo_descender() as f32 * scale; - metrics.leading = os2.s_typo_line_gap() as f32 * scale; - used_typo_metrics = true; - } - metrics.average_width = Some(os2.x_avg_char_width() as f32 * scale); - metrics.cap_height = os2.s_cap_height().map(|v| v as f32 * scale); - metrics.x_height = os2.sx_height().map(|v| v as f32 * scale); - metrics.strikeout = Some(Decoration { - offset: os2.y_strikeout_position() as f32 * scale, - thickness: os2.y_strikeout_size() as f32 * scale, - }); - } - if !used_typo_metrics { - if let Ok(hhea) = font.hhea() { - metrics.ascent = hhea.ascender().to_i16() as f32 * scale; - metrics.descent = hhea.descender().to_i16() as f32 * scale; - metrics.leading = hhea.line_gap().to_i16() as f32 * scale; - } - if metrics.ascent == 0.0 && metrics.descent == 0.0 { - if let Some(os2) = &os2 { - if os2.s_typo_ascender() != 0 || os2.s_typo_descender() != 0 { - metrics.ascent = os2.s_typo_ascender() as f32 * scale; - metrics.descent = os2.s_typo_descender() as f32 * scale; - metrics.leading = os2.s_typo_line_gap() as f32 * scale; - } else { - metrics.ascent = os2.us_win_ascent() as f32 * scale; - // Win descent is always positive while other descent values are negative. Negate it - // to ensure we return consistent metrics. - metrics.descent = -(os2.us_win_descent() as f32 * scale); - } - } - } - } - if let (Ok(mvar), true) = (font.mvar(), !coords.is_empty()) { - use read_fonts::tables::mvar::tags::*; - let metric_delta = - |tag| mvar.metric_delta(tag, coords).unwrap_or_default().to_f64() as f32 * scale; - metrics.ascent += metric_delta(HASC); - metrics.descent += metric_delta(HDSC); - metrics.leading += metric_delta(HLGP); - if let Some(cap_height) = &mut metrics.cap_height { - *cap_height += metric_delta(CPHT); - } - if let Some(x_height) = &mut metrics.x_height { - *x_height += metric_delta(XHGT); - } - if let Some(underline) = &mut metrics.underline { - underline.offset += metric_delta(UNDO); - underline.thickness += metric_delta(UNDS); - } - if let Some(strikeout) = &mut metrics.strikeout { - strikeout.offset += metric_delta(STRO); - strikeout.thickness += metric_delta(STRS); - } - } - metrics - } -} - -/// Glyph specific metrics. -#[derive(Clone)] -pub struct GlyphMetrics<'a> { - glyph_count: u32, - fixed_scale: FixedScaleFactor, - h_metrics: &'a [LongMetric], - default_advance_width: u16, - lsbs: &'a [BigEndian], - hvar: Option>, - gvar: Option>, - loca_glyf: Option<(Loca<'a>, Glyf<'a>)>, - coords: &'a [NormalizedCoord], -} - -impl<'a> GlyphMetrics<'a> { - /// Creates new glyph metrics from the given font, size, and location in - /// normalized variation space. - pub fn new( - font: &impl TableProvider<'a>, - size: Size, - location: impl Into>, - ) -> Self { - let glyph_count = font - .maxp() - .map(|maxp| maxp.num_glyphs() as u32) - .unwrap_or_default(); - let upem = font - .head() - .map(|head| head.units_per_em()) - .unwrap_or_default(); - let fixed_scale = FixedScaleFactor(size.fixed_linear_scale(upem)); - let coords = location.into().coords(); - let (h_metrics, default_advance_width, lsbs) = font - .hmtx() - .map(|hmtx| { - let h_metrics = hmtx.h_metrics(); - let default_advance_width = h_metrics.last().map(|m| m.advance.get()).unwrap_or(0); - let lsbs = hmtx.left_side_bearings(); - (h_metrics, default_advance_width, lsbs) - }) - .unwrap_or_default(); - let hvar = font.hvar().ok(); - let gvar = font.gvar().ok(); - let loca_glyf = if let (Ok(loca), Ok(glyf)) = (font.loca(None), font.glyf()) { - Some((loca, glyf)) - } else { - None - }; - Self { - glyph_count, - fixed_scale, - h_metrics, - default_advance_width, - lsbs, - hvar, - gvar, - loca_glyf, - coords, - } - } - - /// Returns the number of available glyphs in the font. - pub fn glyph_count(&self) -> u32 { - self.glyph_count - } - - /// Returns the advance width for the specified glyph. - /// - /// If normalized coordinates were provided when constructing glyph metrics and - /// an `HVAR` table is present, applies the appropriate delta. - /// - /// Returns `None` if `glyph_id >= self.glyph_count()` or the underlying font - /// data is invalid. - pub fn advance_width(&self, glyph_id: GlyphId) -> Option { - if glyph_id.to_u32() >= self.glyph_count { - return None; - } - let mut advance = self - .h_metrics - .get(glyph_id.to_u32() as usize) - .map(|metric| metric.advance()) - .unwrap_or(self.default_advance_width) as i32; - if let Some(hvar) = &self.hvar { - advance += hvar - .advance_width_delta(glyph_id, self.coords) - // FreeType truncates metric deltas... - // https://github.com/freetype/freetype/blob/7838c78f53f206ac5b8e9cefde548aa81cb00cf4/src/truetype/ttgxvar.c#L1027 - .map(|delta| delta.to_f64() as i32) - .unwrap_or(0); - } else if self.gvar.is_some() { - advance += self.metric_deltas_from_gvar(glyph_id).unwrap_or_default()[1]; - } - Some(self.fixed_scale.apply(advance)) - } - - /// Returns the left side bearing for the specified glyph. - /// - /// If normalized coordinates were provided when constructing glyph metrics and - /// an `HVAR` table is present, applies the appropriate delta. - /// - /// Returns `None` if `glyph_id >= self.glyph_count()` or the underlying font - /// data is invalid. - pub fn left_side_bearing(&self, glyph_id: GlyphId) -> Option { - if glyph_id.to_u32() >= self.glyph_count { - return None; - } - let gid_index = glyph_id.to_u32() as usize; - let mut lsb = self - .h_metrics - .get(gid_index) - .map(|metric| metric.side_bearing()) - .unwrap_or_else(|| { - self.lsbs - .get(gid_index.saturating_sub(self.h_metrics.len())) - .map(|lsb| lsb.get()) - .unwrap_or_default() - }) as i32; - if let Some(hvar) = &self.hvar { - lsb += hvar - .lsb_delta(glyph_id, self.coords) - // FreeType truncates metric deltas... - // https://github.com/freetype/freetype/blob/7838c78f53f206ac5b8e9cefde548aa81cb00cf4/src/truetype/ttgxvar.c#L1027 - .map(|delta| delta.to_f64() as i32) - .unwrap_or(0); - } else if self.gvar.is_some() { - lsb += self.metric_deltas_from_gvar(glyph_id).unwrap_or_default()[0]; - } - Some(self.fixed_scale.apply(lsb)) - } - - /// Returns the bounding box for the specified glyph. - /// - /// Note that variations are not reflected in the bounding box returned by - /// this method. - /// - /// Returns `None` if `glyph_id >= self.glyph_count()`, the underlying font - /// data is invalid, or the font does not contain TrueType outlines. - pub fn bounds(&self, glyph_id: GlyphId) -> Option { - let (loca, glyf) = self.loca_glyf.as_ref()?; - Some(match loca.get_glyf(glyph_id, glyf).ok()? { - Some(glyph) => BoundingBox { - x_min: self.fixed_scale.apply(glyph.x_min() as i32), - y_min: self.fixed_scale.apply(glyph.y_min() as i32), - x_max: self.fixed_scale.apply(glyph.x_max() as i32), - y_max: self.fixed_scale.apply(glyph.y_max() as i32), - }, - // Empty glyphs have an empty bounding box - None => BoundingBox::default(), - }) - } -} - -impl GlyphMetrics<'_> { - fn metric_deltas_from_gvar(&self, glyph_id: GlyphId) -> Option<[i32; 2]> { - let (loca, glyf) = self.loca_glyf.as_ref()?; - let mut deltas = self - .gvar - .as_ref()? - .phantom_point_deltas(glyf, loca, self.coords, glyph_id) - .ok()?; - deltas[1] -= deltas[0]; - Some([deltas[0], deltas[1]].map(|delta| delta.x.to_i32())) - } -} - -#[derive(Copy, Clone)] -struct FixedScaleFactor(Fixed); - -impl FixedScaleFactor { - #[inline(always)] - fn apply(self, value: i32) -> f32 { - // Match FreeType metric scaling - // - self.0 - .mul_div(Fixed::from_bits(value), Fixed::from_bits(64)) - .to_f32() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::MetadataProvider as _; - use font_test_data::{SIMPLE_GLYF, VAZIRMATN_VAR}; - use read_fonts::FontRef; - - #[test] - fn metrics() { - let font = FontRef::new(SIMPLE_GLYF).unwrap(); - let metrics = font.metrics(Size::unscaled(), LocationRef::default()); - let expected = Metrics { - units_per_em: 1024, - glyph_count: 3, - bounds: Some(BoundingBox { - x_min: 51.0, - y_min: -250.0, - x_max: 998.0, - y_max: 950.0, - }), - average_width: Some(1275.0), - max_width: None, - x_height: Some(512.0), - cap_height: Some(717.0), - is_monospace: false, - italic_angle: 0.0, - ascent: 950.0, - descent: -250.0, - leading: 0.0, - underline: None, - strikeout: Some(Decoration { - offset: 307.0, - thickness: 51.0, - }), - }; - assert_eq!(metrics, expected); - } - - #[test] - fn metrics_missing_os2() { - let font = FontRef::new(VAZIRMATN_VAR).unwrap(); - let metrics = font.metrics(Size::unscaled(), LocationRef::default()); - let expected = Metrics { - units_per_em: 2048, - glyph_count: 4, - bounds: Some(BoundingBox { - x_min: 29.0, - y_min: 0.0, - x_max: 1310.0, - y_max: 1847.0, - }), - average_width: None, - max_width: Some(1336.0), - x_height: None, - cap_height: None, - is_monospace: false, - italic_angle: 0.0, - ascent: 2100.0, - descent: -1100.0, - leading: 0.0, - underline: None, - strikeout: None, - }; - assert_eq!(metrics, expected); - } - - #[test] - fn glyph_metrics() { - let font = FontRef::new(VAZIRMATN_VAR).unwrap(); - let glyph_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::default()); - // (advance_width, lsb) in glyph order - let expected = &[ - (908.0, 100.0), - (1336.0, 29.0), - (1336.0, 29.0), - (633.0, 57.0), - ]; - let result = (0..4) - .map(|i| { - let gid = GlyphId::new(i as u32); - let advance_width = glyph_metrics.advance_width(gid).unwrap(); - let lsb = glyph_metrics.left_side_bearing(gid).unwrap(); - (advance_width, lsb) - }) - .collect::>(); - assert_eq!(expected, &result[..]); - } - - /// Asserts that the results generated with Size::unscaled() and - /// Size::new(upem) are equal. - /// - /// See - #[test] - fn glyph_metrics_unscaled_matches_upem_scale() { - let font = FontRef::new(VAZIRMATN_VAR).unwrap(); - let upem = font.head().unwrap().units_per_em() as f32; - let unscaled_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::default()); - let upem_metrics = font.glyph_metrics(Size::new(upem), LocationRef::default()); - for i in 0..unscaled_metrics.glyph_count() { - let gid = GlyphId::new(i); - assert_eq!( - unscaled_metrics.advance_width(gid), - upem_metrics.advance_width(gid) - ); - assert_eq!( - unscaled_metrics.left_side_bearing(gid), - upem_metrics.left_side_bearing(gid) - ); - } - } - - #[test] - fn glyph_metrics_var() { - let font = FontRef::new(VAZIRMATN_VAR).unwrap(); - let coords = &[NormalizedCoord::from_f32(-0.8)]; - let glyph_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::new(coords)); - // (advance_width, lsb) in glyph order - let expected = &[ - (908.0, 100.0), - (1246.0, 29.0), - (1246.0, 29.0), - (556.0, 57.0), - ]; - let result = (0..4) - .map(|i| { - let gid = GlyphId::new(i as u32); - let advance_width = glyph_metrics.advance_width(gid).unwrap(); - let lsb = glyph_metrics.left_side_bearing(gid).unwrap(); - (advance_width, lsb) - }) - .collect::>(); - assert_eq!(expected, &result[..]); - } - - #[test] - fn glyph_metrics_missing_hvar() { - let font = FontRef::new(VAZIRMATN_VAR).unwrap(); - let glyph_count = font.maxp().unwrap().num_glyphs(); - // Test a few different locations in variation space - for coord in [-1.0, -0.8, 0.0, 0.75, 1.0] { - let coords = &[NormalizedCoord::from_f32(coord)]; - let location = LocationRef::new(coords); - let glyph_metrics = font.glyph_metrics(Size::unscaled(), location); - let mut glyph_metrics_no_hvar = glyph_metrics.clone(); - // Setting hvar to None forces use of gvar for metric deltas - glyph_metrics_no_hvar.hvar = None; - for gid in 0..glyph_count { - let gid = GlyphId::from(gid); - assert_eq!( - glyph_metrics.advance_width(gid), - glyph_metrics_no_hvar.advance_width(gid) - ); - assert_eq!( - glyph_metrics.left_side_bearing(gid), - glyph_metrics_no_hvar.left_side_bearing(gid) - ); - } - } - } - - /// Ensure our fixed point scaling code matches FreeType for advances. - /// - /// - #[test] - fn match_freetype_glyph_metric_scaling() { - // fontations: - // gid: 36 advance: 15.33600044250488281250 gid: 68 advance: 13.46399974822998046875 gid: 47 advance: 12.57600021362304687500 gid: 79 advance: 6.19199991226196289062 - // ft: - // gid: 36 advance: 15.33595275878906250000 gid: 68 advance: 13.46395874023437500000 gid: 47 advance: 12.57595825195312500000 gid: 79 advance: 6.19198608398437500000 - // with font.setSize(24); - // - // Raw advances for gids 36, 68, 47, and 79 in NotoSans-Regular - let font_unit_advances = [639, 561, 524, 258]; - #[allow(clippy::excessive_precision)] - let scaled_advances = [ - 15.33595275878906250000, - 13.46395874023437500000, - 12.57595825195312500000, - 6.19198608398437500000, - ]; - let fixed_scale = FixedScaleFactor(Size::new(24.0).fixed_linear_scale(1000)); - for (font_unit_advance, expected_scaled_advance) in - font_unit_advances.iter().zip(scaled_advances) - { - let scaled_advance = fixed_scale.apply(*font_unit_advance); - assert_eq!(scaled_advance, expected_scaled_advance); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,949 +0,0 @@ -//! Edge hinting. -//! -//! Let's actually do some grid fitting. Here we align edges to the pixel -//! grid. This is the final step before applying the edge adjustments to -//! the original outline points. - -use super::super::{ - metrics::{fixed_mul_div, pix_floor, pix_round, Scale, ScaledAxisMetrics, ScaledWidth}, - style::ScriptGroup, - topo::{Axis, Edge}, -}; - -/// Main Latin grid-fitting routine. -/// -/// Note: this is one huge function in FreeType, broken up into several below. -/// -/// See -pub(crate) fn hint_edges( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, - mut top_to_bottom_hinting: bool, -) { - if axis.dim != Axis::VERTICAL { - top_to_bottom_hinting = false; - } - // First align horizontal edges to blue zones if needed - let anchor_ix = align_edges_to_blues(axis, metrics, group, scale); - // Now align the stem edges - let (serif_count, anchor_ix) = align_stem_edges( - axis, - metrics, - group, - scale, - top_to_bottom_hinting, - anchor_ix, - ); - let edges = axis.edges.as_mut_slice(); - // Special case for lowercase m - if axis.dim == Axis::HORIZONTAL && (edges.len() == 6 || edges.len() == 12) { - hint_lowercase_m(edges, group); - } - // Handle serifs and single segment edges - if serif_count > 0 || anchor_ix.is_none() { - align_remaining_edges(axis, group, top_to_bottom_hinting, serif_count, anchor_ix); - } -} - -/// Align horizontal edges to blue zones. -/// -/// See -fn align_edges_to_blues( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, -) -> Option { - let mut anchor_ix = None; - // For default script group, only do vertical blues - if group == ScriptGroup::Default && axis.dim != Axis::VERTICAL { - return anchor_ix; - } - for edge_ix in 0..axis.edges.len() { - let edges = axis.edges.as_mut_slice(); - let edge = &edges[edge_ix]; - if edge.flags & Edge::DONE != 0 { - continue; - } - let edge2_ix = edge.link_ix.map(|x| x as usize); - let edge2 = edge2_ix.map(|ix| &edges[ix]); - // If we have two neutral zones, skip one of them. - if let (true, Some(edge2)) = (edge.blue_edge.is_some(), edge2) { - if edge2.blue_edge.is_some() { - let skip_ix = if edge2.flags & Edge::NEUTRAL != 0 { - edge2_ix - } else if edge.flags & Edge::NEUTRAL != 0 { - Some(edge_ix) - } else { - None - }; - if let Some(skip_ix) = skip_ix { - let skip_edge = &mut edges[skip_ix]; - skip_edge.blue_edge = None; - skip_edge.flags &= !Edge::NEUTRAL; - } - } - } - // Flip edges if the other is aligned to a blue zone - let blue = edges[edge_ix].blue_edge; - let (blue, edge1_ix, edge2_ix) = if let Some(blue) = blue { - (blue, Some(edge_ix), edge2_ix) - } else if let Some(edge2_blue) = edge2_ix.and_then(|ix| edges[ix].blue_edge) { - (edge2_blue, edge2_ix, Some(edge_ix)) - } else { - (Default::default(), None, None) - }; - let Some(edge1_ix) = edge1_ix else { - continue; - }; - let edge1 = &mut edges[edge1_ix]; - edge1.pos = blue.fitted; - edge1.flags |= Edge::DONE; - if let Some(edge2_ix) = edge2_ix { - let edge2 = &mut edges[edge2_ix]; - if edge2.blue_edge.is_none() { - edge2.flags |= Edge::DONE; - align_linked_edge(axis, metrics, group, scale, edge1_ix, edge2_ix); - } - } - if anchor_ix.is_none() { - anchor_ix = Some(edge_ix); - } - } - anchor_ix -} - -/// Align stem edges, trying to main relative order of stems in the glyph. -/// -/// See -fn align_stem_edges( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, - top_to_bottom_hinting: bool, - mut anchor_ix: Option, -) -> (usize, Option) { - let mut serif_count = 0; - let mut last_stem_pos = None; - let mut delta = 0; - // Now align all other stem edges - // This code starts at: - for edge_ix in 0..axis.edges.len() { - let edges = axis.edges.as_mut_slice(); - let edge = &edges[edge_ix]; - if edge.flags & Edge::DONE != 0 { - continue; - } - // Skip all non-stem edges - let Some(edge2_ix) = edge.link_ix.map(|ix| ix as usize) else { - serif_count += 1; - continue; - }; - // For CJK, skip stems that are too close. We'll deal with them later - // See - if group != ScriptGroup::Default { - if let Some(last_pos) = last_stem_pos { - if edge.pos < last_pos + 64 || edges[edge2_ix].pos < last_pos + 64 { - serif_count += 1; - continue; - } - } - } - // This shouldn't happen? - if edges[edge2_ix].blue_edge.is_some() { - edges[edge2_ix].flags |= Edge::DONE; - align_linked_edge(axis, metrics, group, scale, edge2_ix, edge_ix); - continue; - } - if group == ScriptGroup::Default { - // Now align the stem - // Note: the branches here are reversed from the FreeType code - // See - if let Some(anchor_ix) = anchor_ix { - let anchor = &edges[anchor_ix]; - let edge = edges[edge_ix]; - let edge2 = edges[edge2_ix]; - let original_pos = anchor.pos + (edge.opos - anchor.opos); - let original_len = edge2.opos - edge.opos; - let original_center = original_pos + (original_len >> 1); - let cur_len = stem_width( - metrics, - group, - scale, - original_len, - 0, - edge.flags, - edge2.flags, - ); - if edge2.flags & Edge::DONE != 0 { - let new_pos = edge2.pos - cur_len; - edges[edge_ix].pos = new_pos; - } else if cur_len < 96 { - let cur_pos1 = pix_round(original_center); - let (u_off, d_off) = if cur_len <= 64 { (32, 32) } else { (38, 26) }; - let delta1 = (original_center - (cur_pos1 - u_off)).abs(); - let delta2 = (original_center - (cur_pos1 + d_off)).abs(); - let cur_pos1 = if delta1 < delta2 { - cur_pos1 - u_off - } else { - cur_pos1 + d_off - }; - edges[edge_ix].pos = cur_pos1 - cur_len / 2; - edges[edge2_ix].pos = cur_pos1 + cur_len / 2; - } else { - let cur_pos1 = pix_round(original_pos); - let delta1 = (cur_pos1 + (cur_len >> 1) - original_center).abs(); - let cur_pos2 = pix_round(original_pos + original_len) - cur_len; - let delta2 = (cur_pos2 + (cur_len >> 1) - original_center).abs(); - let new_pos = if delta1 < delta2 { cur_pos1 } else { cur_pos2 }; - let new_pos2 = new_pos + cur_len; - edges[edge_ix].pos = new_pos; - edges[edge2_ix].pos = new_pos2; - } - edges[edge_ix].flags |= Edge::DONE; - edges[edge2_ix].flags |= Edge::DONE; - if edge_ix > 0 { - adjust_link(edges, edge_ix, LinkDir::Prev, top_to_bottom_hinting); - } - } else { - // No stem has been aligned yet - let edge = edges[edge_ix]; - let edge2 = edges[edge2_ix]; - let original_len = edge2.opos - edge.opos; - let cur_len = stem_width( - metrics, - group, - scale, - original_len, - 0, - edge.flags, - edge2.flags, - ); - // Some "voodoo" to specially round edges for small stem widths - let (u_off, d_off) = if cur_len <= 64 { - // width <= 1px - (32, 32) - } else { - // 1px < width < 1.5px - (38, 26) - }; - if cur_len < 96 { - let original_center = edge.opos + (original_len >> 1); - let mut cur_pos1 = pix_round(original_center); - let error1 = (original_center - (cur_pos1 - u_off)).abs(); - let error2 = (original_center - (cur_pos1 + d_off)).abs(); - if error1 < error2 { - cur_pos1 -= u_off; - } else { - cur_pos1 += d_off; - } - let edge_pos = cur_pos1 - cur_len / 2; - edges[edge_ix].pos = edge_pos; - edges[edge2_ix].pos = edge_pos + cur_len; - } else { - edges[edge_ix].pos = pix_round(edge.opos); - } - edges[edge_ix].flags |= Edge::DONE; - align_linked_edge(axis, metrics, group, scale, edge_ix, edge2_ix); - anchor_ix = Some(edge_ix); - } - } else { - // More CJK divergence - // See - if edge2_ix < edge_ix { - last_stem_pos = Some(edge.pos); - edges[edge_ix].flags |= Edge::DONE; - align_linked_edge(axis, metrics, group, scale, edge2_ix, edge_ix); - continue; - } - if axis.dim != Axis::VERTICAL && anchor_ix.is_none() { - delta = hint_normal_stem_cjk(axis, metrics, group, scale, edge_ix, edge2_ix, delta); - } else { - hint_normal_stem_cjk(axis, metrics, group, scale, edge_ix, edge2_ix, delta); - } - anchor_ix = Some(edge_ix); - axis.edges[edge_ix].flags |= Edge::DONE; - let edge2 = &mut axis.edges[edge2_ix]; - edge2.flags |= Edge::DONE; - last_stem_pos = Some(edge2.pos); - } - } - (serif_count, anchor_ix) -} - -/// Make sure that lowercase m's maintain symmetry. -/// -/// See -fn hint_lowercase_m(edges: &mut [Edge], group: ScriptGroup) { - let (edge1_ix, edge2_ix, edge3_ix) = if edges.len() == 6 { - (0, 2, 4) - } else { - (1, 5, 9) - }; - let edge1 = &edges[edge1_ix]; - let edge2 = &edges[edge2_ix]; - let edge3 = &edges[edge3_ix]; - let dist1 = edge2.opos - edge1.opos; - let dist2 = edge3.opos - edge2.opos; - let span = (dist1 - dist2).abs(); - if group != ScriptGroup::Default { - // CJK has additional conditions on the following... - // See - for (edge, ix) in [(edge1, edge1_ix), (edge2, edge2_ix), (edge3, edge3_ix)] { - if edge.link_ix != Some((ix + 1) as u16) { - return; - } - } - } - if span < 8 { - let delta = edge3.pos - (2 * edge2.pos - edge1.pos); - let link_ix = edge3.link_ix.map(|ix| ix as usize); - let edge3 = &mut edges[edge3_ix]; - edge3.pos -= delta; - edge3.flags |= Edge::DONE; - if let Some(link_ix) = link_ix { - let link = &mut edges[link_ix]; - link.pos -= delta; - link.flags |= Edge::DONE; - } - // Move serifs along with the stem - if edges.len() == 12 { - edges[8].pos -= delta; - edges[11].pos -= delta; - } - } -} - -/// Align serif and single segment edges. -fn align_remaining_edges( - axis: &mut Axis, - group: ScriptGroup, - top_to_bottom_hinting: bool, - mut serif_count: usize, - mut anchor_ix: Option, -) { - if group == ScriptGroup::Default { - // See - for edge_ix in 0..axis.edges.len() { - let edges = &mut axis.edges; - let edge = &edges[edge_ix]; - if edge.flags & Edge::DONE != 0 { - continue; - } - let mut delta = 1000; - if let Some(serif) = edge.serif(edges) { - delta = (serif.opos - edge.opos).abs(); - } - if delta < 64 + 16 { - // delta is only < 1000 if edge.serif_ix is Some(_) - let serif_ix = edge.serif_ix.unwrap() as usize; - align_serif_edge(axis, serif_ix, edge_ix) - } else if let Some(anchor_ix) = anchor_ix { - let [before_ix, after_ix] = find_bounding_completed_edges(edges, edge_ix); - if let Some((before_ix, after_ix)) = before_ix.zip(after_ix) { - let before = &edges[before_ix]; - let after = &edges[after_ix]; - let new_pos = if after.opos == before.opos { - before.pos - } else { - before.pos - + fixed_mul_div( - edge.opos - before.opos, - after.pos - before.pos, - after.opos - before.opos, - ) - }; - edges[edge_ix].pos = new_pos; - } else { - let anchor = &edges[anchor_ix]; - let new_pos = anchor.pos + ((edge.opos - anchor.opos + 16) & !31); - edges[edge_ix].pos = new_pos; - } - } else { - anchor_ix = Some(edge_ix); - let new_pos = pix_round(edge.opos); - edges[edge_ix].pos = new_pos; - } - let edges = &mut axis.edges; - edges[edge_ix].flags |= Edge::DONE; - adjust_link(edges, edge_ix, LinkDir::Prev, top_to_bottom_hinting); - adjust_link(edges, edge_ix, LinkDir::Next, top_to_bottom_hinting); - } - } else { - // See - for edge_ix in 0..axis.edges.len() { - let edge = &mut axis.edges[edge_ix]; - if edge.flags & Edge::DONE != 0 { - continue; - } - if let Some(serif_ix) = edge.serif_ix.map(|ix| ix as usize) { - edge.flags |= Edge::DONE; - align_serif_edge(axis, serif_ix, edge_ix); - serif_count = serif_count.saturating_sub(1); - } - } - if serif_count == 0 { - return; - } - for edge_ix in 0..axis.edges.len() { - let edges = axis.edges.as_mut_slice(); - let edge = &edges[edge_ix]; - if edge.flags & Edge::DONE != 0 { - continue; - } - let [before_ix, after_ix] = find_bounding_completed_edges(edges, edge_ix); - match (before_ix, after_ix) { - (Some(before_ix), None) => { - align_serif_edge(axis, before_ix, edge_ix); - } - (None, Some(after_ix)) => { - align_serif_edge(axis, after_ix, edge_ix); - } - (Some(before_ix), Some(after_ix)) => { - let before = edges[before_ix]; - let after = edges[after_ix]; - if after.fpos == before.fpos { - edges[edge_ix].pos = before.pos; - } else { - edges[edge_ix].pos = before.pos - + fixed_mul_div( - edge.fpos as i32 - before.fpos as i32, - after.pos - before.pos, - after.fpos as i32 - before.fpos as i32, - ); - } - } - _ => {} - } - } - } -} - -#[derive(Copy, Clone, PartialEq)] -enum LinkDir { - Prev, - Next, -} - -/// Helper to adjust links based on hinting direction. -/// -/// See -fn adjust_link( - edges: &mut [Edge], - edge_ix: usize, - link_dir: LinkDir, - top_to_bottom_hinting: bool, -) -> Option<()> { - let edge = &edges[edge_ix]; - let (edge2, prev_edge) = if link_dir == LinkDir::Next { - let edge2 = edges.get(edge_ix + 1)?; - // Don't adjust next edge if it's not done yet - if edge2.flags & Edge::DONE == 0 { - return None; - } - (edge2, edges.get(edge_ix.checked_sub(1)?)?) - } else { - let edge = edges.get(edge_ix.checked_sub(1)?)?; - (edge, edge) - }; - let pos1 = edge.pos; - let pos2 = edge2.pos; - let order_check = match (link_dir, top_to_bottom_hinting) { - (LinkDir::Prev, true) | (LinkDir::Next, false) => pos1 > pos2, - (LinkDir::Prev, false) | (LinkDir::Next, true) => pos1 < pos2, - }; - if !order_check { - return None; - } - let link = edge.link(edges)?; - if (link.pos - prev_edge.pos).abs() > 16 { - let new_pos = edge2.pos; - edges[edge_ix].pos = new_pos; - } - Some(()) -} - -/// Returns the indices of the "completed" edges before and after the given -/// edge index. -fn find_bounding_completed_edges(edges: &[Edge], ix: usize) -> [Option; 2] { - let before_ix = edges - .get(..ix) - .unwrap_or_default() - .iter() - .enumerate() - .rev() - .filter_map(|(ix, edge)| (edge.flags & Edge::DONE != 0).then_some(ix)) - .next(); - let after_ix = edges - .iter() - .enumerate() - .skip(ix + 1) - .filter_map(|(ix, edge)| (edge.flags & Edge::DONE != 0).then_some(ix)) - .next(); - [before_ix, after_ix] -} - -/// Snap a scaled width to one of the standard widths. -/// -/// See -fn snap_width(widths: &[ScaledWidth], width: i32) -> i32 { - let (_, ref_width) = - widths - .iter() - .fold((64 + 32 + 2, width), |(best_dist, ref_width), candidate| { - let dist = (width - candidate.scaled).abs(); - if dist < best_dist { - (dist, candidate.scaled) - } else { - (best_dist, ref_width) - } - }); - let scaled = pix_round(ref_width); - if width >= ref_width { - if width < scaled + 48 { - ref_width - } else { - width - } - } else if width > scaled - 48 { - ref_width - } else { - width - } -} - -/// Compute the snapped width of a given stem. -/// -/// See -fn stem_width( - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, - width: i32, - base_delta: i32, - base_flags: u8, - stem_flags: u8, -) -> i32 { - if scale.flags & Scale::STEM_ADJUST == 0 - || (group == ScriptGroup::Default && metrics.width_metrics.is_extra_light) - { - return width; - } - let is_vertical = metrics.dim == Axis::VERTICAL; - let sign = if width < 0 { -1 } else { 1 }; - let mut dist = width.abs(); - if (is_vertical && scale.flags & Scale::VERTICAL_SNAP == 0) - || (!is_vertical && scale.flags & Scale::HORIZONTAL_SNAP == 0) - { - // Do smooth hinting - if group == ScriptGroup::Default { - if (stem_flags & Edge::SERIF != 0) && is_vertical && (dist < 3 * 64) { - // Don't touch widths of serifs - return dist * sign; - } else if base_flags & Edge::ROUND != 0 { - if dist < 80 { - dist = 64; - } - } else if dist < 56 { - dist = 56; - } - } - if !metrics.widths.is_empty() { - // Compare to standard width - let min_width = metrics.widths[0].scaled; - let delta = (dist - min_width).abs(); - if delta < 40 { - dist = min_width.max(48); - return dist * sign; - } - if group == ScriptGroup::Default { - // Default/Latin behavior - // See - if dist < 3 * 64 { - let delta = dist & 63; - dist &= -64; - if delta < 10 { - dist += delta; - } else if delta < 32 { - dist += 10; - } else if delta < 54 { - dist += 54; - } else { - dist += delta; - } - } else { - let mut new_base_delta = 0; - if (width > 0 && base_delta > 0) || (width < 0 && base_delta < 0) { - if scale.size < 10.0 { - new_base_delta = base_delta; - } else if scale.size < 30.0 { - new_base_delta = (base_delta * (30.0 - scale.size) as i32) / 20; - } - } - dist = (dist - new_base_delta.abs() + 32) & !63; - } - } - } - if group != ScriptGroup::Default { - // Divergent CJK behavior - // See - if dist < 54 { - dist += (54 - dist) / 2; - } else if dist < 3 * 64 { - let delta = dist & 63; - dist &= -64; - if delta < 10 { - dist += delta; - } else if delta < 22 { - dist += 10; - } else if delta < 42 { - dist += delta; - } else if delta < 54 { - dist += 54; - } else { - dist += delta; - } - } - } - } else { - // Do strong hinting: snap to integer pixels - let original_dist = dist; - dist = snap_width(&metrics.widths, dist); - if is_vertical { - // Always round to integers in the vertical case - if dist >= 64 { - dist = (dist + 16) & !63; - } else { - dist = 64; - } - } else if scale.flags & Scale::MONO != 0 { - // Mono horizontal hinting: snap to integer with different - // threshold - if dist < 64 { - dist = 64; - } else { - dist = (dist + 32) & !63; - } - } else { - // Smooth horizontal hinting: strengthen small stems, round - // stems whose size is between 1 and 2 pixels - if dist < 48 { - dist = (dist + 64) >> 1; - } else if dist < 128 { - // Only round to integer if distortion is less than - // 1/4 pixel - dist = (dist + 22) & !63; - if group == ScriptGroup::Default { - // See - let delta = (dist - original_dist).abs(); - if delta >= 16 { - dist = original_dist; - if dist < 48 { - dist = (dist + 64) >> 1; - } - } - } - } else { - // Round otherwise to prevent color fringes in LCD mode - dist = (dist + 32) & !63; - } - } - } - dist * sign -} - -/// Align one stem edge relative to previous stem edge. -/// -/// See -fn align_linked_edge( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, - base_edge_ix: usize, - stem_edge_ix: usize, -) { - let edges = axis.edges.as_mut_slice(); - let base_edge = &edges[base_edge_ix]; - let stem_edge = &edges[stem_edge_ix]; - let width = stem_edge.opos - base_edge.opos; - let base_delta = base_edge.pos - base_edge.opos; - let fitted_width = stem_width( - metrics, - group, - scale, - width, - base_delta, - base_edge.flags, - stem_edge.flags, - ); - edges[stem_edge_ix].pos = base_edge.pos + fitted_width; -} - -/// Shift the serif edge by the adjustment made to base edge. -/// -/// See -fn align_serif_edge(axis: &mut Axis, base_edge_ix: usize, serif_edge_ix: usize) { - let edges = axis.edges.as_mut_slice(); - let base_edge = &edges[base_edge_ix]; - let serif_edge = &edges[serif_edge_ix]; - edges[serif_edge_ix].pos = base_edge.pos + (serif_edge.opos - base_edge.opos); -} - -/// Adjusts both edges of a stem and returns the delta. -/// -/// See -fn hint_normal_stem_cjk( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - group: ScriptGroup, - scale: &Scale, - edge_ix: usize, - edge2_ix: usize, - anchor: i32, -) -> i32 { - const MAX_HORIZONTAL_GAP: i32 = 9; - const MAX_VERTICAL_GAP: i32 = 15; - const MAX_DELTA_ABS: i32 = 14; - let edge = axis.edges[edge_ix]; - let edge2 = axis.edges[edge2_ix]; - let do_stem_adjust = scale.flags & Scale::STEM_ADJUST != 0; - let threshold_delta = if do_stem_adjust { - 0 - } else { - let delta = if axis.dim == Axis::VERTICAL { - MAX_HORIZONTAL_GAP - } else { - MAX_VERTICAL_GAP - }; - if edge.flags & Edge::ROUND != 0 && edge2.flags & Edge::ROUND != 0 { - delta - } else { - delta / 3 - } - }; - let threshold = 64 - threshold_delta; - let original_len = edge2.opos - edge.opos; - let cur_len = stem_width( - metrics, - group, - scale, - original_len, - 0, - edge.flags, - edge2.flags, - ); - let original_center = (edge.opos + edge2.opos) / 2 + anchor; - let cur_pos1 = original_center - cur_len / 2; - let cur_pos2 = cur_pos1 + cur_len; - let mut finish = |mut delta: i32| { - if !do_stem_adjust { - delta = delta.clamp(-MAX_DELTA_ABS, MAX_DELTA_ABS); - } - let adjustment = cur_pos1 + delta; - if edge.opos < edge2.opos { - axis.edges[edge_ix].pos = adjustment; - axis.edges[edge2_ix].pos = adjustment + cur_len; - } else { - axis.edges[edge2_ix].pos = adjustment; - axis.edges[edge_ix].pos = adjustment + cur_len; - } - delta - }; - let mut d_off1 = cur_pos1 - pix_floor(cur_pos1); - let mut d_off2 = cur_pos2 - pix_floor(cur_pos2); - let mut delta = 0; - if d_off1 == 0 || d_off2 == 0 { - return finish(delta); - } - let mut u_off1 = 64 - d_off1; - let mut u_off2 = 64 - d_off2; - if cur_len <= threshold { - if d_off2 < cur_len { - delta = if u_off1 <= d_off2 { u_off1 } else { -d_off2 }; - } - return finish(delta); - } - if threshold < 64 - && (d_off1 >= threshold - || u_off1 >= threshold - || d_off2 >= threshold - || u_off2 >= threshold) - { - return finish(delta); - } - let mut offset = cur_len & 63; - if offset < 32 { - if u_off1 <= offset || d_off2 <= offset { - return finish(delta); - } - } else { - offset = 64 - threshold; - } - d_off1 = threshold - u_off1; - u_off1 -= offset; - u_off2 = threshold - d_off2; - d_off2 -= offset; - if d_off1 <= u_off1 { - u_off1 = -d_off1; - } - if d_off2 <= u_off2 { - u_off2 = -d_off2; - } - if u_off1.abs() <= u_off2.abs() { - delta = u_off1; - } else { - delta = u_off2; - } - finish(delta) -} - -#[cfg(test)] -mod tests { - use super::{ - super::super::{ - metrics, - outline::Outline, - shape::{Shaper, ShaperMode}, - style, topo, - }, - *, - }; - use crate::{attribute::Style, MetadataProvider}; - use raw::{types::GlyphId, FontRef, TableProvider}; - - #[test] - fn edge_hinting_default() { - let expected_h_edges = [ - (0, Edge::DONE | Edge::ROUND), - (133, Edge::DONE), - (187, Edge::DONE), - (192, Edge::DONE | Edge::ROUND), - ]; - let expected_v_edges = [ - (-256, Edge::DONE), - (463, Edge::DONE), - (576, Edge::DONE | Edge::ROUND | Edge::SERIF), - (633, Edge::DONE), - ]; - check_edges( - font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, - GlyphId::new(9), - style::StyleClass::HEBR, - &expected_h_edges, - &expected_v_edges, - ); - } - - #[test] - fn edge_hinting_cjk() { - let expected_h_edges = [ - (128, Edge::DONE), - (193, Edge::DONE), - (473, 0), - (594, 0), - (704, Edge::DONE), - (673, Edge::DONE), - (767, Edge::DONE), - (832, Edge::DONE), - (896, Edge::DONE), - ]; - let expected_v_edges = [ - (-64, Edge::DONE | Edge::ROUND), - (15, Edge::ROUND), - (142, Edge::ROUND), - (546, Edge::DONE), - (624, Edge::DONE), - (576, Edge::DONE), - (720, Edge::DONE), - (768, Edge::DONE), - (799, Edge::ROUND), - ]; - check_edges( - font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, - GlyphId::new(9), - style::StyleClass::HANI, - &expected_h_edges, - &expected_v_edges, - ); - } - - fn check_edges( - font_data: &[u8], - glyph_id: GlyphId, - class: usize, - expected_h_edges: &[(i32, u8)], - expected_v_edges: &[(i32, u8)], - ) { - let font = FontRef::new(font_data).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let class = &style::STYLE_CLASSES[class]; - let unscaled_metrics = - metrics::compute_unscaled_style_metrics(&shaper, Default::default(), class); - let scale = metrics::Scale::new( - 16.0, - font.head().unwrap().units_per_em() as i32, - Style::Normal, - Default::default(), - class.script.group, - ); - let scaled_metrics = metrics::scale_style_metrics(&unscaled_metrics, scale); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(glyph_id).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axes = [ - Axis::new(Axis::HORIZONTAL, outline.orientation), - Axis::new(Axis::VERTICAL, outline.orientation), - ]; - for (dim, axis) in axes.iter_mut().enumerate() { - topo::compute_segments(&mut outline, axis, class.script.group); - topo::link_segments( - &outline, - axis, - scaled_metrics.axes[dim].scale, - class.script.group, - unscaled_metrics.axes[dim].max_width(), - ); - topo::compute_edges( - axis, - &scaled_metrics.axes[0], - class.script.hint_top_to_bottom, - scaled_metrics.axes[1].scale, - class.script.group, - ); - if dim == Axis::VERTICAL { - topo::compute_blue_edges( - axis, - &scale, - &unscaled_metrics.axes[dim].blues, - &scaled_metrics.axes[dim].blues, - class.script.group, - ); - } - hint_edges( - axis, - &scaled_metrics.axes[dim], - class.script.group, - &scale, - class.script.hint_top_to_bottom, - ); - } - // Only pos and flags fields are modified by edge hinting - let h_edges = axes[Axis::HORIZONTAL] - .edges - .iter() - .map(|edge| (edge.pos, edge.flags)) - .collect::>(); - let v_edges = axes[Axis::VERTICAL] - .edges - .iter() - .map(|edge| (edge.pos, edge.flags)) - .collect::>(); - assert_eq!(h_edges, expected_h_edges); - assert_eq!(v_edges, expected_v_edges); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,119 +0,0 @@ -//! Entry point to hinting algorithm. - -mod edges; -mod outline; - -use super::{ - metrics::{scale_style_metrics, Scale, UnscaledStyleMetrics}, - outline::Outline, - style::{GlyphStyle, ScriptGroup}, - topo::{self, Axis}, -}; - -/// Captures adjusted horizontal scale and outer edge positions to be used -/// for horizontal metrics adjustments. -#[derive(Copy, Clone, PartialEq, Default, Debug)] -pub(crate) struct EdgeMetrics { - pub left_opos: i32, - pub left_pos: i32, - pub right_opos: i32, - pub right_pos: i32, -} - -#[derive(Copy, Clone, PartialEq, Default, Debug)] -pub(crate) struct HintedMetrics { - pub x_scale: i32, - /// This will be `None` when we've identified fewer than two horizontal - /// edges in the outline. This will occur for empty outlines and outlines - /// that are degenerate (all x coordinates have the same value, within - /// a threshold). In these cases, horizontal metrics will not be adjusted. - pub edge_metrics: Option, -} - -/// Applies the complete hinting process to a latin outline. -/// -/// See -pub(crate) fn hint_outline( - outline: &mut Outline, - metrics: &UnscaledStyleMetrics, - scale: &Scale, - glyph_style: Option, -) -> HintedMetrics { - let scaled_metrics = scale_style_metrics(metrics, *scale); - let scale = &scaled_metrics.scale; - let mut axis = Axis::default(); - let hint_top_to_bottom = metrics.style_class().script.hint_top_to_bottom; - outline.scale(&scaled_metrics.scale); - let mut hinted_metrics = HintedMetrics { - x_scale: scale.x_scale, - ..Default::default() - }; - let group = metrics.style_class().script.group; - // For default script group, we don't proceed with hinting if we're - // missing alignment zones. FreeType swaps in a "dummy" hinter here - // See - if group == ScriptGroup::Default && scaled_metrics.axes[1].blues.is_empty() { - return hinted_metrics; - } - for dim in 0..2 { - if (dim == Axis::HORIZONTAL && scale.flags & Scale::NO_HORIZONTAL != 0) - || (dim == Axis::VERTICAL && scale.flags & Scale::NO_VERTICAL != 0) - { - continue; - } - axis.reset(dim, outline.orientation); - topo::compute_segments(outline, &mut axis, group); - topo::link_segments( - outline, - &mut axis, - scaled_metrics.axes[dim].scale, - group, - metrics.axes[dim].max_width(), - ); - topo::compute_edges( - &mut axis, - &scaled_metrics.axes[dim], - hint_top_to_bottom, - scaled_metrics.scale.y_scale, - group, - ); - if dim == Axis::VERTICAL { - if group != ScriptGroup::Default - || glyph_style - .map(|style| !style.is_non_base()) - .unwrap_or(true) - { - topo::compute_blue_edges( - &mut axis, - scale, - &metrics.axes[dim].blues, - &scaled_metrics.axes[dim].blues, - group, - ); - } - } else { - hinted_metrics.x_scale = scaled_metrics.axes[0].scale; - } - edges::hint_edges( - &mut axis, - &scaled_metrics.axes[dim], - group, - scale, - hint_top_to_bottom, - ); - outline::align_edge_points(outline, &axis, group, scale); - outline::align_strong_points(outline, &mut axis); - outline::align_weak_points(outline, dim); - if dim == 0 && axis.edges.len() > 1 { - let left = axis.edges.first().unwrap(); - let right = axis.edges.last().unwrap(); - hinted_metrics.edge_metrics = Some(EdgeMetrics { - left_pos: left.pos, - left_opos: left.opos, - right_pos: right.pos, - right_opos: right.opos, - }); - } - } - hinted_metrics -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,661 +0,0 @@ -//! Apply edge hints to an outline. -//! -//! This happens in three passes: -//! 1. Align points that are directly attached to edges. These are the points -//! which originally generated the edge and are coincident with the edge -//! coordinate (within a threshold) for a given axis. This may include -//! points that were originally classified as weak. -//! 2. Interpolate non-weak points that were not touched by the previous pass. -//! This searches for the edges that enclose the point and interpolates the -//! coordinate based on the adjustment applied to those edges. -//! 3. Interpolate remaining untouched points. These are generally the weak -//! points: those that are very near other points or lacking a dominant -//! inward or outward direction. -//! -//! The final result is a fully hinted outline. - -use super::super::{ - metrics::{fixed_div, fixed_mul, Scale}, - outline::{Outline, Point}, - style::ScriptGroup, - topo::{Axis, Dimension}, -}; -use core::cmp::Ordering; -use raw::tables::glyf::PointMarker; - -/// Align all points of an edge to the same coordinate value. -/// -/// See -pub(crate) fn align_edge_points( - outline: &mut Outline, - axis: &Axis, - group: ScriptGroup, - scale: &Scale, -) -> Option<()> { - let edges = axis.edges.as_slice(); - let segments = axis.segments.as_slice(); - let points = outline.points.as_mut_slice(); - // Snapping is configurable for CJK - // See - let snap = group == ScriptGroup::Default - || ((axis.dim == Axis::HORIZONTAL && scale.flags & Scale::HORIZONTAL_SNAP != 0) - || (axis.dim == Axis::VERTICAL && scale.flags & Scale::VERTICAL_SNAP != 0)); - for segment in segments { - let Some(edge) = segment.edge(edges) else { - continue; - }; - let delta = edge.pos - edge.opos; - let mut point_ix = segment.first(); - let last_ix = segment.last(); - loop { - let point = points.get_mut(point_ix)?; - if axis.dim == Axis::HORIZONTAL { - if snap { - point.x = edge.pos; - } else { - point.x += delta; - } - point.flags.set_marker(PointMarker::TOUCHED_X); - } else { - if snap { - point.y = edge.pos; - } else { - point.y += delta; - } - point.flags.set_marker(PointMarker::TOUCHED_Y); - } - if point_ix == last_ix { - break; - } - point_ix = point.next(); - } - } - Some(()) -} - -/// Align the strong points; equivalent to the TrueType `IP` instruction. -/// -/// See -pub(crate) fn align_strong_points(outline: &mut Outline, axis: &mut Axis) -> Option<()> { - if axis.edges.is_empty() { - return Some(()); - } - let dim = axis.dim; - let touch_flag = if dim == Axis::HORIZONTAL { - PointMarker::TOUCHED_X - } else { - PointMarker::TOUCHED_Y - }; - let points = outline.points.as_mut_slice(); - 'points: for point in points { - // Skip points that are already touched; do weak interpolation in the - // next pass - if point - .flags - .has_marker(touch_flag | PointMarker::WEAK_INTERPOLATION) - { - continue; - } - let (u, ou) = if dim == Axis::VERTICAL { - (point.fy, point.oy) - } else { - (point.fx, point.ox) - }; - let edges = axis.edges.as_mut_slice(); - // Is the point before the first edge? - let edge = edges.first()?; - let delta = edge.fpos as i32 - u; - if delta >= 0 { - store_point(point, dim, edge.pos - (edge.opos - ou)); - continue; - } - // Is the point after the last edge? - let edge = edges.last()?; - let delta = u - edge.fpos as i32; - if delta >= 0 { - store_point(point, dim, edge.pos + (ou - edge.opos)); - continue; - } - // Find enclosing edges; for a small number of edges, use a linear - // search. - // Note: this is actually critical for matching FreeType in cases where - // we have more than one edge with the same fpos. When this happens, - // linear and binary searches can produce different results. - // See - let min_ix = if edges.len() <= 8 { - if let Some((min_ix, edge)) = edges - .iter() - .enumerate() - .find(|(_ix, edge)| edge.fpos as i32 >= u) - { - if edge.fpos as i32 == u { - store_point(point, dim, edge.pos); - continue 'points; - } - min_ix - } else { - 0 - } - } else { - let mut min_ix = 0; - let mut max_ix = edges.len(); - while min_ix < max_ix { - let mid_ix = (min_ix + max_ix) >> 1; - let edge = &edges[mid_ix]; - let fpos = edge.fpos as i32; - match u.cmp(&fpos) { - Ordering::Less => max_ix = mid_ix, - Ordering::Greater => min_ix = mid_ix + 1, - Ordering::Equal => { - // We are on an edge - store_point(point, dim, edge.pos); - continue 'points; - } - } - } - min_ix - }; - // Point is not on an edge - if let Some(before_ix) = min_ix.checked_sub(1) { - let edge_before = edges.get(before_ix)?; - let before_pos = edge_before.pos; - let before_fpos = edge_before.fpos as i32; - let scale = if edge_before.scale == 0 { - let edge_after = edges.get(min_ix)?; - let scale = fixed_div( - edge_after.pos - edge_before.pos, - edge_after.fpos as i32 - before_fpos, - ); - edges[before_ix].scale = scale; - scale - } else { - edge_before.scale - }; - store_point(point, dim, before_pos + fixed_mul(u - before_fpos, scale)); - } - } - Some(()) -} - -/// Align the weak points; equivalent to the TrueType `IUP` instruction. -/// -/// See -pub(crate) fn align_weak_points(outline: &mut Outline, dim: Dimension) -> Option<()> { - let touch_marker = if dim == Axis::HORIZONTAL { - for point in &mut outline.points { - point.u = point.x; - point.v = point.ox; - } - PointMarker::TOUCHED_X - } else { - for point in &mut outline.points { - point.u = point.y; - point.v = point.oy; - } - PointMarker::TOUCHED_Y - }; - for contour in &outline.contours { - let points = outline.points.get_mut(contour.range())?; - // Find first touched point - let Some(first_touched_ix) = points - .iter() - .position(|point| point.flags.has_marker(touch_marker)) - else { - continue; - }; - let last_ix = points.len() - 1; - let mut point_ix = first_touched_ix; - let mut last_touched_ix; - 'outer: loop { - // Skip any touched neighbors - while point_ix < last_ix && points.get(point_ix + 1)?.flags.has_marker(touch_marker) { - point_ix += 1; - } - last_touched_ix = point_ix; - // Find the next touched point - point_ix += 1; - loop { - if point_ix > last_ix { - break 'outer; - } - if points[point_ix].flags.has_marker(touch_marker) { - break; - } - point_ix += 1; - } - iup_interpolate( - points, - last_touched_ix + 1, - point_ix - 1, - last_touched_ix, - point_ix, - ); - } - if last_touched_ix == first_touched_ix { - // Special case: only one point was touched - iup_shift(points, 0, last_ix, first_touched_ix); - } else { - // Interpolate the remainder - if last_touched_ix < last_ix { - iup_interpolate( - points, - last_touched_ix + 1, - last_ix, - last_touched_ix, - first_touched_ix, - ); - } - if first_touched_ix > 0 { - iup_interpolate( - points, - 0, - first_touched_ix - 1, - last_touched_ix, - first_touched_ix, - ); - } - } - } - // Save interpolated values - if dim == Axis::HORIZONTAL { - for point in &mut outline.points { - point.x = point.u; - } - } else { - for point in &mut outline.points { - point.y = point.u; - } - } - Some(()) -} - -#[inline(always)] -fn store_point(point: &mut Point, dim: Dimension, u: i32) { - if dim == Axis::HORIZONTAL { - point.x = u; - point.flags.set_marker(PointMarker::TOUCHED_X); - } else { - point.y = u; - point.flags.set_marker(PointMarker::TOUCHED_Y); - } -} - -/// Shift original coordinates of all points between `p1_ix` and `p2_ix` -/// (inclusive) to get hinted coordinates using the same difference as -/// given by the point at `ref_ix`. -/// -/// The `u` and `v` members are the current and original coordinate values, -/// respectively. -/// -/// See -fn iup_shift(points: &mut [Point], p1_ix: usize, p2_ix: usize, ref_ix: usize) -> Option<()> { - let ref_point = points.get(ref_ix)?; - let delta = ref_point.u - ref_point.v; - if delta == 0 { - return Some(()); - } - for point in points.get_mut(p1_ix..ref_ix)? { - point.u = point.v + delta; - } - for point in points.get_mut(ref_ix + 1..=p2_ix)? { - point.u = point.v + delta; - } - Some(()) -} - -/// Interpolate the original coordinates all of points between `p1_ix` and -/// `p2_ix` (inclusive) to get hinted coordinates, using the points at -/// `ref1_ix` and `ref2_ix` as the reference points. -/// -/// The `u` and `v` members are the current and original coordinate values, -/// respectively. -/// -/// See -fn iup_interpolate( - points: &mut [Point], - p1_ix: usize, - p2_ix: usize, - ref1_ix: usize, - ref2_ix: usize, -) -> Option<()> { - if p1_ix > p2_ix { - return Some(()); - } - let mut ref_point1 = points.get(ref1_ix)?; - let mut ref_point2 = points.get(ref2_ix)?; - if ref_point1.v > ref_point2.v { - core::mem::swap(&mut ref_point1, &mut ref_point2); - } - let (u1, v1) = (ref_point1.u, ref_point1.v); - let (u2, v2) = (ref_point2.u, ref_point2.v); - let d1 = u1 - v1; - let d2 = u2 - v2; - if u1 == u2 || v1 == v2 { - for point in points.get_mut(p1_ix..=p2_ix)? { - point.u = if point.v <= v1 { - point.v + d1 - } else if point.v >= v2 { - point.v + d2 - } else { - u1 - }; - } - } else { - let scale = fixed_div(u2 - u1, v2 - v1); - for point in points.get_mut(p1_ix..=p2_ix)? { - point.u = if point.v <= v1 { - point.v + d1 - } else if point.v >= v2 { - point.v + d2 - } else { - u1 + fixed_mul(point.v - v1, scale) - }; - } - } - Some(()) -} - -#[cfg(test)] -mod tests { - use super::{ - super::super::{ - metrics::{compute_unscaled_style_metrics, Scale}, - shape::{Shaper, ShaperMode}, - style, - }, - super::{EdgeMetrics, HintedMetrics}, - *, - }; - use crate::{attribute::Style, MetadataProvider}; - use raw::{ - types::{F2Dot14, GlyphId}, - FontRef, TableProvider, - }; - - #[test] - fn hinted_coords_and_metrics_default() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let (outline, metrics) = hint_outline( - &font, - 16.0, - Default::default(), - GlyphId::new(9), - &style::STYLE_CLASSES[style::StyleClass::HEBR], - ); - // Expected values were painfully extracted from FreeType with some - // printf debugging - #[rustfmt::skip] - let expected_coords = [ - (133, -256), - (133, 282), - (133, 343), - (146, 431), - (158, 463), - (158, 463), - (57, 463), - (30, 463), - (0, 495), - (0, 534), - (0, 548), - (2, 570), - (11, 604), - (17, 633), - (50, 633), - (50, 629), - (50, 604), - (77, 576), - (101, 576), - (163, 576), - (180, 576), - (192, 562), - (192, 542), - (192, 475), - (190, 457), - (187, 423), - (187, 366), - (187, 315), - (187, -220), - (178, -231), - (159, -248), - (146, -256), - ]; - let coords = outline - .points - .iter() - .map(|point| (point.x, point.y)) - .collect::>(); - assert_eq!(coords, expected_coords); - let expected_metrics = HintedMetrics { - x_scale: 67109, - edge_metrics: Some(EdgeMetrics { - left_opos: 15, - left_pos: 0, - right_opos: 210, - right_pos: 192, - }), - }; - assert_eq!(metrics, expected_metrics); - } - - #[test] - fn hinted_coords_and_metrics_cjk() { - let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); - let (outline, metrics) = hint_outline( - &font, - 16.0, - Default::default(), - GlyphId::new(9), - &style::STYLE_CLASSES[style::StyleClass::HANI], - ); - // Expected values were painfully extracted from FreeType with some - // printf debugging - let expected_coords = [ - (279, 768), - (568, 768), - (618, 829), - (618, 829), - (634, 812), - (657, 788), - (685, 758), - (695, 746), - (692, 720), - (667, 720), - (288, 720), - (704, 704), - (786, 694), - (785, 685), - (777, 672), - (767, 670), - (767, 163), - (767, 159), - (750, 148), - (728, 142), - (716, 142), - (704, 142), - (402, 767), - (473, 767), - (473, 740), - (450, 598), - (338, 357), - (236, 258), - (220, 270), - (274, 340), - (345, 499), - (390, 675), - (344, 440), - (398, 425), - (464, 384), - (496, 343), - (501, 307), - (486, 284), - (458, 281), - (441, 291), - (434, 314), - (398, 366), - (354, 416), - (334, 433), - (832, 841), - (934, 830), - (932, 819), - (914, 804), - (896, 802), - (896, 30), - (896, 5), - (885, -35), - (848, -60), - (809, -65), - (807, -51), - (794, -27), - (781, -19), - (767, -11), - (715, 0), - (673, 5), - (673, 21), - (673, 21), - (707, 18), - (756, 15), - (799, 13), - (807, 13), - (821, 13), - (832, 23), - (832, 35), - (407, 624), - (594, 624), - (594, 546), - (396, 546), - (569, 576), - (558, 576), - (599, 614), - (677, 559), - (671, 552), - (654, 547), - (636, 545), - (622, 458), - (572, 288), - (488, 130), - (357, -5), - (259, -60), - (246, -45), - (327, 9), - (440, 150), - (516, 311), - (558, 486), - (128, 542), - (158, 581), - (226, 576), - (223, 562), - (207, 543), - (193, 539), - (193, -44), - (193, -46), - (175, -56), - (152, -64), - (141, -64), - (128, -64), - (195, 850), - (300, 820), - (295, 799), - (259, 799), - (234, 712), - (163, 543), - (80, 395), - (33, 338), - (19, 347), - (54, 410), - (120, 575), - (176, 759), - ]; - let coords = outline - .points - .iter() - .map(|point| (point.x, point.y)) - .collect::>(); - assert_eq!(coords, expected_coords); - let expected_metrics = HintedMetrics { - x_scale: 67109, - edge_metrics: Some(EdgeMetrics { - left_opos: 141, - left_pos: 128, - right_opos: 933, - right_pos: 896, - }), - }; - assert_eq!(metrics, expected_metrics); - } - - /// Empty glyphs (like spaces) have no edges and therefore no edge - /// metrics - #[test] - fn missing_edge_metrics() { - let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); - let (_outline, metrics) = hint_outline( - &font, - 16.0, - Default::default(), - GlyphId::new(1), - &style::STYLE_CLASSES[style::StyleClass::LATN], - ); - let expected_metrics = HintedMetrics { - x_scale: 65536, - edge_metrics: None, - }; - assert_eq!(metrics, expected_metrics); - } - - // Specific test case for which - // uses the Ahem - // font - #[test] - fn skia_ahem_test_case() { - let font = FontRef::new(font_test_data::AHEM).unwrap(); - let outline = hint_outline( - &font, - 24.0, - Default::default(), - // This glyph is the typical Ahem block square; the link to the - // font description above more detail. - GlyphId::new(5), - &style::STYLE_CLASSES[style::StyleClass::LATN], - ) - .0; - let expected_coords = [(0, 1216), (1536, 1216), (1536, -320), (0, -320)]; - // See - // Note that Skia inverts y coords - let expected_float_coords = [(0.0, 19.0), (24.0, 19.0), (24.0, -5.0), (0.0, -5.0)]; - let coords = outline - .points - .iter() - .map(|point| (point.x, point.y)) - .collect::>(); - let float_coords = coords - .iter() - .map(|(x, y)| (*x as f32 / 64.0, *y as f32 / 64.0)) - .collect::>(); - assert_eq!(coords, expected_coords); - assert_eq!(float_coords, expected_float_coords); - } - - fn hint_outline( - font: &FontRef, - size: f32, - coords: &[F2Dot14], - gid: GlyphId, - style: &style::StyleClass, - ) -> (Outline, HintedMetrics) { - let shaper = Shaper::new(font, ShaperMode::Nominal); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(gid).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, coords).unwrap(); - let metrics = compute_unscaled_style_metrics(&shaper, coords, style); - let scale = Scale::new( - size, - font.head().unwrap().units_per_em() as i32, - Style::Normal, - Default::default(), - metrics.style_class().script.group, - ); - let hinted_metrics = super::super::hint_outline(&mut outline, &metrics, &scale, None); - (outline, hinted_metrics) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -//! Autohinting state for a font instance. - -use crate::{attribute::Style, prelude::Size, MetadataProvider}; - -use super::{ - super::{ - pen::PathStyle, AdjustedMetrics, DrawError, OutlineGlyph, OutlineGlyphCollection, - OutlinePen, Target, - }, - metrics::{fixed_mul, pix_round, Scale, UnscaledStyleMetricsSet}, - outline::Outline, - shape::{Shaper, ShaperMode}, - style::GlyphStyleMap, -}; -use alloc::sync::Arc; -use raw::{ - types::{F26Dot6, F2Dot14}, - FontRef, TableProvider, -}; - -/// We enable "best effort" mode by default but allow it to be disabled with -/// a feature for testing. -const SHAPER_MODE: ShaperMode = if cfg!(feature = "autohint_shaping") { - ShaperMode::BestEffort -} else { - ShaperMode::Nominal -}; - -/// Set of derived glyph styles that are used for automatic hinting. -/// -/// These are invariant per font so can be precomputed and reused for multiple -/// instances when requesting automatic hinting with [`Engine::Auto`](super::super::hint::Engine::Auto). -#[derive(Clone, Debug)] -pub struct GlyphStyles(Arc); - -impl GlyphStyles { - /// Precomputes the full set of glyph styles for the given outlines. - pub fn new(outlines: &OutlineGlyphCollection) -> Self { - if let Some(font) = outlines.font() { - let glyph_count = font - .maxp() - .map(|maxp| maxp.num_glyphs() as u32) - .unwrap_or_default(); - let shaper = Shaper::new(font, SHAPER_MODE); - Self(Arc::new(GlyphStyleMap::new(glyph_count, &shaper))) - } else { - Self(Default::default()) - } - } -} - -#[derive(Clone)] -pub(crate) struct Instance { - styles: GlyphStyles, - metrics: UnscaledStyleMetricsSet, - target: Target, - is_fixed_width: bool, - style: Style, -} - -impl Instance { - pub fn new( - font: &FontRef, - outlines: &OutlineGlyphCollection, - coords: &[F2Dot14], - target: Target, - styles: Option, - lazy_metrics: bool, - ) -> Self { - let styles = styles.unwrap_or_else(|| GlyphStyles::new(outlines)); - #[cfg(feature = "std")] - let metrics = if lazy_metrics { - UnscaledStyleMetricsSet::lazy(&styles.0) - } else { - UnscaledStyleMetricsSet::precomputed(font, coords, SHAPER_MODE, &styles.0) - }; - #[cfg(not(feature = "std"))] - let metrics = UnscaledStyleMetricsSet::precomputed(font, coords, SHAPER_MODE, &styles.0); - let is_fixed_width = font - .post() - .map(|post| post.is_fixed_pitch() != 0) - .unwrap_or_default(); - let style = font.attributes().style; - Self { - styles, - metrics, - target, - is_fixed_width, - style, - } - } - - pub fn draw( - &self, - size: Size, - coords: &[F2Dot14], - glyph: &OutlineGlyph, - path_style: PathStyle, - pen: &mut impl OutlinePen, - ) -> Result { - let font = glyph.font(); - let glyph_id = glyph.glyph_id(); - let style = self - .styles - .0 - .style(glyph_id) - .ok_or(DrawError::GlyphNotFound(glyph_id))?; - let metrics = self - .metrics - .get(font, coords, SHAPER_MODE, &self.styles.0, glyph_id) - .ok_or(DrawError::GlyphNotFound(glyph_id))?; - let units_per_em = glyph.units_per_em() as i32; - let scale = Scale::new( - size.ppem().unwrap_or(units_per_em as f32), - units_per_em, - self.style, - self.target, - metrics.style_class().script.group, - ); - let mut outline = Outline::default(); - outline.fill(glyph, coords)?; - let hinted_metrics = super::hint::hint_outline(&mut outline, &metrics, &scale, Some(style)); - let h_advance = outline.advance; - let mut pp1x = 0; - let mut pp2x = fixed_mul(h_advance, hinted_metrics.x_scale); - let is_light = self.target.is_light() || self.target.preserve_linear_metrics(); - // - if !is_light { - if let (true, Some(edge_metrics)) = ( - scale.flags & Scale::NO_ADVANCE == 0, - hinted_metrics.edge_metrics, - ) { - let old_rsb = pp2x - edge_metrics.right_opos; - let old_lsb = edge_metrics.left_opos; - let new_lsb = edge_metrics.left_pos; - let mut pp1x_uh = new_lsb - old_lsb; - let mut pp2x_uh = edge_metrics.right_pos + old_rsb; - if old_lsb < 24 { - pp1x_uh -= 8; - } - if old_rsb < 24 { - pp2x_uh += 8; - } - pp1x = pix_round(pp1x_uh); - pp2x = pix_round(pp2x_uh); - if pp1x >= new_lsb && old_lsb > 0 { - pp1x -= 64; - } - if pp2x <= edge_metrics.right_pos && old_rsb > 0 { - pp2x += 64; - } - } else { - pp1x = pix_round(pp1x); - pp2x = pix_round(pp2x); - } - } else { - pp1x = pix_round(pp1x); - pp2x = pix_round(pp2x); - } - if pp1x != 0 { - for point in &mut outline.points { - point.x -= pp1x; - } - } - let advance = if !is_light - && (self.is_fixed_width || (metrics.digits_have_same_width && style.is_digit())) - { - fixed_mul(h_advance, scale.x_scale) - } else if h_advance != 0 { - pp2x - pp1x - } else { - 0 - }; - outline.to_path(path_style, pen)?; - Ok(AdjustedMetrics { - has_overlaps: glyph.has_overlaps().unwrap_or_default(), - lsb: None, - advance_width: Some(F26Dot6::from_bits(pix_round(advance)).to_f32()), - }) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,952 +0,0 @@ -//! Latin blue values. - -use super::{ - super::{ - super::{unscaled::UnscaledOutlineBuf, OutlineGlyphCollection}, - shape::{ShapedCluster, Shaper}, - style::{ScriptGroup, StyleClass}, - }, - ScaledWidth, -}; -use crate::{collections::SmallVec, FontRef, MetadataProvider}; -use raw::types::F2Dot14; -use raw::TableProvider; - -/// Maximum number of blue values. -/// -/// See -const MAX_BLUES: usize = 8; - -// Chosen to maximize opportunity to avoid heap allocation while keeping stack -// size < 2k. -const MAX_INLINE_POINTS: usize = 256; - -// -const BLUE_STRING_MAX_LEN: usize = 51; - -/// Defines the zone(s) that are associated with a blue value. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -#[repr(transparent)] -pub(crate) struct BlueZones(u16); - -impl BlueZones { - // These properties ostensibly come from - // - // but are modified to match those at - // - // so that when don't need to keep two sets and adjust during blue - // computation. - pub const NONE: Self = Self(0); - pub const TOP: Self = Self(1 << 1); - pub const SUB_TOP: Self = Self(1 << 2); - pub const NEUTRAL: Self = Self(1 << 3); - pub const ADJUSTMENT: Self = Self(1 << 4); - pub const X_HEIGHT: Self = Self(1 << 5); - pub const LONG: Self = Self(1 << 6); - pub const HORIZONTAL: Self = Self(1 << 2); - pub const RIGHT: Self = Self::TOP; - - pub const fn contains(self, other: Self) -> bool { - self.0 & other.0 == other.0 - } - - // Used for generated data structures because the bit-or operator - // cannot be const. - #[must_use] - pub const fn union(self, other: Self) -> Self { - Self(self.0 | other.0) - } - - pub fn is_top_like(self) -> bool { - self & (Self::TOP | Self::SUB_TOP) != Self::NONE - } - - pub fn is_top(self) -> bool { - self.contains(Self::TOP) - } - - pub fn is_sub_top(self) -> bool { - self.contains(Self::SUB_TOP) - } - - pub fn is_neutral(self) -> bool { - self.contains(Self::NEUTRAL) - } - - pub fn is_x_height(self) -> bool { - self.contains(Self::X_HEIGHT) - } - - pub fn is_long(self) -> bool { - self.contains(Self::LONG) - } - - pub fn is_horizontal(self) -> bool { - self.contains(Self::HORIZONTAL) - } - - pub fn is_right(self) -> bool { - self.contains(Self::RIGHT) - } - - #[must_use] - pub fn retain_top_like_or_neutral(self) -> Self { - self & (Self::TOP | Self::SUB_TOP | Self::NEUTRAL) - } -} - -impl core::ops::Not for BlueZones { - type Output = Self; - - fn not(self) -> Self::Output { - Self(!self.0) - } -} - -impl core::ops::BitOr for BlueZones { - type Output = Self; - - fn bitor(self, rhs: Self) -> Self::Output { - Self(self.0 | rhs.0) - } -} - -impl core::ops::BitOrAssign for BlueZones { - fn bitor_assign(&mut self, rhs: Self) { - self.0 |= rhs.0; - } -} - -impl core::ops::BitAnd for BlueZones { - type Output = Self; - - fn bitand(self, rhs: Self) -> Self::Output { - Self(self.0 & rhs.0) - } -} - -impl core::ops::BitAndAssign for BlueZones { - fn bitand_assign(&mut self, rhs: Self) { - self.0 &= rhs.0; - } -} - -// FreeType keeps a single array of blue values per metrics set -// and mutates when the scale factor changes. We'll separate them so -// that we can reuse unscaled metrics as immutable state without -// recomputing them (which is the expensive part). -// -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(crate) struct UnscaledBlue { - pub position: i32, - pub overshoot: i32, - pub ascender: i32, - pub descender: i32, - pub zones: BlueZones, -} - -pub(crate) type UnscaledBlues = SmallVec; - -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(crate) struct ScaledBlue { - pub position: ScaledWidth, - pub overshoot: ScaledWidth, - pub zones: BlueZones, - pub is_active: bool, -} - -pub(crate) type ScaledBlues = SmallVec; - -/// Compute unscaled blues values for each axis. -pub(crate) fn compute_unscaled_blues( - shaper: &Shaper, - coords: &[F2Dot14], - style: &StyleClass, -) -> [UnscaledBlues; 2] { - match style.script.group { - ScriptGroup::Default => [ - // Default group doesn't have horizontal blues - Default::default(), - compute_default_blues(shaper, coords, style), - ], - ScriptGroup::Cjk => compute_cjk_blues(shaper, coords, style), - // Indic group doesn't use blue values (yet?) - ScriptGroup::Indic => Default::default(), - } -} - -/// Compute unscaled blue values for the default script set. -/// -/// See -fn compute_default_blues(shaper: &Shaper, coords: &[F2Dot14], style: &StyleClass) -> UnscaledBlues { - let mut blues = UnscaledBlues::new(); - let (mut outline_buf, mut flats, mut rounds) = buffers(); - let (glyphs, units_per_em) = things_all_blues_need(shaper.font()); - let flat_threshold = units_per_em / 14; - let mut cluster_shaper = shaper.cluster_shaper(style); - let mut shaped_cluster = ShapedCluster::default(); - // Walk over each of the blue character sets for our script. - for (blue_str, blue_zones) in style.script.blues { - let mut ascender = i32::MIN; - let mut descender = i32::MAX; - let mut n_flats = 0; - let mut n_rounds = 0; - for cluster in blue_str.split(' ') { - let mut best_y_extremum = if blue_zones.is_top() { - i32::MIN - } else { - i32::MAX - }; - let mut best_is_round = false; - cluster_shaper.shape(cluster, &mut shaped_cluster); - for (glyph, y_offset) in shaped_cluster - .iter() - .filter(|g| g.id.to_u32() != 0) - .filter_map(|g| Some((glyphs.get(g.id)?, g.y_offset))) - { - outline_buf.clear(); - if glyph.draw_unscaled(coords, None, &mut outline_buf).is_err() { - continue; - } - let outline = outline_buf.as_ref(); - // Reject glyphs that can't produce any rendering - if outline.points.len() <= 2 { - continue; - } - let mut best_y: Option = None; - // Find the extreme point depending on whether this is a top or - // bottom blue - let best_contour_and_point = if blue_zones.is_top_like() { - outline.find_last_contour(|point| { - if best_y.is_none() || Some(point.y) > best_y { - best_y = Some(point.y); - ascender = ascender.max(point.y as i32 + y_offset); - true - } else { - descender = descender.min(point.y as i32 + y_offset); - false - } - }) - } else { - outline.find_last_contour(|point| { - if best_y.is_none() || Some(point.y) < best_y { - best_y = Some(point.y); - descender = descender.min(point.y as i32 + y_offset); - true - } else { - ascender = ascender.max(point.y as i32 + y_offset); - false - } - }) - }; - let Some((best_contour_range, best_point_ix)) = best_contour_and_point else { - continue; - }; - let best_contour = &outline.points[best_contour_range]; - // If we have a contour and point then best_y is guaranteed to - // be Some - let mut best_y = best_y.unwrap() as i32; - let best_x = best_contour[best_point_ix].x as i32; - // Now determine whether the point belongs to a straight or - // round segment by examining the previous and next points. - let [mut on_point_first, mut on_point_last] = - if best_contour[best_point_ix].is_on_curve() { - [Some(best_point_ix); 2] - } else { - [None; 2] - }; - let mut segment_first = best_point_ix; - let mut segment_last = best_point_ix; - // Look for the previous and next points on the contour that - // are not on the same Y coordinate, then threshold the - // "closeness" - for (ix, prev) in cycle_backward(best_contour, best_point_ix) { - let dist = (prev.y as i32 - best_y).abs(); - // Allow a small distance or angle (20 == roughly 2.9 degrees) - if dist > 5 && ((prev.x as i32 - best_x).abs() <= (20 * dist)) { - break; - } - segment_first = ix; - if prev.is_on_curve() { - on_point_first = Some(ix); - if on_point_last.is_none() { - on_point_last = Some(ix); - } - } - } - let mut next_ix = 0; - for (ix, next) in cycle_forward(best_contour, best_point_ix) { - // Save next_ix which is used in "long" blue computation - // later - next_ix = ix; - let dist = (next.y as i32 - best_y).abs(); - // Allow a small distance or angle (20 == roughly 2.9 degrees) - if dist > 5 && ((next.x as i32 - best_x).abs() <= (20 * dist)) { - break; - } - segment_last = ix; - if next.is_on_curve() { - on_point_last = Some(ix); - if on_point_first.is_none() { - on_point_first = Some(ix); - } - } - } - if blue_zones.is_long() { - // Taken verbatim from FreeType: - // - // "If this flag is set, we have an additional constraint to - // get the blue zone distance: Find a segment of the topmost - // (or bottommost) contour that is longer than a heuristic - // threshold. This ensures that small bumps in the outline - // are ignored (for example, the `vertical serifs' found in - // many Hebrew glyph designs). - // - // If this segment is long enough, we are done. Otherwise, - // search the segment next to the extremum that is long - // enough, has the same direction, and a not too large - // vertical distance from the extremum. Note that the - // algorithm doesn't check whether the found segment is - // actually the one (vertically) nearest to the extremum."" - // - // See - // heuristic threshold value - let length_threshold = units_per_em / 25; - let dist = (best_contour[segment_last].x as i32 - - best_contour[segment_first].x as i32) - .abs(); - if dist < length_threshold - && satisfies_min_long_segment_len( - segment_first, - segment_last, - best_contour.len() - 1, - ) - { - // heuristic threshold value - let height_threshold = units_per_em / 4; - // find previous point with different x value - let mut prev_ix = best_point_ix; - for (ix, prev) in cycle_backward(best_contour, best_point_ix) { - if prev.x as i32 != best_x { - prev_ix = ix; - break; - } - } - // skip for degenerate case - if prev_ix == best_point_ix { - continue; - } - let is_ltr = (best_contour[prev_ix].x as i32) < best_x; - let mut first = segment_last; - let mut last = first; - let mut p_first = None; - let mut p_last = None; - let mut hit = false; - loop { - if !hit { - // no hit, adjust first point - first = last; - // also adjust first and last on curve point - if best_contour[first].is_on_curve() { - p_first = Some(first); - p_last = Some(first); - } else { - p_first = None; - p_last = None; - } - hit = true; - } - if last < best_contour.len() - 1 { - last += 1; - } else { - last = 0; - } - if (best_y - best_contour[first].y as i32).abs() > height_threshold { - // vertical distance too large - hit = false; - continue; - } - let dist = - (best_contour[last].y as i32 - best_contour[first].y as i32).abs(); - if dist > 5 - && (best_contour[last].x as i32 - best_contour[first].x as i32) - .abs() - <= 20 * dist - { - hit = false; - if last == segment_first { - break; - } - continue; - } - if best_contour[last].is_on_curve() { - p_last = Some(last); - if p_first.is_none() { - p_first = Some(last); - } - } - let first_x = best_contour[first].x as i32; - let last_x = best_contour[last].x as i32; - let is_cur_ltr = first_x < last_x; - let dx = (last_x - first_x).abs(); - if is_cur_ltr == is_ltr && dx >= length_threshold { - loop { - if last < best_contour.len() - 1 { - last += 1; - } else { - last = 0; - } - let dy = (best_contour[last].y as i32 - - best_contour[first].y as i32) - .abs(); - if dy > 5 - && (best_contour[next_ix].x as i32 - - best_contour[first].x as i32) - .abs() - <= 20 * dist - { - if last > 0 { - last -= 1; - } else { - last = best_contour.len() - 1; - } - break; - } - p_last = Some(last); - if best_contour[last].is_on_curve() { - p_last = Some(last); - if p_first.is_none() { - p_first = Some(last); - } - } - if last == segment_first { - break; - } - } - best_y = best_contour[first].y as i32; - segment_first = first; - segment_last = last; - on_point_first = p_first; - on_point_last = p_last; - break; - } - if last == segment_first { - break; - } - } - } - } - best_y += y_offset; - // Is the segment round? - // 1. horizontal distance between first and last oncurve point - // is larger than a heuristic flat threshold, then it's flat - // 2. either first or last point of segment is offcurve then - // it's round - let is_round = match (on_point_first, on_point_last) { - (Some(first), Some(last)) - if (best_contour[last].x as i32 - best_contour[first].x as i32).abs() - > flat_threshold => - { - false - } - _ => { - !best_contour[segment_first].is_on_curve() - || !best_contour[segment_last].is_on_curve() - } - }; - if is_round && blue_zones.is_neutral() { - // Ignore round segments for neutral zone - continue; - } - // This seems to ignore LATIN_SUB_TOP? - if blue_zones.is_top() { - if best_y > best_y_extremum { - best_y_extremum = best_y; - best_is_round = is_round; - } - } else if best_y < best_y_extremum { - best_y_extremum = best_y; - best_is_round = is_round; - } - } - if best_y_extremum != i32::MIN && best_y_extremum != i32::MAX { - if best_is_round { - rounds[n_rounds] = best_y_extremum; - n_rounds += 1; - } else { - flats[n_flats] = best_y_extremum; - n_flats += 1; - } - } - } - if n_flats == 0 && n_rounds == 0 { - continue; - } - rounds[..n_rounds].sort_unstable(); - flats[..n_flats].sort_unstable(); - let (mut blue_ref, mut blue_shoot) = if n_flats == 0 { - let val = rounds[n_rounds / 2]; - (val, val) - } else if n_rounds == 0 { - let val = flats[n_flats / 2]; - (val, val) - } else { - (flats[n_flats / 2], rounds[n_rounds / 2]) - }; - if blue_shoot != blue_ref { - let over_ref = blue_shoot > blue_ref; - if blue_zones.is_top_like() ^ over_ref { - let val = (blue_shoot + blue_ref) / 2; - blue_ref = val; - blue_shoot = val; - } - } - let mut blue = UnscaledBlue { - position: blue_ref, - overshoot: blue_shoot, - ascender, - descender, - zones: blue_zones.retain_top_like_or_neutral(), - }; - if blue_zones.is_x_height() { - blue.zones |= BlueZones::ADJUSTMENT; - } - blues.push(blue); - } - // sort bottoms - let mut sorted_indices: [usize; MAX_BLUES] = core::array::from_fn(|ix| ix); - let blue_values = blues.as_mut_slice(); - let len = blue_values.len(); - if len == 0 { - return blues; - } - // sort from bottom to top - for i in 1..len { - for j in (1..=i).rev() { - let first = &blue_values[sorted_indices[j - 1]]; - let second = &blue_values[sorted_indices[j]]; - let a = if first.zones.is_top_like() { - first.position - } else { - first.overshoot - }; - let b = if second.zones.is_top_like() { - second.position - } else { - second.overshoot - }; - if b >= a { - break; - } - sorted_indices.swap(j, j - 1); - } - } - // and adjust tops - for i in 0..len - 1 { - let index1 = sorted_indices[i]; - let index2 = sorted_indices[i + 1]; - let first = &blue_values[index1]; - let second = &blue_values[index2]; - let a = if first.zones.is_top_like() { - first.overshoot - } else { - first.position - }; - let b = if second.zones.is_top_like() { - second.overshoot - } else { - second.position - }; - if a > b { - if first.zones.is_top_like() { - blue_values[index1].overshoot = b; - } else { - blue_values[index1].position = b; - } - } - } - blues -} - -/// Given inclusive indices and a contour length, returns true if the segment -/// is of sufficient size to test for bumps when detecting "long" Hebrew -/// alignment zones. -fn satisfies_min_long_segment_len(first_ix: usize, last_ix: usize, contour_last: usize) -> bool { - let inclusive_diff = if first_ix <= last_ix { - last_ix - first_ix - } else { - // If first_ix > last_ix, then we want to capture the sum of the ranges - // [first_ix, contour_last] and [0, last_ix] - // We add 1 here to ensure the element that crosses the boundary is - // included. For example, if first_ix == contour_last and - // last_ix == 0, then we want the result to be 1 - contour_last - first_ix + 1 + last_ix - }; - // The +2 matches FreeType. The assumption is that this includes sufficient - // points to detect a bump and extend the segment? - // - inclusive_diff + 2 <= contour_last -} - -/// Compute unscaled blue values for the CJK script set. -/// -/// Note: unlike the default code above, this produces two sets of blues, -/// one for horizontal zones and one for vertical zones, respectively. The -/// horizontal set is currently not generated because this has been -/// disabled in FreeType but the code remains because we may want to revisit -/// in the future. -/// -/// See -fn compute_cjk_blues( - shaper: &Shaper, - coords: &[F2Dot14], - style: &StyleClass, -) -> [UnscaledBlues; 2] { - let mut blues = [UnscaledBlues::new(), UnscaledBlues::new()]; - let (mut outline_buf, mut flats, mut fills) = buffers(); - let (glyphs, _) = things_all_blues_need(shaper.font()); - let mut cluster_shaper = shaper.cluster_shaper(style); - let mut shaped_cluster = ShapedCluster::default(); - // Walk over each of the blue character sets for our script. - for (blue_str, blue_zones) in style.script.blues { - let is_horizontal = blue_zones.is_horizontal(); - // Note: horizontal blue zones are disabled by default and have been - // for many years in FreeType: - // See - // and - if is_horizontal { - continue; - } - let is_right = blue_zones.is_right(); - let is_top = blue_zones.is_top(); - let blues = &mut blues[!is_horizontal as usize]; - if blues.len() >= MAX_BLUES { - continue; - } - let mut n_flats = 0; - let mut n_fills = 0; - let mut is_fill = true; - for cluster in blue_str.split(' ') { - // The '|' character is used as a sentinel in the blue string that - // signifies a switch to characters that define "flat" values - // - if cluster == "|" { - is_fill = false; - continue; - } - cluster_shaper.shape(cluster, &mut shaped_cluster); - for glyph in shaped_cluster - .iter() - .filter(|g| g.id.to_u32() != 0) - .filter_map(|g| glyphs.get(g.id)) - { - outline_buf.clear(); - if glyph.draw_unscaled(coords, None, &mut outline_buf).is_err() { - continue; - } - let outline = outline_buf.as_ref(); - // Reject glyphs that can't produce any rendering - if outline.points.len() <= 2 { - continue; - } - // Step right up and find an extrema! - // Unwrap is safe because we know per ^ that we have at least 3 points - let best_pos = outline - .points - .iter() - .map(|p| if is_horizontal { p.x } else { p.y }) - .reduce( - if (is_horizontal && is_right) || (!is_horizontal && is_top) { - |a: i16, c: i16| a.max(c) - } else { - |a: i16, c: i16| a.min(c) - }, - ) - .unwrap(); - if is_fill { - fills[n_fills] = best_pos; - n_fills += 1; - } else { - flats[n_flats] = best_pos; - n_flats += 1; - } - } - } - if n_flats == 0 && n_fills == 0 { - continue; - } - // Now determine the reference and overshoot of the blue; simply - // take the median after a sort - fills[..n_fills].sort_unstable(); - flats[..n_flats].sort_unstable(); - let (mut blue_ref, mut blue_shoot) = if n_flats == 0 { - let value = fills[n_fills / 2] as i32; - (value, value) - } else if n_fills == 0 { - let value = flats[n_flats / 2] as i32; - (value, value) - } else { - (fills[n_fills / 2] as i32, flats[n_flats / 2] as i32) - }; - // Make sure blue_ref >= blue_shoot for top/right or vice versa for - // bottom left - if blue_shoot != blue_ref { - let under_ref = blue_shoot < blue_ref; - if blue_zones.is_top() ^ under_ref { - blue_ref = (blue_shoot + blue_ref) / 2; - blue_shoot = blue_ref; - } - } - blues.push(UnscaledBlue { - position: blue_ref, - overshoot: blue_shoot, - ascender: 0, - descender: 0, - zones: *blue_zones & BlueZones::TOP, - }); - } - blues -} - -#[inline(always)] -fn buffers() -> ( - UnscaledOutlineBuf, - [T; BLUE_STRING_MAX_LEN], - [T; BLUE_STRING_MAX_LEN], -) { - ( - UnscaledOutlineBuf::::new(), - [T::default(); BLUE_STRING_MAX_LEN], - [T::default(); BLUE_STRING_MAX_LEN], - ) -} - -/// A thneed is something everyone needs -#[inline(always)] -fn things_all_blues_need<'a>(font: &FontRef<'a>) -> (OutlineGlyphCollection<'a>, i32) { - ( - font.outline_glyphs(), - font.head() - .map(|head| head.units_per_em()) - .unwrap_or_default() as i32, - ) -} - -/// Iterator that begins at `start + 1` and cycles through all items -/// of the slice in forward order, ending with `start`. -pub(super) fn cycle_forward(items: &[T], start: usize) -> impl Iterator { - let len = items.len(); - let start = start + 1; - (0..len).map(move |ix| { - let real_ix = (ix + start) % len; - (real_ix, &items[real_ix]) - }) -} - -/// Iterator that begins at `start - 1` and cycles through all items -/// of the slice in reverse order, ending with `start`. -pub(super) fn cycle_backward(items: &[T], start: usize) -> impl Iterator { - let len = items.len(); - (0..len).rev().map(move |ix| { - let real_ix = (ix + start) % len; - (real_ix, &items[real_ix]) - }) -} - -#[cfg(test)] -mod tests { - use crate::outline::autohint::metrics::BlueZones; - - use super::{ - super::super::{ - shape::{Shaper, ShaperMode}, - style, - }, - satisfies_min_long_segment_len, UnscaledBlue, - }; - use raw::FontRef; - - #[test] - fn latin_blues() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let style = &style::STYLE_CLASSES[super::StyleClass::LATN]; - let blues = super::compute_default_blues(&shaper, &[], style); - let values = blues.as_slice(); - let expected = [ - UnscaledBlue { - position: 714, - overshoot: 725, - ascender: 725, - descender: -230, - zones: BlueZones::TOP, - }, - UnscaledBlue { - position: 0, - overshoot: -10, - ascender: 725, - descender: -10, - zones: BlueZones::default(), - }, - UnscaledBlue { - position: 760, - overshoot: 760, - ascender: 770, - descender: -240, - zones: BlueZones::TOP, - }, - UnscaledBlue { - position: 536, - overshoot: 546, - ascender: 546, - descender: -10, - zones: BlueZones::TOP | BlueZones::ADJUSTMENT, - }, - UnscaledBlue { - position: 0, - overshoot: -10, - ascender: 546, - descender: -10, - zones: BlueZones::default(), - }, - UnscaledBlue { - position: -240, - overshoot: -240, - ascender: 760, - descender: -240, - zones: BlueZones::default(), - }, - ]; - assert_eq!(values, &expected); - } - - #[test] - fn hebrew_long_blues() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - // Hebrew triggers "long" blue code path - let style = &style::STYLE_CLASSES[super::StyleClass::HEBR]; - let blues = super::compute_default_blues(&shaper, &[], style); - let values = blues.as_slice(); - assert_eq!(values.len(), 3); - let expected = [ - UnscaledBlue { - position: 592, - overshoot: 592, - ascender: 647, - descender: -240, - zones: BlueZones::TOP, - }, - UnscaledBlue { - position: 0, - overshoot: -9, - ascender: 647, - descender: -9, - zones: BlueZones::default(), - }, - UnscaledBlue { - position: -240, - overshoot: -240, - ascender: 647, - descender: -240, - zones: BlueZones::default(), - }, - ]; - assert_eq!(values, &expected); - } - - #[test] - fn cjk_blues() { - let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let style = &style::STYLE_CLASSES[super::StyleClass::HANI]; - let blues = super::compute_cjk_blues(&shaper, &[], style); - let values = blues[1].as_slice(); - let expected = [ - UnscaledBlue { - position: 837, - overshoot: 824, - ascender: 0, - descender: 0, - zones: BlueZones::TOP, - }, - UnscaledBlue { - position: -78, - overshoot: -66, - ascender: 0, - descender: 0, - zones: BlueZones::default(), - }, - ]; - assert_eq!(values, &expected); - } - - #[test] - fn c2sc_shaped_blues() { - let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::BestEffort); - let style = &style::STYLE_CLASSES[super::StyleClass::LATN_C2SC]; - let blues = super::compute_default_blues(&shaper, &[], style); - let values = blues.as_slice(); - // Captured from FreeType with HarfBuzz enabled - let expected = [ - UnscaledBlue { - position: 571, - overshoot: 571, - ascender: 571, - descender: 0, - zones: BlueZones::TOP, - }, - UnscaledBlue { - position: 0, - overshoot: 0, - ascender: 571, - descender: 0, - zones: BlueZones::default(), - }, - ]; - assert_eq!(values, &expected); - } - - /// Avoid subtraction overflow raised in - /// - #[test] - fn long_segment_len_avoid_overflow() { - // Test font in issue above triggers overflow with - // first = 22, last = 0, contour_last = 22 (all inclusive). - // FreeType succeeds on this with suspicious signed - // arithmetic and we should too with our code that - // takes the boundary into account - assert!(satisfies_min_long_segment_len(22, 0, 22)); - } - - #[test] - fn cycle_iter_forward() { - let items = [0, 1, 2, 3, 4, 5, 6, 7]; - let from_5 = super::cycle_forward(&items, 5) - .map(|(_, val)| *val) - .collect::>(); - assert_eq!(from_5, &[6, 7, 0, 1, 2, 3, 4, 5]); - let from_last = super::cycle_forward(&items, 7) - .map(|(_, val)| *val) - .collect::>(); - assert_eq!(from_last, &items); - // Don't panic on empty slice - let _ = super::cycle_forward::(&[], 5).count(); - } - - #[test] - fn cycle_iter_backward() { - let items = [0, 1, 2, 3, 4, 5, 6, 7]; - let from_5 = super::cycle_backward(&items, 5) - .map(|(_, val)| *val) - .collect::>(); - assert_eq!(from_5, &[4, 3, 2, 1, 0, 7, 6, 5]); - let from_0 = super::cycle_backward(&items, 0) - .map(|(_, val)| *val) - .collect::>(); - assert_eq!(from_0, &[7, 6, 5, 4, 3, 2, 1, 0]); - // Don't panic on empty slice - let _ = super::cycle_backward::(&[], 5).count(); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,480 +0,0 @@ -//! Autohinting specific metrics. - -mod blues; -mod scale; -mod widths; - -use super::{ - super::Target, - shape::{Shaper, ShaperMode}, - style::{GlyphStyleMap, ScriptGroup, StyleClass}, - topo::Dimension, -}; -use crate::{attribute::Style, collections::SmallVec, FontRef}; -use alloc::vec::Vec; -use raw::types::{F2Dot14, Fixed, GlyphId}; -#[cfg(feature = "std")] -use std::sync::{Arc, RwLock}; - -pub(crate) use blues::{BlueZones, ScaledBlue, ScaledBlues, UnscaledBlue, UnscaledBlues}; -pub(crate) use scale::{compute_unscaled_style_metrics, scale_style_metrics}; - -/// Maximum number of widths, same for Latin and CJK. -/// -/// See -/// and -pub(crate) const MAX_WIDTHS: usize = 16; - -/// Unscaled metrics for a single axis. -/// -/// This is the union of the Latin and CJK axis records. -/// -/// See -/// and -#[derive(Clone, Default, Debug)] -pub(crate) struct UnscaledAxisMetrics { - pub dim: Dimension, - pub widths: UnscaledWidths, - pub width_metrics: WidthMetrics, - pub blues: UnscaledBlues, -} - -impl UnscaledAxisMetrics { - pub fn max_width(&self) -> Option { - self.widths.last().copied() - } -} - -/// Scaled metrics for a single axis. -#[derive(Clone, Default, Debug)] -pub(crate) struct ScaledAxisMetrics { - pub dim: Dimension, - /// Font unit to 26.6 scale in the axis direction. - pub scale: i32, - /// 1/64 pixel delta in the axis direction. - pub delta: i32, - pub widths: ScaledWidths, - pub width_metrics: WidthMetrics, - pub blues: ScaledBlues, -} - -/// Unscaled metrics for a single style and script. -/// -/// This is the union of the root, Latin and CJK style metrics but -/// the latter two are actually identical. -/// -/// See -/// and -/// and -#[derive(Clone, Default, Debug)] -pub(crate) struct UnscaledStyleMetrics { - /// Index of style class. - pub class_ix: u16, - /// Monospaced digits? - pub digits_have_same_width: bool, - /// Per-dimension unscaled metrics. - pub axes: [UnscaledAxisMetrics; 2], -} - -impl UnscaledStyleMetrics { - pub fn style_class(&self) -> &'static StyleClass { - &super::style::STYLE_CLASSES[self.class_ix as usize] - } -} - -/// The set of unscaled style metrics for a single font. -/// -/// For a variable font, this is dependent on the location in variation space. -#[derive(Clone, Debug)] -pub(crate) enum UnscaledStyleMetricsSet { - Precomputed(Vec), - #[cfg(feature = "std")] - Lazy(Arc>>>), -} - -impl UnscaledStyleMetricsSet { - /// Creates a precomputed style metrics set containing all metrics - /// required by the glyph map. - pub fn precomputed( - font: &FontRef, - coords: &[F2Dot14], - shaper_mode: ShaperMode, - style_map: &GlyphStyleMap, - ) -> Self { - // The metrics_styles() iterator does not report exact size so we - // preallocate and extend here rather than collect to avoid - // over allocating memory. - let shaper = Shaper::new(font, shaper_mode); - let mut vec = Vec::with_capacity(style_map.metrics_count()); - vec.extend( - style_map - .metrics_styles() - .map(|style| compute_unscaled_style_metrics(&shaper, coords, style)), - ); - Self::Precomputed(vec) - } - - /// Creates an unscaled style metrics set where each entry will be - /// initialized as needed. - #[cfg(feature = "std")] - pub fn lazy(style_map: &GlyphStyleMap) -> Self { - let vec = vec![None; style_map.metrics_count()]; - Self::Lazy(Arc::new(RwLock::new(vec))) - } - - /// Returns the unscaled style metrics for the given style map and glyph - /// identifier. - pub fn get( - &self, - font: &FontRef, - coords: &[F2Dot14], - shaper_mode: ShaperMode, - style_map: &GlyphStyleMap, - glyph_id: GlyphId, - ) -> Option { - let style = style_map.style(glyph_id)?; - let index = style_map.metrics_index(style)?; - match self { - Self::Precomputed(metrics) => metrics.get(index).cloned(), - #[cfg(feature = "std")] - Self::Lazy(lazy) => { - let read = lazy.read().unwrap(); - let entry = read.get(index)?; - if let Some(metrics) = &entry { - return Some(metrics.clone()); - } - core::mem::drop(read); - // The std RwLock doesn't support upgrading and contention is - // expected to be low, so let's just race to compute the new - // metrics. - let shaper = Shaper::new(font, shaper_mode); - let style_class = style.style_class()?; - let metrics = compute_unscaled_style_metrics(&shaper, coords, style_class); - let mut entry = lazy.write().unwrap(); - *entry.get_mut(index)? = Some(metrics.clone()); - Some(metrics) - } - } - } -} - -/// Scaled metrics for a single style and script. -#[derive(Clone, Default, Debug)] -pub(crate) struct ScaledStyleMetrics { - /// Multidimensional scaling factors and deltas. - pub scale: Scale, - /// Per-dimension scaled metrics. - pub axes: [ScaledAxisMetrics; 2], -} - -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(crate) struct WidthMetrics { - /// Used for creating edges. - pub edge_distance_threshold: i32, - /// Default stem thickness. - pub standard_width: i32, - /// Is standard width very light? - pub is_extra_light: bool, -} - -pub(crate) type UnscaledWidths = SmallVec; - -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(crate) struct ScaledWidth { - /// Width after applying scale. - pub scaled: i32, - /// Grid-fitted width. - pub fitted: i32, -} - -pub(crate) type ScaledWidths = SmallVec; - -/// Captures scaling parameters which may be modified during metrics -/// computation. -#[derive(Copy, Clone, Default, Debug)] -pub(crate) struct Scale { - /// Font unit to 26.6 scale in the X direction. - pub x_scale: i32, - /// Font unit to 26.6 scale in the Y direction. - pub y_scale: i32, - /// In 1/64 device pixels. - pub x_delta: i32, - /// In 1/64 device pixels. - pub y_delta: i32, - /// Font size in pixels per em. - pub size: f32, - /// From the source font. - pub units_per_em: i32, - /// Flags that determine hinting functionality. - pub flags: u32, -} - -impl Scale { - /// Create initial scaling parameters from metrics and hinting target. - pub fn new( - size: f32, - units_per_em: i32, - font_style: Style, - target: Target, - group: ScriptGroup, - ) -> Self { - let scale = - (Fixed::from_bits((size * 64.0) as i32) / Fixed::from_bits(units_per_em)).to_bits(); - let mut flags = 0; - let is_italic = font_style != Style::Normal; - let is_mono = target == Target::Mono; - let is_light = target.is_light() || target.preserve_linear_metrics(); - // Snap vertical stems for monochrome and horizontal LCD rendering. - if is_mono || target.is_lcd() { - flags |= Self::HORIZONTAL_SNAP; - } - // Snap horizontal stems for monochrome and vertical LCD rendering. - if is_mono || target.is_vertical_lcd() { - flags |= Self::VERTICAL_SNAP; - } - // Adjust stems to full pixels unless in LCD or light modes. - if !(target.is_lcd() || is_light) { - flags |= Self::STEM_ADJUST; - } - if is_mono { - flags |= Self::MONO; - } - if group == ScriptGroup::Default { - // Disable horizontal hinting completely for LCD, light hinting - // and italic fonts - // See - if target.is_lcd() || is_light || is_italic { - flags |= Self::NO_HORIZONTAL; - } - } else { - // CJK doesn't hint advances - // See - flags |= Self::NO_ADVANCE; - } - // CJK doesn't hint advances - // See - if group != ScriptGroup::Default { - flags |= Self::NO_ADVANCE; - } - Self { - x_scale: scale, - y_scale: scale, - x_delta: 0, - y_delta: 0, - size, - units_per_em, - flags, - } - } -} - -/// Scaler flags that determine hinting settings. -/// -/// See -/// and -impl Scale { - /// Stem width snapping. - pub const HORIZONTAL_SNAP: u32 = 1 << 0; - /// Stem height snapping. - pub const VERTICAL_SNAP: u32 = 1 << 1; - /// Stem width/height adjustment. - pub const STEM_ADJUST: u32 = 1 << 2; - /// Monochrome rendering. - pub const MONO: u32 = 1 << 3; - /// Disable horizontal hinting. - pub const NO_HORIZONTAL: u32 = 1 << 4; - /// Disable vertical hinting. - pub const NO_VERTICAL: u32 = 1 << 5; - /// Disable advance hinting. - pub const NO_ADVANCE: u32 = 1 << 6; -} - -// -pub(crate) fn sort_and_quantize_widths(widths: &mut UnscaledWidths, threshold: i32) { - if widths.len() <= 1 { - return; - } - widths.sort_unstable(); - let table = widths.as_mut_slice(); - let mut cur_ix = 0; - let mut cur_val = table[cur_ix]; - let last_ix = table.len() - 1; - let mut ix = 1; - // Compute and use mean values for clusters not larger than - // `threshold`. - while ix < table.len() { - if (table[ix] - cur_val) > threshold || ix == last_ix { - let mut sum = 0; - // Fix loop for end of array? - if (table[ix] - cur_val <= threshold) && ix == last_ix { - ix += 1; - } - for val in &mut table[cur_ix..ix] { - sum += *val; - *val = 0; - } - table[cur_ix] = sum / ix as i32; - if ix < last_ix { - cur_ix = ix + 1; - cur_val = table[cur_ix]; - } - } - ix += 1; - } - cur_ix = 1; - // Compress array to remove zero values - for ix in 1..table.len() { - if table[ix] != 0 { - table[cur_ix] = table[ix]; - cur_ix += 1; - } - } - widths.truncate(cur_ix); -} - -// Fixed point helpers -// -// Note: lots of bit fiddling based fixed point math in the autohinter -// so we're opting out of using the strongly typed variants because they -// just add noise and reduce clarity. - -pub(crate) fn fixed_mul(a: i32, b: i32) -> i32 { - (Fixed::from_bits(a) * Fixed::from_bits(b)).to_bits() -} - -pub(crate) fn fixed_div(a: i32, b: i32) -> i32 { - (Fixed::from_bits(a) / Fixed::from_bits(b)).to_bits() -} - -pub(crate) fn fixed_mul_div(a: i32, b: i32, c: i32) -> i32 { - Fixed::from_bits(a) - .mul_div(Fixed::from_bits(b), Fixed::from_bits(c)) - .to_bits() -} - -pub(crate) fn pix_round(a: i32) -> i32 { - (a + 32) & !63 -} - -pub(crate) fn pix_floor(a: i32) -> i32 { - a & !63 -} - -#[cfg(test)] -mod tests { - use super::{ - super::{ - shape::{Shaper, ShaperMode}, - style::STYLE_CLASSES, - }, - *, - }; - use raw::TableProvider; - - #[test] - fn sort_widths() { - // We use 10 and 20 as thresholds because the computation used - // is units_per_em / 100 - assert_eq!(sort_widths_helper(&[1], 10), &[1]); - assert_eq!(sort_widths_helper(&[1], 20), &[1]); - assert_eq!(sort_widths_helper(&[60, 20, 40, 35], 10), &[20, 35, 13, 60]); - assert_eq!(sort_widths_helper(&[60, 20, 40, 35], 20), &[31, 60]); - } - - fn sort_widths_helper(widths: &[i32], threshold: i32) -> Vec { - let mut widths2 = UnscaledWidths::new(); - for width in widths { - widths2.push(*width); - } - sort_and_quantize_widths(&mut widths2, threshold); - widths2.into_iter().collect() - } - - #[test] - fn precomputed_style_set() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let coords = &[]; - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let glyph_count = font.maxp().unwrap().num_glyphs() as u32; - let style_map = GlyphStyleMap::new(glyph_count, &shaper); - let style_set = - UnscaledStyleMetricsSet::precomputed(&font, coords, ShaperMode::Nominal, &style_map); - let UnscaledStyleMetricsSet::Precomputed(set) = &style_set else { - panic!("we definitely made a precomputed style set"); - }; - // This font has Latin, Hebrew and CJK (for unassigned chars) styles - assert_eq!(STYLE_CLASSES[set[0].class_ix as usize].name, "Latin"); - assert_eq!(STYLE_CLASSES[set[1].class_ix as usize].name, "Hebrew"); - assert_eq!( - STYLE_CLASSES[set[2].class_ix as usize].name, - "CJKV ideographs" - ); - assert_eq!(set.len(), 3); - } - - #[test] - fn lazy_style_set() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let coords = &[]; - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let glyph_count = font.maxp().unwrap().num_glyphs() as u32; - let style_map = GlyphStyleMap::new(glyph_count, &shaper); - let style_set = UnscaledStyleMetricsSet::lazy(&style_map); - let all_empty = lazy_set_presence(&style_set); - // Set starts out all empty - assert_eq!(all_empty, [false; 3]); - // First load a CJK glyph - let metrics2 = style_set - .get( - &font, - coords, - ShaperMode::Nominal, - &style_map, - GlyphId::new(0), - ) - .unwrap(); - assert_eq!( - STYLE_CLASSES[metrics2.class_ix as usize].name, - "CJKV ideographs" - ); - let only_cjk = lazy_set_presence(&style_set); - assert_eq!(only_cjk, [false, false, true]); - // Then a Hebrew glyph - let metrics1 = style_set - .get( - &font, - coords, - ShaperMode::Nominal, - &style_map, - GlyphId::new(1), - ) - .unwrap(); - assert_eq!(STYLE_CLASSES[metrics1.class_ix as usize].name, "Hebrew"); - let hebrew_and_cjk = lazy_set_presence(&style_set); - assert_eq!(hebrew_and_cjk, [false, true, true]); - // And finally a Latin glyph - let metrics0 = style_set - .get( - &font, - coords, - ShaperMode::Nominal, - &style_map, - GlyphId::new(15), - ) - .unwrap(); - assert_eq!(STYLE_CLASSES[metrics0.class_ix as usize].name, "Latin"); - let all_present = lazy_set_presence(&style_set); - assert_eq!(all_present, [true; 3]); - } - - fn lazy_set_presence(style_set: &UnscaledStyleMetricsSet) -> Vec { - let UnscaledStyleMetricsSet::Lazy(set) = &style_set else { - panic!("we definitely made a lazy style set"); - }; - set.read() - .unwrap() - .iter() - .map(|opt| opt.is_some()) - .collect() - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,429 +0,0 @@ -//! Metrics scaling. -//! -//! Uses the widths and blues computations to generate unscaled metrics for a -//! given style/script. -//! -//! Then applies a scaling factor to those metrics, computes a potentially -//! modified scale, and tags active blue zones. - -use super::super::{ - metrics::{ - fixed_div, fixed_mul, fixed_mul_div, pix_round, BlueZones, Scale, ScaledAxisMetrics, - ScaledBlue, ScaledStyleMetrics, ScaledWidth, UnscaledAxisMetrics, UnscaledBlue, - UnscaledStyleMetrics, WidthMetrics, - }, - shape::Shaper, - style::{ScriptGroup, StyleClass}, - topo::{Axis, Dimension}, -}; -use crate::{prelude::Size, MetadataProvider}; -use raw::types::F2Dot14; - -/// Computes unscaled metrics for the Latin writing system. -/// -/// See -pub(crate) fn compute_unscaled_style_metrics( - shaper: &Shaper, - coords: &[F2Dot14], - style: &StyleClass, -) -> UnscaledStyleMetrics { - let charmap = shaper.charmap(); - // We don't attempt to produce any metrics if we don't have a Unicode - // cmap - // See - if charmap.is_symbol() { - return UnscaledStyleMetrics { - class_ix: style.index as u16, - axes: [ - UnscaledAxisMetrics { - dim: Axis::HORIZONTAL, - ..Default::default() - }, - UnscaledAxisMetrics { - dim: Axis::VERTICAL, - ..Default::default() - }, - ], - ..Default::default() - }; - } - let [hwidths, vwidths] = super::widths::compute_widths(shaper, coords, style); - let [hblues, vblues] = super::blues::compute_unscaled_blues(shaper, coords, style); - let glyph_metrics = shaper.font().glyph_metrics(Size::unscaled(), coords); - let mut digit_advance = None; - let mut digits_have_same_width = true; - for ch in '0'..='9' { - if let Some(advance) = charmap - .map(ch) - .and_then(|gid| glyph_metrics.advance_width(gid)) - { - if digit_advance.is_some() && digit_advance != Some(advance) { - digits_have_same_width = false; - break; - } - digit_advance = Some(advance); - } - } - UnscaledStyleMetrics { - class_ix: style.index as u16, - digits_have_same_width, - axes: [ - UnscaledAxisMetrics { - dim: Axis::HORIZONTAL, - blues: hblues, - width_metrics: hwidths.0, - widths: hwidths.1, - }, - UnscaledAxisMetrics { - dim: Axis::VERTICAL, - blues: vblues, - width_metrics: vwidths.0, - widths: vwidths.1, - }, - ], - } -} - -/// Computes scaled metrics for the Latin writing system. -/// -/// See -pub(crate) fn scale_style_metrics( - unscaled_metrics: &UnscaledStyleMetrics, - mut scale: Scale, -) -> ScaledStyleMetrics { - let scale_axis_fn = if unscaled_metrics.style_class().script.group == ScriptGroup::Default { - scale_default_axis_metrics - } else { - scale_cjk_axis_metrics - }; - let mut scale_axis = |axis: &UnscaledAxisMetrics| { - scale_axis_fn( - axis.dim, - &axis.widths, - axis.width_metrics, - &axis.blues, - &mut scale, - ) - }; - let axes = [ - scale_axis(&unscaled_metrics.axes[0]), - scale_axis(&unscaled_metrics.axes[1]), - ]; - ScaledStyleMetrics { scale, axes } -} - -/// Computes scaled metrics for a single axis. -/// -/// See -fn scale_default_axis_metrics( - dim: Dimension, - widths: &[i32], - width_metrics: WidthMetrics, - blues: &[UnscaledBlue], - scale: &mut Scale, -) -> ScaledAxisMetrics { - let mut axis = ScaledAxisMetrics { - dim, - ..Default::default() - }; - if dim == Axis::HORIZONTAL { - axis.scale = scale.x_scale; - axis.delta = scale.x_delta; - } else { - axis.scale = scale.y_scale; - axis.delta = scale.y_delta; - }; - // Correct Y scale to optimize alignment - if let Some(blue_ix) = blues - .iter() - .position(|blue| blue.zones.contains(BlueZones::ADJUSTMENT)) - { - let unscaled_blue = &blues[blue_ix]; - let scaled = fixed_mul(axis.scale, unscaled_blue.overshoot); - let fitted = (scaled + 40) & !63; - if scaled != fitted && dim == Axis::VERTICAL { - let new_scale = fixed_mul_div(axis.scale, fitted, scaled); - // Scaling should not adjust by more than 2 pixels - let mut max_height = scale.units_per_em; - for blue in blues { - max_height = max_height.max(blue.ascender).max(-blue.descender); - } - let mut dist = fixed_mul(max_height, new_scale - axis.scale).abs(); - dist &= !127; - if dist == 0 { - axis.scale = new_scale; - scale.y_scale = new_scale; - } - } - } - // Now scale the widths - axis.width_metrics = width_metrics; - for unscaled_width in widths { - let scaled = fixed_mul(axis.scale, *unscaled_width); - axis.widths.push(ScaledWidth { - scaled, - fitted: scaled, - }); - } - // Compute extra light property: this is a standard width that is - // less than 5/8 pixels - axis.width_metrics.is_extra_light = - fixed_mul(axis.width_metrics.standard_width, axis.scale) < (32 + 8); - if dim == Axis::VERTICAL { - // And scale the blue zones - for unscaled_blue in blues { - let scaled_position = fixed_mul(axis.scale, unscaled_blue.position) + axis.delta; - let scaled_overshoot = fixed_mul(axis.scale, unscaled_blue.overshoot) + axis.delta; - let mut blue = ScaledBlue { - position: ScaledWidth { - scaled: scaled_position, - fitted: scaled_position, - }, - overshoot: ScaledWidth { - scaled: scaled_overshoot, - fitted: scaled_overshoot, - }, - zones: unscaled_blue.zones, - is_active: false, - }; - // Only activate blue zones less than 3/4 pixel tall - let dist = fixed_mul(unscaled_blue.position - unscaled_blue.overshoot, axis.scale); - if (-48..=48).contains(&dist) { - let mut delta = dist.abs(); - if delta < 32 { - delta = 0; - } else if delta < 48 { - delta = 32; - } else { - delta = 64; - } - if dist < 0 { - delta = -delta; - } - blue.position.fitted = pix_round(blue.position.scaled); - blue.overshoot.fitted = blue.position.fitted - delta; - blue.is_active = true; - } - axis.blues.push(blue); - } - // Use sub-top blue zone if it doesn't overlap with another - // non-sub-top blue zone - for blue_ix in 0..axis.blues.len() { - let blue = axis.blues[blue_ix]; - if !blue.zones.is_sub_top() || !blue.is_active { - continue; - } - for blue2 in &axis.blues { - if blue2.zones.is_sub_top() || !blue2.is_active { - continue; - } - if blue2.position.fitted <= blue.overshoot.fitted - && blue2.overshoot.fitted >= blue.position.fitted - { - axis.blues[blue_ix].is_active = false; - break; - } - } - } - } - axis -} - -/// Computes scaled metrics for a single axis for the CJK script group. -/// -/// See -fn scale_cjk_axis_metrics( - dim: Dimension, - widths: &[i32], - width_metrics: WidthMetrics, - blues: &[UnscaledBlue], - scale: &mut Scale, -) -> ScaledAxisMetrics { - let mut axis = ScaledAxisMetrics { - dim, - ..Default::default() - }; - axis.dim = dim; - if dim == Axis::HORIZONTAL { - axis.scale = scale.x_scale; - axis.delta = scale.x_delta; - } else { - axis.scale = scale.y_scale; - axis.delta = scale.y_delta; - }; - let scale = axis.scale; - // Scale the blue zones - for unscaled_blue in blues { - let position = fixed_mul(unscaled_blue.position, scale) + axis.delta; - let overshoot = fixed_mul(unscaled_blue.overshoot, scale) + axis.delta; - let mut blue = ScaledBlue { - position: ScaledWidth { - scaled: position, - fitted: position, - }, - overshoot: ScaledWidth { - scaled: overshoot, - fitted: overshoot, - }, - zones: unscaled_blue.zones, - is_active: false, - }; - // A blue zone is only active if it is less than 3/4 pixels tall - let dist = fixed_mul(unscaled_blue.position - unscaled_blue.overshoot, scale); - if (-48..=48).contains(&dist) { - blue.position.fitted = pix_round(blue.position.scaled); - // For CJK, "overshoot" is actually undershoot - let delta1 = fixed_div(blue.position.fitted, scale) - unscaled_blue.overshoot; - let mut delta2 = fixed_mul(delta1.abs(), scale); - if delta2 < 32 { - delta2 = 0; - } else { - delta2 = pix_round(delta2); - } - if delta1 < 0 { - delta2 = -delta2; - } - blue.overshoot.fitted = blue.position.fitted - delta2; - blue.is_active = true; - } - axis.blues.push(blue); - } - // FreeType never seems to compute scaled width values. We'll just - // match this behavior for now. - // - for _ in 0..widths.len() { - axis.widths.push(ScaledWidth::default()); - } - axis.width_metrics = width_metrics; - axis -} - -#[cfg(test)] -mod tests { - use super::{ - super::super::{shape::ShaperMode, style}, - *, - }; - use crate::attribute::Style; - use raw::{FontRef, TableProvider}; - - #[test] - fn scaled_metrics_default() { - // Note: expected values scraped from a FreeType debugging - // session - let scaled_metrics = make_scaled_metrics( - font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, - StyleClass::HEBR, - ); - // Check scale and deltas - assert_eq!(scaled_metrics.scale.x_scale, 67109); - assert_eq!(scaled_metrics.scale.y_scale, 67109); - assert_eq!(scaled_metrics.scale.x_delta, 0); - assert_eq!(scaled_metrics.scale.y_delta, 0); - // Horizontal widths - let h_axis = &scaled_metrics.axes[0]; - let expected_h_widths = [55]; - // No horizontal blues - check_axis(h_axis, &expected_h_widths, &[]); - // Not extra light - assert!(!h_axis.width_metrics.is_extra_light); - // Vertical widths - let v_axis = &scaled_metrics.axes[1]; - let expected_v_widths = [22, 112]; - // Vertical blues - #[rustfmt::skip] - let expected_v_blues = [ - // ((scaled_pos, fitted_pos), (scaled_shoot, fitted_shoot), flags, is_active) - ScaledBlue::from(((606, 576), (606, 576), BlueZones::TOP, true)), - ScaledBlue::from(((0, 0), (-9, 0), BlueZones::default(), true)), - ScaledBlue::from(((-246, -256), (-246, -256), BlueZones::default(), true)), - ]; - check_axis(v_axis, &expected_v_widths, &expected_v_blues); - // This one is extra light - assert!(v_axis.width_metrics.is_extra_light); - } - - #[test] - fn cjk_scaled_metrics() { - // Note: expected values scraped from a FreeType debugging - // session - let scaled_metrics = make_scaled_metrics( - font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, - StyleClass::HANI, - ); - // Check scale and deltas - assert_eq!(scaled_metrics.scale.x_scale, 67109); - assert_eq!(scaled_metrics.scale.y_scale, 67109); - assert_eq!(scaled_metrics.scale.x_delta, 0); - assert_eq!(scaled_metrics.scale.y_delta, 0); - // Horizontal widths - let h_axis = &scaled_metrics.axes[0]; - let expected_h_widths = [0]; - check_axis(h_axis, &expected_h_widths, &[]); - // Not extra light - assert!(!h_axis.width_metrics.is_extra_light); - // Vertical widths - let v_axis = &scaled_metrics.axes[1]; - let expected_v_widths = [0]; - // Vertical blues - #[rustfmt::skip] - let expected_v_blues = [ - // ((scaled_pos, fitted_pos), (scaled_shoot, fitted_shoot), flags, is_active) - ScaledBlue::from(((857, 832), (844, 832), BlueZones::TOP, true)), - ScaledBlue::from(((-80, -64), (-68, -64), BlueZones::default(), true)), - ]; - // No horizontal blues - check_axis(v_axis, &expected_v_widths, &expected_v_blues); - // Also not extra light - assert!(!v_axis.width_metrics.is_extra_light); - } - - fn make_scaled_metrics(font_data: &[u8], style_class: usize) -> ScaledStyleMetrics { - let font = FontRef::new(font_data).unwrap(); - let class = &style::STYLE_CLASSES[style_class]; - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let unscaled_metrics = compute_unscaled_style_metrics(&shaper, Default::default(), class); - let scale = Scale::new( - 16.0, - font.head().unwrap().units_per_em() as i32, - Style::Normal, - Default::default(), - class.script.group, - ); - scale_style_metrics(&unscaled_metrics, scale) - } - - fn check_axis( - axis: &ScaledAxisMetrics, - expected_widths: &[i32], - expected_blues: &[ScaledBlue], - ) { - let widths = axis - .widths - .iter() - .map(|width| width.scaled) - .collect::>(); - assert_eq!(widths, expected_widths); - assert_eq!(axis.blues.as_slice(), expected_blues); - } - - impl From<(i32, i32)> for ScaledWidth { - fn from(value: (i32, i32)) -> Self { - Self { - scaled: value.0, - fitted: value.1, - } - } - } - - impl From<((i32, i32), (i32, i32), BlueZones, bool)> for ScaledBlue { - fn from(value: ((i32, i32), (i32, i32), BlueZones, bool)) -> Self { - Self { - position: value.0.into(), - overshoot: value.1.into(), - zones: value.2, - is_active: value.3, - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ -//! Latin standard stem width computation. - -use super::super::{ - derived_constant, - metrics::{self, UnscaledWidths, WidthMetrics, MAX_WIDTHS}, - outline::Outline, - shape::{ShapedCluster, Shaper}, - style::{ScriptGroup, StyleClass}, - topo::{compute_segments, link_segments, Axis}, -}; -use crate::MetadataProvider; -use raw::{types::F2Dot14, TableProvider}; - -/// Compute all stem widths and initialize standard width and height for the -/// given script. -/// -/// Returns width metrics and unscaled widths for each dimension. -/// -/// See -pub(super) fn compute_widths( - shaper: &Shaper, - coords: &[F2Dot14], - style: &StyleClass, -) -> [(WidthMetrics, UnscaledWidths); 2] { - let mut result: [(WidthMetrics, UnscaledWidths); 2] = Default::default(); - let font = shaper.font(); - let glyphs = font.outline_glyphs(); - let units_per_em = font - .head() - .map(|head| head.units_per_em() as i32) - .unwrap_or_default(); - let mut outline = Outline::default(); - let mut axis = Axis::default(); - let mut cluster_shaper = shaper.cluster_shaper(style); - let mut shaped_cluster = ShapedCluster::default(); - // We take the first available glyph from the standard character set. - let glyph = style - .script - .std_chars - .split(' ') - .filter_map(|cluster| { - cluster_shaper.shape(cluster, &mut shaped_cluster); - // Reject input that maps to more than a single glyph - // See - match shaped_cluster.as_slice() { - [glyph] if glyph.id.to_u32() != 0 => glyphs.get(glyph.id), - _ => None, - } - }) - .next(); - if let Some(glyph) = glyph { - if outline.fill(&glyph, coords).is_ok() && !outline.points.is_empty() { - // Now process each dimension - for (dim, (_metrics, widths)) in result.iter_mut().enumerate() { - axis.reset(dim, outline.orientation); - // Segment computation for widths always uses the default - // script group - compute_segments(&mut outline, &mut axis, ScriptGroup::Default); - link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); - let segments = axis.segments.as_slice(); - for (segment_ix, segment) in segments.iter().enumerate() { - let segment_ix = segment_ix as u16; - let Some(link_ix) = segment.link_ix else { - continue; - }; - let link = &segments[link_ix as usize]; - if link_ix > segment_ix && link.link_ix == Some(segment_ix) { - let dist = (segment.pos as i32 - link.pos as i32).abs(); - if widths.len() < MAX_WIDTHS { - widths.push(dist); - } else { - break; - } - } - } - // FreeTypes `af_sort_and_quantize_widths()` has the side effect - // of always updating the width count to 1 when we don't find - // any... - // See - if widths.is_empty() { - widths.push(0); - } - // The value 100 is heuristic - metrics::sort_and_quantize_widths(widths, units_per_em / 100); - } - } - } - for (metrics, widths) in result.iter_mut() { - // Now set derived values - let stdw = widths - .first() - .copied() - .unwrap_or_else(|| derived_constant(units_per_em, 50)); - // Heuristic value of 20% of the smallest width - metrics.edge_distance_threshold = stdw / 5; - metrics.standard_width = stdw; - metrics.is_extra_light = false; - } - result -} - -#[cfg(test)] -mod tests { - use super::{ - super::super::{shape::ShaperMode, style}, - *, - }; - use raw::FontRef; - - #[test] - fn computed_widths() { - // Expected data produced by internal routines in FreeType. Scraped - // from a debugger - check_widths( - font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, - super::StyleClass::HEBR, - [ - ( - WidthMetrics { - edge_distance_threshold: 10, - standard_width: 54, - is_extra_light: false, - }, - &[54], - ), - ( - WidthMetrics { - edge_distance_threshold: 4, - standard_width: 21, - is_extra_light: false, - }, - &[21, 109], - ), - ], - ); - } - - #[test] - fn fallback_widths() { - // Expected data produced by internal routines in FreeType. Scraped - // from a debugger - check_widths( - font_test_data::CANTARELL_VF_TRIMMED, - super::StyleClass::LATN, - [ - ( - WidthMetrics { - edge_distance_threshold: 4, - standard_width: 24, - is_extra_light: false, - }, - &[], - ), - ( - WidthMetrics { - edge_distance_threshold: 4, - standard_width: 24, - is_extra_light: false, - }, - &[], - ), - ], - ); - } - - #[test] - fn cjk_computed_widths() { - // Expected data produced by internal routines in FreeType. Scraped - // from a debugger - check_widths( - font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, - super::StyleClass::HANI, - [ - ( - WidthMetrics { - edge_distance_threshold: 13, - standard_width: 65, - is_extra_light: false, - }, - &[65], - ), - ( - WidthMetrics { - edge_distance_threshold: 5, - standard_width: 29, - is_extra_light: false, - }, - &[29], - ), - ], - ); - } - - fn check_widths(font_data: &[u8], style_class: usize, expected: [(WidthMetrics, &[i32]); 2]) { - let font = FontRef::new(font_data).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let script = &style::STYLE_CLASSES[style_class]; - let [(hori_metrics, hori_widths), (vert_metrics, vert_widths)] = - compute_widths(&shaper, Default::default(), script); - assert_eq!(hori_metrics, expected[0].0); - assert_eq!(hori_widths.as_slice(), expected[0].1); - assert_eq!(vert_metrics, expected[1].0); - assert_eq!(vert_widths.as_slice(), expected[1].1); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -//! Runtime autohinting support. - -mod hint; -mod instance; -mod metrics; -mod outline; -mod shape; -mod style; -mod topo; - -pub use instance::GlyphStyles; -pub(crate) use instance::Instance; - -/// All constants are defined based on a UPEM of 2048. -/// -/// See -fn derived_constant(units_per_em: i32, value: i32) -> i32 { - value * units_per_em / 2048 -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,768 +0,0 @@ -//! Outline representation and helpers for autohinting. - -use super::{ - super::{ - path, - pen::PathStyle, - unscaled::{UnscaledOutlineSink, UnscaledPoint}, - DrawError, LocationRef, OutlineGlyph, OutlinePen, - }, - metrics::Scale, -}; -use crate::collections::SmallVec; -use core::ops::Range; -use raw::{ - tables::glyf::{PointFlags, PointMarker}, - types::{F26Dot6, F2Dot14}, -}; - -/// Hinting directions. -/// -/// The values are such that `dir1 + dir2 == 0` when the directions are -/// opposite. -/// -/// See -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -#[repr(i8)] -pub(crate) enum Direction { - #[default] - None = 4, - Right = 1, - Left = -1, - Up = 2, - Down = -2, -} - -impl Direction { - /// Computes a direction from a vector. - /// - /// See - pub fn new(dx: i32, dy: i32) -> Self { - let (dir, long_arm, short_arm) = if dy >= dx { - if dy >= -dx { - (Direction::Up, dy, dx) - } else { - (Direction::Left, -dx, dy) - } - } else if dy >= -dx { - (Direction::Right, dx, dy) - } else { - (Direction::Down, -dy, dx) - }; - // Return no direction if arm lengths do not differ enough. - // - if long_arm <= 14 * short_arm.abs() { - Direction::None - } else { - dir - } - } - - pub fn is_opposite(self, other: Self) -> bool { - self as i8 + other as i8 == 0 - } - - pub fn is_same_axis(self, other: Self) -> bool { - (self as i8).abs() == (other as i8).abs() - } - - pub fn normalize(self) -> Self { - // FreeType uses absolute value for this. - match self { - Self::Left => Self::Right, - Self::Down => Self::Up, - _ => self, - } - } -} - -/// The overall orientation of an outline. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub(crate) enum Orientation { - Clockwise, - CounterClockwise, -} - -/// Outline point with a lot of context for hinting. -/// -/// See -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(super) struct Point { - /// Describes the type and hinting state of the point. - pub flags: PointFlags, - /// X coordinate in font units. - pub fx: i32, - /// Y coordinate in font units. - pub fy: i32, - /// Scaled X coordinate. - pub ox: i32, - /// Scaled Y coordinate. - pub oy: i32, - /// Hinted X coordinate. - pub x: i32, - /// Hinted Y coordinate. - pub y: i32, - /// Direction of inwards vector. - pub in_dir: Direction, - /// Direction of outwards vector. - pub out_dir: Direction, - /// Context dependent coordinate. - pub u: i32, - /// Context dependent coordinate. - pub v: i32, - /// Index of next point in contour. - pub next_ix: u16, - /// Index of previous point in contour. - pub prev_ix: u16, -} - -impl Point { - pub fn is_on_curve(&self) -> bool { - self.flags.is_on_curve() - } - - /// Returns the index of the next point in the contour. - pub fn next(&self) -> usize { - self.next_ix as usize - } - - /// Returns the index of the previous point in the contour. - pub fn prev(&self) -> usize { - self.prev_ix as usize - } - - #[inline(always)] - fn as_contour_point(&self) -> path::ContourPoint { - path::ContourPoint { - x: F26Dot6::from_bits(self.x), - y: F26Dot6::from_bits(self.y), - flags: self.flags, - } - } -} - -// Matches FreeType's inline usage -// -// See -const MAX_INLINE_POINTS: usize = 96; -const MAX_INLINE_CONTOURS: usize = 8; - -#[derive(Default)] -pub(super) struct Outline { - pub units_per_em: i32, - pub orientation: Option, - pub points: SmallVec, - pub contours: SmallVec, - pub advance: i32, -} - -impl Outline { - /// Fills the outline from the given glyph. - pub fn fill(&mut self, glyph: &OutlineGlyph, coords: &[F2Dot14]) -> Result<(), DrawError> { - self.clear(); - let advance = glyph.draw_unscaled(LocationRef::new(coords), None, self)?; - self.advance = advance; - self.units_per_em = glyph.units_per_em() as i32; - // Heuristic value - let near_limit = 20 * self.units_per_em / 2048; - self.link_points(); - self.mark_near_points(near_limit); - self.compute_directions(near_limit); - self.simplify_topology(); - self.check_remaining_weak_points(); - self.compute_orientation(); - Ok(()) - } - - /// Applies dimension specific scaling factors and deltas to each - /// point in the outline. - pub fn scale(&mut self, scale: &Scale) { - use super::metrics::fixed_mul; - for point in &mut self.points { - let x = fixed_mul(point.fx, scale.x_scale) + scale.x_delta; - let y = fixed_mul(point.fy, scale.y_scale) + scale.y_delta; - point.ox = x; - point.x = x; - point.oy = y; - point.y = y; - } - } - - pub fn clear(&mut self) { - self.units_per_em = 0; - self.points.clear(); - self.contours.clear(); - self.advance = 0; - } - - pub fn to_path( - &self, - style: PathStyle, - pen: &mut impl OutlinePen, - ) -> Result<(), path::ToPathError> { - for contour in &self.contours { - let Some(points) = self.points.get(contour.range()) else { - continue; - }; - if let Some(last_point) = points.last().map(Point::as_contour_point) { - path::contour_to_path( - points.iter().map(Point::as_contour_point), - last_point, - style, - pen, - )?; - } - } - Ok(()) - } -} - -impl Outline { - /// Sets next and previous indices for each point. - fn link_points(&mut self) { - let points = self.points.as_mut_slice(); - for contour in &self.contours { - let Some(points) = points.get_mut(contour.range()) else { - continue; - }; - let first_ix = contour.first() as u16; - let mut prev_ix = contour.last() as u16; - for (ix, point) in points.iter_mut().enumerate() { - let ix = ix as u16 + first_ix; - point.prev_ix = prev_ix; - prev_ix = ix; - point.next_ix = ix + 1; - } - points.last_mut().unwrap().next_ix = first_ix; - } - } - - /// Computes the near flag for each contour. - /// - /// See - fn mark_near_points(&mut self, near_limit: i32) { - let points = self.points.as_mut_slice(); - for contour in &self.contours { - let mut prev_ix = contour.last(); - for ix in contour.range() { - let point = points[ix]; - let prev = &mut points[prev_ix]; - // - let out_x = point.fx - prev.fx; - let out_y = point.fy - prev.fy; - if out_x.abs() + out_y.abs() < near_limit { - prev.flags.set_marker(PointMarker::NEAR); - } - prev_ix = ix; - } - } - } - - /// Compute directions of in and out vectors. - /// - /// See - fn compute_directions(&mut self, near_limit: i32) { - let near_limit2 = 2 * near_limit - 1; - let points = self.points.as_mut_slice(); - for contour in &self.contours { - // Walk backward to find the first non-near point. - let mut first_ix = contour.first(); - let mut ix = first_ix; - let mut prev_ix = contour.prev(first_ix); - let mut point = points[first_ix]; - while prev_ix != first_ix { - let prev = points[prev_ix]; - let out_x = point.fx - prev.fx; - let out_y = point.fy - prev.fy; - // - if out_x.abs() + out_y.abs() >= near_limit2 { - break; - } - point = prev; - ix = prev_ix; - prev_ix = contour.prev(prev_ix); - } - first_ix = ix; - // Abuse u and v fields to store deltas to the next and previous - // non-near points, respectively. - let first = &mut points[first_ix]; - first.u = first_ix as _; - first.v = first_ix as _; - let mut next_ix = first_ix; - let mut ix = first_ix; - // Now loop over all points in the contour to compute in and - // out directions - let mut out_x = 0; - let mut out_y = 0; - loop { - let point_ix = next_ix; - next_ix = contour.next(point_ix); - let point = points[point_ix]; - let next = &mut points[next_ix]; - // Accumulate the deltas until we surpass near_limit - out_x += next.fx - point.fx; - out_y += next.fy - point.fy; - if out_x.abs() + out_y.abs() < near_limit { - next.flags.set_marker(PointMarker::WEAK_INTERPOLATION); - // The original code is a do-while loop, so make - // sure we keep this condition before the continue - if next_ix == first_ix { - break; - } - continue; - } - let out_dir = Direction::new(out_x, out_y); - next.in_dir = out_dir; - next.v = ix as _; - let cur = &mut points[ix]; - cur.u = next_ix as _; - cur.out_dir = out_dir; - // Adjust directions for all intermediate points - let mut inter_ix = contour.next(ix); - while inter_ix != next_ix { - let point = &mut points[inter_ix]; - point.in_dir = out_dir; - point.out_dir = out_dir; - inter_ix = contour.next(inter_ix); - } - ix = next_ix; - points[ix].u = first_ix as _; - points[first_ix].v = ix as _; - out_x = 0; - out_y = 0; - if next_ix == first_ix { - break; - } - } - } - } - - /// Simplify so that we can identify local extrema more reliably. - /// - /// See - fn simplify_topology(&mut self) { - let points = self.points.as_mut_slice(); - for i in 0..points.len() { - let point = points[i]; - if point.flags.has_marker(PointMarker::WEAK_INTERPOLATION) { - continue; - } - if point.in_dir == Direction::None && point.out_dir == Direction::None { - let u_index = point.u as usize; - let v_index = point.v as usize; - let next_u = points[u_index]; - let prev_v = points[v_index]; - let in_x = point.fx - prev_v.fx; - let in_y = point.fy - prev_v.fy; - let out_x = next_u.fx - point.fx; - let out_y = next_u.fy - point.fy; - if (in_x ^ out_x) >= 0 && (in_y ^ out_y) >= 0 { - // Both vectors point into the same quadrant - points[i].flags.set_marker(PointMarker::WEAK_INTERPOLATION); - points[v_index].u = u_index as _; - points[u_index].v = v_index as _; - } - } - } - } - - /// Check for remaining weak points. - /// - /// See - fn check_remaining_weak_points(&mut self) { - let points = self.points.as_mut_slice(); - for i in 0..points.len() { - let point = points[i]; - let mut make_weak = false; - if point.flags.has_marker(PointMarker::WEAK_INTERPOLATION) { - // Already weak - continue; - } - if !point.flags.is_on_curve() { - // Control points are always weak - make_weak = true; - } else if point.out_dir == point.in_dir { - if point.out_dir != Direction::None { - // Point lies on a vertical or horizontal segment but - // not at start or end - make_weak = true; - } else { - let u_index = point.u as usize; - let v_index = point.v as usize; - let next_u = points[u_index]; - let prev_v = points[v_index]; - if is_corner_flat( - point.fx - prev_v.fx, - point.fy - prev_v.fy, - next_u.fx - point.fx, - next_u.fy - point.fy, - ) { - // One of the vectors is more dominant - make_weak = true; - points[v_index].u = u_index as _; - points[u_index].v = v_index as _; - } - } - } else if point.in_dir.is_opposite(point.out_dir) { - // Point forms a "spike" - make_weak = true; - } - if make_weak { - points[i].flags.set_marker(PointMarker::WEAK_INTERPOLATION); - } - } - } - - /// Computes the overall winding order of the outline. - /// - /// See - fn compute_orientation(&mut self) { - self.orientation = None; - let points = self.points.as_slice(); - if points.is_empty() { - return; - } - fn point_to_i64(point: &Point) -> (i64, i64) { - (point.fx as i64, point.fy as i64) - } - let mut area = 0i64; - for contour in &self.contours { - let last_ix = contour.last(); - let first_ix = contour.first(); - let (mut prev_x, mut prev_y) = point_to_i64(&points[last_ix]); - for point in &points[first_ix..=last_ix] { - let (x, y) = point_to_i64(point); - area += (y - prev_y) * (x + prev_x); - (prev_x, prev_y) = (x, y); - } - } - use core::cmp::Ordering; - self.orientation = match area.cmp(&0) { - Ordering::Less => Some(Orientation::CounterClockwise), - Ordering::Greater => Some(Orientation::Clockwise), - Ordering::Equal => None, - }; - } -} - -/// See -fn is_corner_flat(in_x: i32, in_y: i32, out_x: i32, out_y: i32) -> bool { - let ax = in_x + out_x; - let ay = in_y + out_y; - fn hypot(x: i32, y: i32) -> i32 { - let x = x.abs(); - let y = y.abs(); - if x > y { - x + ((3 * y) >> 3) - } else { - y + ((3 * x) >> 3) - } - } - let d_in = hypot(in_x, in_y); - let d_out = hypot(out_x, out_y); - let d_hypot = hypot(ax, ay); - (d_in + d_out - d_hypot) < (d_hypot >> 4) -} - -#[derive(Copy, Clone, Default, Debug)] -pub(super) struct Contour { - first_ix: u16, - last_ix: u16, -} - -impl Contour { - pub fn first(self) -> usize { - self.first_ix as usize - } - - pub fn last(self) -> usize { - self.last_ix as usize - } - - pub fn next(self, index: usize) -> usize { - if index >= self.last_ix as usize { - self.first_ix as usize - } else { - index + 1 - } - } - - pub fn prev(self, index: usize) -> usize { - if index <= self.first_ix as usize { - self.last_ix as usize - } else { - index - 1 - } - } - - pub fn range(self) -> Range { - self.first()..self.last() + 1 - } -} - -impl UnscaledOutlineSink for Outline { - fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError> { - if self.points.try_reserve(additional) { - Ok(()) - } else { - Err(DrawError::InsufficientMemory) - } - } - - fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError> { - let new_point = Point { - flags: point.flags, - fx: point.x as i32, - fy: point.y as i32, - ..Default::default() - }; - let new_point_ix: u16 = self - .points - .len() - .try_into() - .map_err(|_| DrawError::InsufficientMemory)?; - if point.is_contour_start { - self.contours.push(Contour { - first_ix: new_point_ix, - last_ix: new_point_ix, - }); - } else if let Some(last_contour) = self.contours.last_mut() { - last_contour.last_ix += 1; - } else { - // If our first point is not marked as contour start, just - // create a new contour. - self.contours.push(Contour { - first_ix: new_point_ix, - last_ix: new_point_ix, - }); - } - self.points.push(new_point); - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::super::super::{pen::SvgPen, DrawSettings}; - use super::*; - use crate::{prelude::Size, MetadataProvider}; - use raw::{types::GlyphId, FontRef, TableProvider}; - - #[test] - fn direction_from_vectors() { - assert_eq!(Direction::new(-100, 0), Direction::Left); - assert_eq!(Direction::new(100, 0), Direction::Right); - assert_eq!(Direction::new(0, -100), Direction::Down); - assert_eq!(Direction::new(0, 100), Direction::Up); - assert_eq!(Direction::new(7, 100), Direction::Up); - // This triggers the too close heuristic - assert_eq!(Direction::new(8, 100), Direction::None); - } - - #[test] - fn direction_axes() { - use Direction::*; - let hori = [Left, Right]; - let vert = [Up, Down]; - for h in hori { - for h2 in hori { - assert!(h.is_same_axis(h2)); - if h != h2 { - assert!(h.is_opposite(h2)); - } else { - assert!(!h.is_opposite(h2)); - } - } - for v in vert { - assert!(!h.is_same_axis(v)); - assert!(!h.is_opposite(v)); - } - } - for v in vert { - for v2 in vert { - assert!(v.is_same_axis(v2)); - if v != v2 { - assert!(v.is_opposite(v2)); - } else { - assert!(!v.is_opposite(v2)); - } - } - } - } - - #[test] - fn fill_outline() { - let outline = make_outline(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, 8); - use Direction::*; - let expected = &[ - // (x, y, in_dir, out_dir, flags) - (107, 0, Left, Left, 3), - (85, 0, Left, None, 2), - (55, 26, None, Up, 2), - (55, 71, Up, Up, 3), - (55, 332, Up, Up, 3), - (55, 360, Up, None, 2), - (67, 411, None, None, 2), - (93, 459, None, None, 2), - (112, 481, None, Up, 1), - (112, 504, Up, Right, 1), - (168, 504, Right, Down, 1), - (168, 483, Down, None, 1), - (153, 473, None, None, 2), - (126, 428, None, None, 2), - (109, 366, None, Down, 2), - (109, 332, Down, Down, 3), - (109, 109, Down, Right, 1), - (407, 109, Right, Right, 3), - (427, 109, Right, None, 2), - (446, 136, None, None, 2), - (453, 169, None, Up, 2), - (453, 178, Up, Up, 3), - (453, 374, Up, Up, 3), - (453, 432, Up, None, 2), - (400, 483, None, Left, 2), - (362, 483, Left, Left, 3), - (109, 483, Left, Left, 3), - (86, 483, Left, None, 2), - (62, 517, None, Up, 2), - (62, 555, Up, Up, 3), - (62, 566, Up, None, 2), - (64, 587, None, None, 2), - (71, 619, None, None, 2), - (76, 647, None, Right, 1), - (103, 647, Right, Down, 9), - (103, 644, Down, Down, 3), - (103, 619, Down, None, 2), - (131, 592, None, Right, 2), - (155, 592, Right, Right, 3), - (386, 592, Right, Right, 3), - (437, 592, Right, None, 2), - (489, 552, None, None, 2), - (507, 485, None, Down, 2), - (507, 443, Down, Down, 3), - (507, 75, Down, Down, 3), - (507, 40, Down, None, 2), - (470, 0, None, Left, 2), - (436, 0, Left, Left, 3), - ]; - let points = outline - .points - .iter() - .map(|point| { - ( - point.fx, - point.fy, - point.in_dir, - point.out_dir, - point.flags.to_bits(), - ) - }) - .collect::>(); - assert_eq!(&points, expected); - } - - #[test] - fn orientation() { - let tt_outline = make_outline(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, 8); - // TrueType outlines are counter clockwise - assert_eq!(tt_outline.orientation, Some(Orientation::CounterClockwise)); - let ps_outline = make_outline(font_test_data::CANTARELL_VF_TRIMMED, 4); - // PostScript outlines are clockwise - assert_eq!(ps_outline.orientation, Some(Orientation::Clockwise)); - } - - fn make_outline(font_data: &[u8], glyph_id: u32) -> Outline { - let font = FontRef::new(font_data).unwrap(); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::from(glyph_id)).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - outline - } - - #[test] - fn mostly_off_curve_to_path_scan_backward() { - compare_path_conversion(font_test_data::MOSTLY_OFF_CURVE, PathStyle::FreeType); - } - - #[test] - fn mostly_off_curve_to_path_scan_forward() { - compare_path_conversion(font_test_data::MOSTLY_OFF_CURVE, PathStyle::HarfBuzz); - } - - #[test] - fn starting_off_curve_to_path_scan_backward() { - compare_path_conversion(font_test_data::STARTING_OFF_CURVE, PathStyle::FreeType); - } - - #[test] - fn starting_off_curve_to_path_scan_forward() { - compare_path_conversion(font_test_data::STARTING_OFF_CURVE, PathStyle::HarfBuzz); - } - - #[test] - fn cubic_to_path_scan_backward() { - compare_path_conversion(font_test_data::CUBIC_GLYF, PathStyle::FreeType); - } - - #[test] - fn cubic_to_path_scan_forward() { - compare_path_conversion(font_test_data::CUBIC_GLYF, PathStyle::HarfBuzz); - } - - #[test] - fn cff_to_path_scan_backward() { - compare_path_conversion(font_test_data::CANTARELL_VF_TRIMMED, PathStyle::FreeType); - } - - #[test] - fn cff_to_path_scan_forward() { - compare_path_conversion(font_test_data::CANTARELL_VF_TRIMMED, PathStyle::HarfBuzz); - } - - /// Ensures autohint path conversion matches the base scaler path - /// conversion for all glyphs in the given font with a certain - /// path style. - fn compare_path_conversion(font_data: &[u8], path_style: PathStyle) { - let font = FontRef::new(font_data).unwrap(); - let glyph_count = font.maxp().unwrap().num_glyphs(); - let glyphs = font.outline_glyphs(); - let mut results = Vec::new(); - // And all glyphs - for gid in 0..glyph_count { - let glyph = glyphs.get(GlyphId::from(gid)).unwrap(); - // Unscaled, unhinted code path - let mut base_svg = SvgPen::default(); - let settings = DrawSettings::unhinted(Size::unscaled(), LocationRef::default()) - .with_path_style(path_style); - glyph.draw(settings, &mut base_svg).unwrap(); - let base_svg = base_svg.to_string(); - // Autohinter outline code path - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - // The to_path method uses the (x, y) coords which aren't filled - // until we scale (and we aren't doing that here) so update - // them with 26.6 values manually - for point in &mut outline.points { - point.x = point.fx << 6; - point.y = point.fy << 6; - } - let mut autohint_svg = SvgPen::default(); - outline.to_path(path_style, &mut autohint_svg).unwrap(); - let autohint_svg = autohint_svg.to_string(); - if base_svg != autohint_svg { - results.push((gid, base_svg, autohint_svg)); - } - } - if !results.is_empty() { - let report: String = results - .into_iter() - .map(|(gid, expected, got)| { - format!("[glyph {gid}]\nexpected: {expected}\n got: {got}") - }) - .collect::>() - .join("\n"); - panic!("outline to path comparison failed:\n{report}"); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,781 +0,0 @@ -//! Shaping support for autohinting. - -use super::style::{GlyphStyle, StyleClass}; -use crate::{charmap::Charmap, collections::SmallVec, FontRef, GlyphId, MetadataProvider}; -use core::ops::Range; -use raw::{ - tables::{ - gsub::{ - ChainedSequenceContext, Gsub, SequenceContext, SingleSubst, SubstitutionLookupList, - SubstitutionSubtables, - }, - layout::{Feature, ScriptTags}, - varc::CoverageTable, - }, - types::Tag, - ReadError, TableProvider, -}; - -// To prevent infinite recursion in contextual lookups. Matches HB -// -const MAX_NESTING_DEPTH: usize = 64; - -/// Determines the fidelity with which we apply shaping in the -/// autohinter. -/// -/// Shaping only affects glyph style classification and the glyphs that -/// are chosen for metrics computations. We keep the `Nominal` mode around -/// to enable validation of internal algorithms against a configuration that -/// is known to match FreeType. The `BestEffort` mode should always be -/// used for actual rendering. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub(crate) enum ShaperMode { - /// Characters are mapped to nominal glyph identifiers and layout tables - /// are not used for style coverage. - /// - /// This matches FreeType when HarfBuzz support is not enabled. - Nominal, - /// Simple substitutions are applied according to script rules and layout - /// tables are used to extend style coverage beyond the character map. - #[allow(unused)] - BestEffort, -} - -#[derive(Copy, Clone, Default, Debug)] -pub(crate) struct ShapedGlyph { - pub id: GlyphId, - /// This may be used for computing vertical alignment zones, particularly - /// for glyphs like super/subscripts which might have adjustments in GPOS. - /// - /// Note that we don't do the same in the horizontal direction which - /// means that we don't care about the x-offset. - pub y_offset: i32, -} - -/// Arbitrarily chosen to cover our max input size plus some extra to account -/// for expansion from multiple substitution tables. -const SHAPED_CLUSTER_INLINE_SIZE: usize = 16; - -/// Container for storing the result of shaping a cluster. -/// -/// Some of our input "characters" for metrics computations are actually -/// multi-character [grapheme clusters](https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) -/// that may expand to multiple glyphs. -pub(crate) type ShapedCluster = SmallVec; - -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub(crate) enum ShaperCoverageKind { - /// Shaper coverage that traverses a specific script. - Script, - /// Shaper coverage that also includes the `Dflt` script. - /// - /// This is used as a catch all after all styles are processed. - Default, -} - -/// Maps characters to glyphs and handles extended style coverage beyond -/// glyphs that are available in the character map. -/// -/// Roughly covers the functionality in . -pub(crate) struct Shaper<'a> { - font: FontRef<'a>, - #[allow(unused)] - mode: ShaperMode, - charmap: Charmap<'a>, - gsub: Option>, -} - -impl<'a> Shaper<'a> { - pub fn new(font: &FontRef<'a>, mode: ShaperMode) -> Self { - let charmap = font.charmap(); - let gsub = (mode != ShaperMode::Nominal) - .then(|| font.gsub().ok()) - .flatten(); - Self { - font: font.clone(), - mode, - charmap, - gsub, - } - } - - pub fn font(&self) -> &FontRef<'a> { - &self.font - } - - pub fn charmap(&self) -> &Charmap<'a> { - &self.charmap - } - - pub fn cluster_shaper(&'a self, style: &StyleClass) -> ClusterShaper<'a> { - if self.mode == ShaperMode::BestEffort { - // For now, only apply substitutions for styles with an associated - // feature - if let Some(feature_tag) = style.feature { - if let Some((lookup_list, feature)) = self.gsub.as_ref().and_then(|gsub| { - let script_list = gsub.script_list().ok()?; - let selected_script = - script_list.select(&ScriptTags::from_unicode(style.script.tag))?; - let script = script_list.get(selected_script.index).ok()?; - let lang_sys = script.default_lang_sys()?.ok()?; - let feature_list = gsub.feature_list().ok()?; - let feature_ix = lang_sys.feature_index_for_tag(&feature_list, feature_tag)?; - let feature = feature_list.get(feature_ix).ok()?.element; - let lookup_list = gsub.lookup_list().ok()?; - Some((lookup_list, feature)) - }) { - return ClusterShaper { - shaper: self, - lookup_list: Some(lookup_list), - kind: ClusterShaperKind::SingleFeature(feature), - }; - } - } - } - ClusterShaper { - shaper: self, - lookup_list: None, - kind: ClusterShaperKind::Nominal, - } - } - - /// Uses layout tables to compute coverage for the given style. - /// - /// Returns `true` if any glyph styles were updated for this style. - /// - /// See - pub(crate) fn compute_coverage( - &self, - style: &StyleClass, - coverage_kind: ShaperCoverageKind, - glyph_styles: &mut [GlyphStyle], - ) -> bool { - let Some(gsub) = self.gsub.as_ref() else { - return false; - }; - let (Ok(script_list), Ok(feature_list), Ok(lookup_list)) = - (gsub.script_list(), gsub.feature_list(), gsub.lookup_list()) - else { - return false; - }; - let mut script_tags: [Option; 3] = [None; 3]; - for (a, b) in script_tags - .iter_mut() - .zip(ScriptTags::from_unicode(style.script.tag).iter()) - { - *a = Some(*b); - } - // - const DEFAULT_SCRIPT: Tag = Tag::new(b"Dflt"); - if coverage_kind == ShaperCoverageKind::Default { - if script_tags[0].is_none() { - script_tags[0] = Some(DEFAULT_SCRIPT); - } else if script_tags[1].is_none() { - script_tags[1] = Some(DEFAULT_SCRIPT); - } else if script_tags[1] != Some(DEFAULT_SCRIPT) { - script_tags[2] = Some(DEFAULT_SCRIPT); - } - } else { - // Script classes contain some non-standard tags used for special - // purposes. We ignore these - // - const NON_STANDARD_TAGS: &[Option] = &[ - // Khmer symbols - Some(Tag::new(b"Khms")), - // Latin subscript fallbacks - Some(Tag::new(b"Latb")), - // Latin superscript fallbacks - Some(Tag::new(b"Latp")), - ]; - if NON_STANDARD_TAGS.contains(&script_tags[0]) { - return false; - } - } - // Check each requested script that is available in GSUB - let mut gsub_handler = GsubHandler::new(&self.charmap, &lookup_list, style, glyph_styles); - for script in script_tags.iter().filter_map(|tag| { - tag.and_then(|tag| script_list.index_for_tag(tag)) - .and_then(|ix| script_list.script_records().get(ix as usize)) - .and_then(|rec| rec.script(script_list.offset_data()).ok()) - }) { - // And all language systems for each script - for langsys in script - .lang_sys_records() - .iter() - .filter_map(|rec| rec.lang_sys(script.offset_data()).ok()) - .chain(script.default_lang_sys().transpose().ok().flatten()) - { - for feature_ix in langsys.feature_indices() { - let Some(feature) = feature_list - .feature_records() - .get(feature_ix.get() as usize) - .and_then(|rec| { - // If our style has a feature tag, we only look at that specific - // feature; otherwise, handle all of them - if style.feature == Some(rec.feature_tag()) || style.feature.is_none() { - rec.feature(feature_list.offset_data()).ok() - } else { - None - } - }) - else { - continue; - }; - // And now process associated lookups - for index in feature.lookup_list_indices().iter() { - // We only care about errors here for testing - let _ = gsub_handler.process_lookup(index.get()); - } - } - } - } - if let Some(range) = gsub_handler.finish() { - // If we get a range then we captured at least some glyphs so - // let's try to assign our current style - let mut result = false; - for glyph_style in &mut glyph_styles[range] { - // We only want to return true here if we actually assign the - // style to avoid computing unnecessary metrics - result |= glyph_style.maybe_assign_gsub_output_style(style); - } - result - } else { - false - } - } -} - -pub(crate) struct ClusterShaper<'a> { - shaper: &'a Shaper<'a>, - lookup_list: Option>, - kind: ClusterShaperKind<'a>, -} - -impl ClusterShaper<'_> { - pub(crate) fn shape(&mut self, input: &str, output: &mut ShapedCluster) { - // First fill the output cluster with the nominal character - // to glyph id mapping - output.clear(); - for ch in input.chars() { - output.push(ShapedGlyph { - id: self.shaper.charmap.map(ch).unwrap_or_default(), - y_offset: 0, - }); - } - match self.kind.clone() { - ClusterShaperKind::Nominal => { - // In nominal mode, reject clusters with multiple glyphs - // See - if self.shaper.mode == ShaperMode::Nominal && output.len() > 1 { - output.clear(); - } - } - ClusterShaperKind::SingleFeature(feature) => { - let mut did_subst = false; - for lookup_ix in feature.lookup_list_indices() { - let mut glyph_ix = 0; - while glyph_ix < output.len() { - did_subst |= self.apply_lookup(lookup_ix.get(), output, glyph_ix, 0); - glyph_ix += 1; - } - } - // Reject clusters that weren't modified by the feature. - // FreeType detects this by shaping twice and comparing gids - // but we just track substitutions - // - if !did_subst { - output.clear(); - } - } - } - } - - fn apply_lookup( - &self, - lookup_index: u16, - cluster: &mut ShapedCluster, - glyph_ix: usize, - nesting_depth: usize, - ) -> bool { - if nesting_depth > MAX_NESTING_DEPTH { - return false; - } - let Some(glyph) = cluster.get_mut(glyph_ix) else { - return false; - }; - let Some(subtables) = self - .lookup_list - .as_ref() - .and_then(|list| list.lookups().get(lookup_index as usize).ok()) - .and_then(|lookup| lookup.subtables().ok()) - else { - return false; - }; - match subtables { - // For now, just applying single substitutions because we're - // currently only handling shaping for "feature" styles like - // c2sc (caps to small caps) which are (almost?) always - // single substs - SubstitutionSubtables::Single(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - match table { - SingleSubst::Format1(table) => { - let Some(_) = table.coverage().ok().and_then(|cov| cov.get(glyph.id)) - else { - continue; - }; - let delta = table.delta_glyph_id() as i32; - glyph.id = GlyphId::from((glyph.id.to_u32() as i32 + delta) as u16); - return true; - } - SingleSubst::Format2(table) => { - let Some(cov_ix) = - table.coverage().ok().and_then(|cov| cov.get(glyph.id)) - else { - continue; - }; - let Some(subst) = table.substitute_glyph_ids().get(cov_ix as usize) - else { - continue; - }; - glyph.id = subst.get().into(); - return true; - } - } - } - } - SubstitutionSubtables::Multiple(_tables) => {} - SubstitutionSubtables::Ligature(_tables) => {} - SubstitutionSubtables::Alternate(_tables) => {} - SubstitutionSubtables::Contextual(_tables) => {} - SubstitutionSubtables::ChainContextual(_tables) => {} - SubstitutionSubtables::Reverse(_tables) => {} - } - false - } -} - -#[derive(Clone)] -enum ClusterShaperKind<'a> { - Nominal, - SingleFeature(Feature<'a>), -} - -/// Captures glyphs from the GSUB table that aren't present in cmap. -/// -/// FreeType does this in a few phases: -/// 1. Collect all lookups for a given set of scripts and features. -/// -/// 2. For each lookup, collect all _output_ glyphs. -/// -/// 3. If the style represents a specific feature, make sure at least one of -/// the characters in the associated blue string would be substituted by -/// those lookups. If none would be substituted, then we don't assign the -/// style to any glyphs because we don't have any modified alignment -/// zones. -/// -/// -/// We roll these into one pass over the lookups below so that we don't have -/// to allocate a lookup set or iterate them twice. Note that since -/// substitutions are checked for individual characters, we ignore ligatures -/// and contextual lookups (and alternates since they aren't applicable). -struct GsubHandler<'a> { - charmap: &'a Charmap<'a>, - lookup_list: &'a SubstitutionLookupList<'a>, - style: &'a StyleClass, - glyph_styles: &'a mut [GlyphStyle], - // Set to true when we need to check if any substitutions are available - // for our blue strings. This is the case when style.feature != None - need_blue_substs: bool, - // Keep track of our range of touched gids in the style list - min_gid: usize, - max_gid: usize, - // Stack for detecting cycles in lookups - lookup_stack: [u16; MAX_NESTING_DEPTH], - lookup_depth: usize, -} - -impl<'a> GsubHandler<'a> { - fn new( - charmap: &'a Charmap<'a>, - lookup_list: &'a SubstitutionLookupList, - style: &'a StyleClass, - glyph_styles: &'a mut [GlyphStyle], - ) -> Self { - let min_gid = glyph_styles.len(); - // If we have a feature, then we need to check the blue string to see - // if any substitutions are available. If not, we don't enable this - // style because it won't have any affect on alignment zones - let need_blue_substs = style.feature.is_some(); - Self { - charmap, - lookup_list, - style, - glyph_styles, - need_blue_substs, - min_gid, - max_gid: 0, - lookup_stack: [0; MAX_NESTING_DEPTH], - lookup_depth: 0, - } - } - - fn process_lookup(&mut self, lookup_index: u16) -> Result<(), ProcessLookupError> { - // Guard: don't cycle and don't exceed depth limit - // Note: we use a linear search here under the assumption that - // most fonts have shallow contextual lookup chains - if self.lookup_depth != 0 { - if self.lookup_depth == MAX_NESTING_DEPTH { - return Err(ProcessLookupError::ExceededMaxDepth); - } - if self.lookup_stack[..self.lookup_depth].contains(&lookup_index) { - return Err(ProcessLookupError::CycleDetected); - } - } - self.lookup_stack[self.lookup_depth] = lookup_index; - self.lookup_depth += 1; - - // Actually process the lookup - let result = self.process_lookup_inner(lookup_index); - - // Out we go again - self.lookup_depth -= 1; - result - } - - #[inline(always)] - fn process_lookup_inner(&mut self, lookup_index: u16) -> Result<(), ProcessLookupError> { - let Ok(subtables) = self - .lookup_list - .lookups() - .get(lookup_index as usize) - .and_then(|lookup| lookup.subtables()) - else { - return Ok(()); - }; - match subtables { - SubstitutionSubtables::Single(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - match table { - SingleSubst::Format1(table) => { - let Ok(coverage) = table.coverage() else { - continue; - }; - let delta = table.delta_glyph_id() as i32; - for gid in coverage.iter() { - self.capture_glyph((gid.to_u32() as i32 + delta) as u16 as u32); - } - // Check input coverage for blue strings if - // required and if we're not under a contextual - // lookup - if self.need_blue_substs && self.lookup_depth == 1 { - self.check_blue_coverage(Ok(coverage)); - } - } - SingleSubst::Format2(table) => { - for gid in table.substitute_glyph_ids() { - self.capture_glyph(gid.get().to_u32()); - } - // See above - if self.need_blue_substs && self.lookup_depth == 1 { - self.check_blue_coverage(table.coverage()); - } - } - } - } - } - SubstitutionSubtables::Multiple(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - for seq in table.sequences().iter().filter_map(|seq| seq.ok()) { - for gid in seq.substitute_glyph_ids() { - self.capture_glyph(gid.get().to_u32()); - } - } - // See above - if self.need_blue_substs && self.lookup_depth == 1 { - self.check_blue_coverage(table.coverage()); - } - } - } - SubstitutionSubtables::Ligature(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - for set in table.ligature_sets().iter().filter_map(|set| set.ok()) { - for lig in set.ligatures().iter().filter_map(|lig| lig.ok()) { - self.capture_glyph(lig.ligature_glyph().to_u32()); - } - } - } - } - SubstitutionSubtables::Alternate(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - for set in table.alternate_sets().iter().filter_map(|set| set.ok()) { - for gid in set.alternate_glyph_ids() { - self.capture_glyph(gid.get().to_u32()); - } - } - } - } - SubstitutionSubtables::Contextual(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - match table { - SequenceContext::Format1(table) => { - for set in table - .seq_rule_sets() - .iter() - .filter_map(|set| set.transpose().ok().flatten()) - { - for rule in set.seq_rules().iter().filter_map(|rule| rule.ok()) { - for rec in rule.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - SequenceContext::Format2(table) => { - for set in table - .class_seq_rule_sets() - .iter() - .filter_map(|set| set.transpose().ok().flatten()) - { - for rule in - set.class_seq_rules().iter().filter_map(|rule| rule.ok()) - { - for rec in rule.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - SequenceContext::Format3(table) => { - for rec in table.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - } - SubstitutionSubtables::ChainContextual(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - match table { - ChainedSequenceContext::Format1(table) => { - for set in table - .chained_seq_rule_sets() - .iter() - .filter_map(|set| set.transpose().ok().flatten()) - { - for rule in - set.chained_seq_rules().iter().filter_map(|rule| rule.ok()) - { - for rec in rule.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - ChainedSequenceContext::Format2(table) => { - for set in table - .chained_class_seq_rule_sets() - .iter() - .filter_map(|set| set.transpose().ok().flatten()) - { - for rule in set - .chained_class_seq_rules() - .iter() - .filter_map(|rule| rule.ok()) - { - for rec in rule.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - ChainedSequenceContext::Format3(table) => { - for rec in table.seq_lookup_records() { - self.process_lookup(rec.lookup_list_index())?; - } - } - } - } - } - SubstitutionSubtables::Reverse(tables) => { - for table in tables.iter().filter_map(|table| table.ok()) { - for gid in table.substitute_glyph_ids() { - self.capture_glyph(gid.get().to_u32()); - } - } - } - } - Ok(()) - } - - /// Finishes processing for this set of GSUB lookups and - /// returns the range of touched glyphs. - fn finish(self) -> Option> { - if self.min_gid > self.max_gid { - // We didn't touch any glyphs - return None; - } - let range = self.min_gid..self.max_gid + 1; - if self.need_blue_substs { - // We didn't find any substitutions for our blue strings so - // we ignore the style. Clear the GSUB marker for any touched - // glyphs - for glyph in &mut self.glyph_styles[range] { - glyph.clear_from_gsub(); - } - None - } else { - Some(range) - } - } - - /// Checks the given coverage table for any characters in the blue - /// strings associated with our current style. - fn check_blue_coverage(&mut self, coverage: Result, ReadError>) { - let Ok(coverage) = coverage else { - return; - }; - for (blue_str, _) in self.style.script.blues { - if blue_str - .chars() - .filter_map(|ch| self.charmap.map(ch)) - .filter_map(|gid| coverage.get(gid)) - .next() - .is_some() - { - // Condition satisfied, so don't check any further subtables - self.need_blue_substs = false; - return; - } - } - } - - fn capture_glyph(&mut self, gid: u32) { - let gid = gid as usize; - if let Some(style) = self.glyph_styles.get_mut(gid) { - style.set_from_gsub_output(); - self.min_gid = gid.min(self.min_gid); - self.max_gid = gid.max(self.max_gid); - } - } -} - -#[derive(PartialEq, Debug)] -enum ProcessLookupError { - ExceededMaxDepth, - CycleDetected, -} - -#[cfg(test)] -mod tests { - use super::{super::style, *}; - use raw::{test_helpers::BeBuffer, FontData, FontRead}; - - #[test] - fn small_caps_subst() { - let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::BestEffort); - let style = &style::STYLE_CLASSES[style::StyleClass::LATN_C2SC]; - let mut cluster_shaper = shaper.cluster_shaper(style); - let mut cluster = ShapedCluster::new(); - cluster_shaper.shape("H", &mut cluster); - assert_eq!(cluster.len(), 1); - // from ttx, gid 8 is small caps "H" - assert_eq!(cluster[0].id, GlyphId::new(8)); - } - - #[test] - fn small_caps_nominal() { - let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let style = &style::STYLE_CLASSES[style::StyleClass::LATN_C2SC]; - let mut cluster_shaper = shaper.cluster_shaper(style); - let mut cluster = ShapedCluster::new(); - cluster_shaper.shape("H", &mut cluster); - assert_eq!(cluster.len(), 1); - // from ttx, gid 1 is "H" - assert_eq!(cluster[0].id, GlyphId::new(1)); - } - - #[test] - fn exceed_max_depth() { - let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::BestEffort); - let style = &style::STYLE_CLASSES[style::StyleClass::LATN]; - // Build a lookup chain exceeding our max depth - let mut bad_lookup_builder = BadLookupBuilder::default(); - for i in 0..MAX_NESTING_DEPTH { - // each lookup calls the next - bad_lookup_builder.lookups.push(i as u16 + 1); - } - let lookup_list_buf = bad_lookup_builder.build(); - let lookup_list = SubstitutionLookupList::read(FontData::new(&lookup_list_buf)).unwrap(); - let mut gsub_handler = GsubHandler::new(&shaper.charmap, &lookup_list, style, &mut []); - assert_eq!( - gsub_handler.process_lookup(0), - Err(ProcessLookupError::ExceededMaxDepth) - ); - } - - #[test] - fn detect_cycles() { - let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::BestEffort); - let style = &style::STYLE_CLASSES[style::StyleClass::LATN]; - // Build a lookup chain that cycles; 0 calls 1 which calls 0 - let mut bad_lookup_builder = BadLookupBuilder::default(); - bad_lookup_builder.lookups.push(1); - bad_lookup_builder.lookups.push(0); - let lookup_list_buf = bad_lookup_builder.build(); - let lookup_list = SubstitutionLookupList::read(FontData::new(&lookup_list_buf)).unwrap(); - let mut gsub_handler = GsubHandler::new(&shaper.charmap, &lookup_list, style, &mut []); - assert_eq!( - gsub_handler.process_lookup(0), - Err(ProcessLookupError::CycleDetected) - ); - } - - #[derive(Default)] - struct BadLookupBuilder { - /// Just a list of nested lookup indices for each generated lookup - lookups: Vec, - } - - impl BadLookupBuilder { - fn build(&self) -> Vec { - // Full byte size of a contextual format 3 lookup with one - // subtable and one nested lookup - const CONTEXT3_FULL_SIZE: usize = 18; - let mut buf = BeBuffer::default(); - // LookupList table - // count - buf = buf.push(self.lookups.len() as u16); - // offsets for each lookup - let base_offset = 2 + 2 * self.lookups.len(); - for i in 0..self.lookups.len() { - buf = buf.push((base_offset + i * CONTEXT3_FULL_SIZE) as u16); - } - // now the actual lookups - for nested_ix in &self.lookups { - // lookup type: GSUB contextual substitution - buf = buf.push(5u16); - // lookup flag - buf = buf.push(0u16); - // subtable count - buf = buf.push(1u16); - // offset to single subtable (always 8 bytes from start of lookup) - buf = buf.push(8u16); - // start of subtable, format == 3 - buf = buf.push(3u16); - // number of glyphs in sequence - buf = buf.push(0u16); - // sequence lookup count - buf = buf.push(1u16); - // (no coverage offsets) - // sequence lookup (sequence index, lookup index) - buf = buf.push(0u16).push(*nested_ix); - } - buf.to_vec() - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,558 +0,0 @@ -//! Styles, scripts and glyph style mapping. - -use super::metrics::BlueZones; -use super::shape::ShaperCoverageKind; -use alloc::vec::Vec; -use raw::types::{GlyphId, Tag}; - -/// Defines the script and style associated with a single glyph. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -#[repr(transparent)] -pub(super) struct GlyphStyle(pub(super) u16); - -impl GlyphStyle { - // The following flags roughly correspond to those defined in FreeType - // here: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afglobal.h#L76 - // but with different values because we intend to store "meta style" - // information differently. - const STYLE_INDEX_MASK: u16 = 0xFF; - const UNASSIGNED: u16 = Self::STYLE_INDEX_MASK; - // A non-base character, perhaps more commonly referred to as a "mark" - const NON_BASE: u16 = 0x100; - const DIGIT: u16 = 0x200; - // Used as intermediate state to mark when a glyph appears as GSUB output - // for a given script - const FROM_GSUB_OUTPUT: u16 = 0x8000; - - pub const fn is_unassigned(self) -> bool { - self.0 & Self::STYLE_INDEX_MASK == Self::UNASSIGNED - } - - pub const fn is_non_base(self) -> bool { - self.0 & Self::NON_BASE != 0 - } - - pub const fn is_digit(self) -> bool { - self.0 & Self::DIGIT != 0 - } - - pub fn style_class(self) -> Option<&'static StyleClass> { - StyleClass::from_index(self.style_index()?) - } - - pub fn style_index(self) -> Option { - let ix = self.0 & Self::STYLE_INDEX_MASK; - if ix != Self::UNASSIGNED { - Some(ix) - } else { - None - } - } - - fn maybe_assign(&mut self, other: Self) { - // FreeType walks the style array in order so earlier styles - // have precedence. Since we walk the cmap and binary search - // on the full range mapping, our styles are mapped in a - // different order. This check allows us to replace a currently - // mapped style if the new style index is lower which matches - // FreeType's behavior. - // - // Note that we keep the extra bits because FreeType allows - // setting the NON_BASE bit to an already mapped style. - if other.0 & Self::STYLE_INDEX_MASK <= self.0 & Self::STYLE_INDEX_MASK { - self.0 = (self.0 & !Self::STYLE_INDEX_MASK) | other.0; - } - } - - pub(super) fn set_from_gsub_output(&mut self) { - self.0 |= Self::FROM_GSUB_OUTPUT - } - - pub(super) fn clear_from_gsub(&mut self) { - self.0 &= !Self::FROM_GSUB_OUTPUT; - } - - /// Assign a style if we've been marked as GSUB output _and_ the - /// we don't currently have an assigned style. - /// - /// This also clears the GSUB output bit. - /// - /// Returns `true` if this style was applied. - pub(super) fn maybe_assign_gsub_output_style(&mut self, style: &StyleClass) -> bool { - let style_ix = style.index as u16; - if self.0 & Self::FROM_GSUB_OUTPUT != 0 && self.is_unassigned() { - self.clear_from_gsub(); - self.0 = (self.0 & !Self::STYLE_INDEX_MASK) | style_ix; - true - } else { - false - } - } -} - -impl Default for GlyphStyle { - fn default() -> Self { - Self(Self::UNASSIGNED) - } -} - -/// Sentinel for unused styles in [`GlyphStyleMap::metrics_map`]. -const UNMAPPED_STYLE: u8 = 0xFF; - -/// Maps glyph identifiers to glyph styles. -/// -/// Also keeps track of the styles that are actually used so we can allocate -/// an appropriately sized metrics array. -#[derive(Debug)] -pub(crate) struct GlyphStyleMap { - /// List of styles, indexed by glyph id. - styles: Vec, - /// Maps an actual style class index into a compacted index for the - /// metrics table. - /// - /// Uses `0xFF` to signify unused styles. - metrics_map: [u8; MAX_STYLES], - /// Number of metrics styles in use. - metrics_count: u8, -} - -impl GlyphStyleMap { - /// Computes a new glyph style map for the given glyph count and character - /// map. - /// - /// Roughly based on - pub fn new(glyph_count: u32, shaper: &Shaper) -> Self { - let mut map = Self { - styles: vec![GlyphStyle::default(); glyph_count as usize], - metrics_map: [UNMAPPED_STYLE; MAX_STYLES], - metrics_count: 0, - }; - // Step 1: compute styles for glyphs covered by OpenType features - // See - for style in super::style::STYLE_CLASSES { - if style.feature.is_some() - && shaper.compute_coverage(style, ShaperCoverageKind::Script, &mut map.styles) - { - map.use_style(style.index); - } - } - // Step 2: compute styles for glyphs contained in the cmap - // cmap entries are sorted so we keep track of the most recent range to - // avoid a binary search per character - let mut last_range: Option<(usize, StyleRange)> = None; - for (ch, gid) in shaper.charmap().mappings() { - let Some(style) = map.styles.get_mut(gid.to_u32() as usize) else { - continue; - }; - // Charmaps enumerate in order so we're likely to encounter at least - // a few codepoints in the same range. - if let Some(last) = last_range { - if last.1.contains(ch) { - style.maybe_assign(last.1.style); - continue; - } - } - let ix = match STYLE_RANGES.binary_search_by(|x| x.first.cmp(&ch)) { - Ok(i) => i, - Err(i) => i.saturating_sub(1), - }; - let Some(range) = STYLE_RANGES.get(ix).copied() else { - continue; - }; - if range.contains(ch) { - style.maybe_assign(range.style); - if let Some(style_ix) = range.style.style_index() { - map.use_style(style_ix as usize); - } - last_range = Some((ix, range)); - } - } - // Step 3a: compute script based coverage - // See - for style in super::style::STYLE_CLASSES { - if style.feature.is_none() - && shaper.compute_coverage(style, ShaperCoverageKind::Script, &mut map.styles) - { - map.use_style(style.index); - } - } - // Step 3b: compute coverage for "default" script which is always set - // to Latin in FreeType - // See - let default_style = &STYLE_CLASSES[StyleClass::LATN]; - if shaper.compute_coverage(default_style, ShaperCoverageKind::Default, &mut map.styles) { - map.use_style(default_style.index); - } - // Step 4: Assign a default to all remaining glyphs - // For some reason, FreeType uses Hani as a default fallback style so - // let's do the same. - // - let mut need_hani = false; - for style in map.styles.iter_mut() { - if style.is_unassigned() { - style.0 &= !GlyphStyle::STYLE_INDEX_MASK; - style.0 |= StyleClass::HANI as u16; - need_hani = true; - } - } - if need_hani { - map.use_style(StyleClass::HANI); - } - // Step 5: Mark ASCII digits - // - for digit_char in '0'..='9' { - if let Some(style) = shaper - .charmap() - .map(digit_char) - .and_then(|gid| map.styles.get_mut(gid.to_u32() as usize)) - { - style.0 |= GlyphStyle::DIGIT; - } - } - map - } - - pub fn style(&self, glyph_id: GlyphId) -> Option { - self.styles.get(glyph_id.to_u32() as usize).copied() - } - - /// Returns a compacted metrics index for the given glyph style. - pub fn metrics_index(&self, style: GlyphStyle) -> Option { - let ix = style.style_index()? as usize; - let metrics_ix = *self.metrics_map.get(ix)? as usize; - if metrics_ix != UNMAPPED_STYLE as usize { - Some(metrics_ix) - } else { - None - } - } - - /// Returns the required size of the compacted metrics array. - pub fn metrics_count(&self) -> usize { - self.metrics_count as usize - } - - /// Returns an ordered iterator yielding each style class referenced by - /// this map. - pub fn metrics_styles(&self) -> impl Iterator + '_ { - // Need to build a reverse map so that these are properly ordered - let mut reverse_map = [UNMAPPED_STYLE; MAX_STYLES]; - for (ix, &entry) in self.metrics_map.iter().enumerate() { - if entry != UNMAPPED_STYLE { - reverse_map[entry as usize] = ix as u8; - } - } - reverse_map - .into_iter() - .enumerate() - .filter_map(move |(mapped, style_ix)| { - if mapped == UNMAPPED_STYLE as usize { - None - } else { - STYLE_CLASSES.get(style_ix as usize) - } - }) - } - - fn use_style(&mut self, style_ix: usize) { - let mapped = &mut self.metrics_map[style_ix]; - if *mapped == UNMAPPED_STYLE { - // This the first time we've seen this style so record - // it in the metrics map - *mapped = self.metrics_count; - self.metrics_count += 1; - } - } -} - -impl Default for GlyphStyleMap { - fn default() -> Self { - Self { - styles: Default::default(), - metrics_map: [UNMAPPED_STYLE; MAX_STYLES], - metrics_count: 0, - } - } -} - -/// Determines which algorithms the autohinter will use while generating -/// metrics and processing a glyph outline. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub(crate) enum ScriptGroup { - /// All scripts that are not CJK or Indic. - /// - /// FreeType calls this Latin. - #[default] - Default, - Cjk, - Indic, -} - -/// Defines the basic properties for each script supported by the -/// autohinter. -#[derive(Clone, Debug)] -pub(crate) struct ScriptClass { - #[allow(unused)] - pub name: &'static str, - /// Group that defines how glyphs belonging to this script are hinted. - pub group: ScriptGroup, - /// Unicode tag for the script. - #[allow(unused)] - pub tag: Tag, - /// True if outline edges are processed top to bottom. - pub hint_top_to_bottom: bool, - /// Characters used to define standard width and height of stems. - pub std_chars: &'static str, - /// "Blue" characters used to define alignment zones. - pub blues: &'static [(&'static str, BlueZones)], -} - -/// Defines the basic properties for each style supported by the -/// autohinter. -/// -/// There's mostly a 1:1 correspondence between styles and scripts except -/// in the cases where style coverage is determined by OpenType feature -/// coverage. -#[derive(Clone, Debug)] -pub(crate) struct StyleClass { - #[allow(unused)] - pub name: &'static str, - /// Index of self in the STYLE_CLASSES array. - pub index: usize, - /// Associated Unicode script. - pub script: &'static ScriptClass, - /// OpenType feature tag for styles that derive coverage from layout - /// tables. - #[allow(unused)] - pub feature: Option, -} - -impl StyleClass { - pub(crate) fn from_index(index: u16) -> Option<&'static StyleClass> { - STYLE_CLASSES.get(index as usize) - } -} - -/// Associates a basic glyph style with a range of codepoints. -#[derive(Copy, Clone, Debug)] -pub(super) struct StyleRange { - pub first: u32, - pub last: u32, - pub style: GlyphStyle, -} - -impl StyleRange { - pub fn contains(&self, ch: u32) -> bool { - (self.first..=self.last).contains(&ch) - } -} - -// The following are helpers for generated code. -const fn base_range(first: u32, last: u32, style_index: u16) -> StyleRange { - StyleRange { - first, - last, - style: GlyphStyle(style_index), - } -} - -const fn non_base_range(first: u32, last: u32, style_index: u16) -> StyleRange { - StyleRange { - first, - last, - style: GlyphStyle(style_index | GlyphStyle::NON_BASE), - } -} - -const MAX_STYLES: usize = STYLE_CLASSES.len(); - -use super::shape::Shaper; - -include!("../../../generated/generated_autohint_styles.rs"); - -#[cfg(test)] -mod tests { - use super::{super::shape::ShaperMode, *}; - use crate::{raw::TableProvider, FontRef, MetadataProvider}; - - /// Ensure that style mapping accurately applies the DIGIT bit to - /// ASCII digit glyphs. - #[test] - fn capture_digit_styles() { - let font = FontRef::new(font_test_data::AHEM).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let num_glyphs = font.maxp().unwrap().num_glyphs() as u32; - let style_map = GlyphStyleMap::new(num_glyphs, &shaper); - let charmap = font.charmap(); - let mut digit_count = 0; - for (ch, gid) in charmap.mappings() { - let style = style_map.style(gid).unwrap(); - let is_char_digit = char::from_u32(ch).unwrap().is_ascii_digit(); - assert_eq!(style.is_digit(), is_char_digit); - digit_count += is_char_digit as u32; - } - // This font has all 10 ASCII digits - assert_eq!(digit_count, 10); - } - - #[test] - fn glyph_styles() { - // generated by printf debugging in FreeType - // (gid, Option<(script_name, is_non_base_char)>) - // where "is_non_base_char" more common means "is_mark" - let expected = &[ - (0, Some(("CJKV ideographs", false))), - (1, Some(("Latin", true))), - (2, Some(("Armenian", true))), - (3, Some(("Hebrew", true))), - (4, Some(("Arabic", false))), - (5, Some(("Arabic", false))), - (6, Some(("Arabic", true))), - (7, Some(("Devanagari", true))), - (8, Some(("Devanagari", false))), - (9, Some(("Bengali", true))), - (10, Some(("Bengali", false))), - (11, Some(("Gurmukhi", true))), - (12, Some(("Gurmukhi", false))), - (13, Some(("Gujarati", true))), - (14, Some(("Gujarati", true))), - (15, Some(("Oriya", true))), - (16, Some(("Oriya", false))), - (17, Some(("Tamil", true))), - (18, Some(("Tamil", false))), - (19, Some(("Telugu", true))), - (20, Some(("Telugu", false))), - (21, Some(("Kannada", true))), - (22, Some(("Kannada", false))), - (23, Some(("Malayalam", true))), - (24, Some(("Malayalam", false))), - (25, Some(("Sinhala", true))), - (26, Some(("Sinhala", false))), - (27, Some(("Thai", true))), - (28, Some(("Thai", false))), - (29, Some(("Lao", true))), - (30, Some(("Lao", false))), - (31, Some(("Tibetan", true))), - (32, Some(("Tibetan", false))), - (33, Some(("Myanmar", true))), - (34, Some(("Ethiopic", true))), - (35, Some(("Buhid", true))), - (36, Some(("Buhid", false))), - (37, Some(("Khmer", true))), - (38, Some(("Khmer", false))), - (39, Some(("Mongolian", true))), - (40, Some(("Canadian Syllabics", false))), - (41, Some(("Limbu", true))), - (42, Some(("Limbu", false))), - (43, Some(("Khmer Symbols", false))), - (44, Some(("Sundanese", true))), - (45, Some(("Ol Chiki", false))), - (46, Some(("Georgian (Mkhedruli)", false))), - (47, Some(("Sundanese", false))), - (48, Some(("Latin Superscript Fallback", false))), - (49, Some(("Latin", true))), - (50, Some(("Greek", true))), - (51, Some(("Greek", false))), - (52, Some(("Latin Subscript Fallback", false))), - (53, Some(("Coptic", true))), - (54, Some(("Coptic", false))), - (55, Some(("Georgian (Khutsuri)", false))), - (56, Some(("Tifinagh", false))), - (57, Some(("Ethiopic", false))), - (58, Some(("Cyrillic", true))), - (59, Some(("CJKV ideographs", true))), - (60, Some(("CJKV ideographs", false))), - (61, Some(("Lisu", false))), - (62, Some(("Vai", false))), - (63, Some(("Cyrillic", true))), - (64, Some(("Bamum", true))), - (65, Some(("Syloti Nagri", true))), - (66, Some(("Syloti Nagri", false))), - (67, Some(("Saurashtra", true))), - (68, Some(("Saurashtra", false))), - (69, Some(("Kayah Li", true))), - (70, Some(("Kayah Li", false))), - (71, Some(("Myanmar", false))), - (72, Some(("Tai Viet", true))), - (73, Some(("Tai Viet", false))), - (74, Some(("Cherokee", false))), - (75, Some(("Armenian", false))), - (76, Some(("Hebrew", false))), - (77, Some(("Arabic", false))), - (78, Some(("Carian", false))), - (79, Some(("Gothic", false))), - (80, Some(("Deseret", false))), - (81, Some(("Shavian", false))), - (82, Some(("Osmanya", false))), - (83, Some(("Osage", false))), - (84, Some(("Cypriot", false))), - (85, Some(("Avestan", true))), - (86, Some(("Avestan", true))), - (87, Some(("Old Turkic", false))), - (88, Some(("Hanifi Rohingya", false))), - (89, Some(("Chakma", true))), - (90, Some(("Chakma", false))), - (91, Some(("Mongolian", false))), - (92, Some(("CJKV ideographs", false))), - (93, Some(("Medefaidrin", false))), - (94, Some(("Glagolitic", true))), - (95, Some(("Glagolitic", true))), - (96, Some(("Adlam", true))), - (97, Some(("Adlam", false))), - ]; - check_styles(font_test_data::AUTOHINT_CMAP, ShaperMode::Nominal, expected); - } - - #[test] - fn shaped_glyph_styles() { - // generated by printf debugging in FreeType - // (gid, Option<(script_name, is_non_base_char)>) - // where "is_non_base_char" more common means "is_mark" - let expected = &[ - (0, Some(("CJKV ideographs", false))), - (1, Some(("Latin", false))), - (2, Some(("Latin", false))), - (3, Some(("Latin", false))), - (4, Some(("Latin", false))), - // Note: ligatures starting with 'f' are assigned the Cyrillic - // script which matches FreeType - (5, Some(("Cyrillic", false))), - (6, Some(("Cyrillic", false))), - (7, Some(("Cyrillic", false))), - // Capture the Latin c2sc feature - (8, Some(("Latin small capitals from capitals", false))), - ]; - check_styles( - font_test_data::NOTOSERIF_AUTOHINT_SHAPING, - ShaperMode::BestEffort, - expected, - ); - } - - fn check_styles(font_data: &[u8], mode: ShaperMode, expected: &[(u32, Option<(&str, bool)>)]) { - let font = FontRef::new(font_data).unwrap(); - let shaper = Shaper::new(&font, mode); - let num_glyphs = font.maxp().unwrap().num_glyphs() as u32; - let style_map = GlyphStyleMap::new(num_glyphs, &shaper); - let results = style_map - .styles - .iter() - .enumerate() - .map(|(gid, style)| { - ( - gid as u32, - style - .style_class() - .map(|style_class| (style_class.name, style.is_non_base())), - ) - }) - .collect::>(); - for (i, result) in results.iter().enumerate() { - assert_eq!(result, &expected[i]); - } - // Ensure each style has a remapped metrics index - for style in &style_map.styles { - style_map.metrics_index(*style).unwrap(); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,823 +0,0 @@ -//! Edge detection. -//! -//! Edges are sets of segments that all lie within a threshold based on -//! stem widths. -//! -//! Here we compute edges from the segment list, assign properties (round, -//! serif, links) and then associate them with blue zones. - -use super::{ - super::{ - metrics::{fixed_div, fixed_mul, Scale, ScaledAxisMetrics, ScaledBlue, UnscaledBlue}, - outline::Direction, - style::ScriptGroup, - }, - Axis, Edge, Segment, -}; - -/// Links segments to edges, using feature analysis for selection. -/// -/// See -pub(crate) fn compute_edges( - axis: &mut Axis, - metrics: &ScaledAxisMetrics, - top_to_bottom_hinting: bool, - y_scale: i32, - group: ScriptGroup, -) { - axis.edges.clear(); - let scale = metrics.scale; - // This is always passed as 0 in functions that take hinting direction - // in CJK - // See - let top_to_bottom_hinting = if axis.dim == Axis::HORIZONTAL || group != ScriptGroup::Default { - false - } else { - top_to_bottom_hinting - }; - // Ignore horizontal segments less than 1 pixel in length - let segment_length_threshold = if axis.dim == Axis::HORIZONTAL { - fixed_div(64, y_scale) - } else { - 0 - }; - // Also ignore segments with a width delta larger than 0.5 pixels - let segment_width_threshold = fixed_div(32, scale); - // Ensure that edge distance threshold is less than or equal to - // 0.25 pixels - let initial_threshold = metrics.width_metrics.edge_distance_threshold; - const EDGE_DISTANCE_THRESHOLD_MAX: i32 = 64 / 4; - let edge_distance_threshold = if group == ScriptGroup::Default { - fixed_div( - fixed_mul(initial_threshold, scale).min(EDGE_DISTANCE_THRESHOLD_MAX), - scale, - ) - } else { - // CJK uses a slightly different computation here - // See - let threshold = fixed_mul(initial_threshold, scale); - if threshold > EDGE_DISTANCE_THRESHOLD_MAX { - fixed_div(EDGE_DISTANCE_THRESHOLD_MAX, scale) - } else { - initial_threshold - } - }; - // Now build the sorted table of edges by looping over all segments - // to find a matching edge, adding a new one if not found. - // We can't iterate segments because we make mutable calls on `axis` - // below which causes overlapping borrows - for segment_ix in 0..axis.segments.len() { - let segment = &axis.segments[segment_ix]; - if group == ScriptGroup::Default { - // Ignore segments that are too short, too wide or direction-less - if (segment.height as i32) < segment_length_threshold - || (segment.delta as i32 > segment_width_threshold) - || segment.dir == Direction::None - { - continue; - } - // Ignore serif edges that are smaller than 1.5 pixels - if segment.serif_ix.is_some() - && (2 * segment.height as i32) < (3 * segment_length_threshold) - { - continue; - } - } - // Look for a corresponding edge for this segment - let mut best_dist = i32::MAX; - let mut best_edge_ix = None; - for edge_ix in 0..axis.edges.len() { - let edge = &axis.edges[edge_ix]; - let dist = (segment.pos as i32 - edge.fpos as i32).abs(); - if dist < edge_distance_threshold && edge.dir == segment.dir && dist < best_dist { - if group == ScriptGroup::Default { - best_edge_ix = Some(edge_ix); - break; - } - // For CJK, we add some additional checks - // See - if let Some(link) = segment.link(&axis.segments).copied() { - // Check whether all linked segments of the candidate edge - // can make a single edge - let first_ix = edge.first_ix as usize; - let mut seg1 = &axis.segments[first_ix]; - let mut dist2 = 0; - loop { - if let Some(link1) = seg1.link(&axis.segments).copied() { - dist2 = (link.pos as i32 - link1.pos as i32).abs(); - if dist2 >= edge_distance_threshold { - break; - } - } - if seg1.edge_next_ix == Some(first_ix as u16) { - break; - } - if let Some(next) = seg1.next_in_edge(&axis.segments) { - seg1 = next; - } else { - break; - } - } - if dist2 >= edge_distance_threshold { - continue; - } - } - best_dist = dist; - best_edge_ix = Some(edge_ix); - } - } - if let Some(edge_ix) = best_edge_ix { - axis.append_segment_to_edge(segment_ix, edge_ix); - } else { - // We couldn't find an edge, so add a new one for this segment - let opos = fixed_mul(segment.pos as i32, scale); - let edge = Edge { - fpos: segment.pos, - opos, - pos: opos, - dir: segment.dir, - first_ix: segment_ix as u16, - last_ix: segment_ix as u16, - ..Default::default() - }; - axis.insert_edge(edge, top_to_bottom_hinting); - axis.segments[segment_ix].edge_next_ix = Some(segment_ix as u16); - } - } - if group == ScriptGroup::Default { - // Loop again to find single point segments without a direction and - // associate them with an existing edge if possible - for segment_ix in 0..axis.segments.len() { - let segment = &axis.segments[segment_ix]; - if segment.dir != Direction::None { - continue; - } - // Try to find an edge that coincides with this segment within the - // threshold - if let Some(edge_ix) = axis - .edges - .iter() - .enumerate() - .filter_map(|(ix, edge)| { - ((segment.pos as i32 - edge.fpos as i32).abs() < edge_distance_threshold) - .then_some(ix) - }) - .next() - { - // We found an edge, link everything up - axis.append_segment_to_edge(segment_ix, edge_ix); - } - } - } - link_segments_to_edges(axis); - compute_edge_properties(axis); -} - -/// Edges get reordered as they're built so we need to assign edge indices to -/// segments in a second pass. -fn link_segments_to_edges(axis: &mut Axis) { - let segments = axis.segments.as_mut_slice(); - for edge_ix in 0..axis.edges.len() { - let edge = &axis.edges[edge_ix]; - let mut ix = edge.first_ix as usize; - let last_ix = edge.last_ix as usize; - loop { - let segment = &mut segments[ix]; - segment.edge_ix = Some(edge_ix as u16); - if ix == last_ix { - break; - } - ix = segment - .edge_next_ix - .map(|ix| ix as usize) - .unwrap_or(last_ix); - } - } -} - -/// Compute the edge properties based on the series of segments that make -/// up the edge. -/// -/// See -fn compute_edge_properties(axis: &mut Axis) { - let edges = axis.edges.as_mut_slice(); - let segments = axis.segments.as_slice(); - for edge_ix in 0..edges.len() { - let mut roundness = 0; - let mut straightness = 0; - let edge = edges[edge_ix]; - let mut segment_ix = edge.first_ix as usize; - let last_segment_ix = edge.last_ix as usize; - loop { - // This loop can modify the current edge, so make sure we - // reload it here - let edge = edges[edge_ix]; - let segment = &segments[segment_ix]; - let next_segment_ix = segment.edge_next_ix; - // Check roundness - if segment.flags & Segment::ROUND != 0 { - roundness += 1; - } else { - straightness += 1; - } - // Check for serifs - let is_serif = if let Some(serif_ix) = segment.serif_ix { - let serif = &segments[serif_ix as usize]; - serif.edge_ix.is_some() && serif.edge_ix != Some(edge_ix as u16) - } else { - false - }; - // Check for links - if is_serif - || (segment.link_ix.is_some() - && segments[segment.link_ix.unwrap() as usize] - .edge_ix - .is_some()) - { - let (edge2_ix, segment2_ix) = if is_serif { - (edge.serif_ix, segment.serif_ix) - } else { - (edge.link_ix, segment.link_ix) - }; - let edge2_ix = if let (Some(edge2_ix), Some(segment2_ix)) = (edge2_ix, segment2_ix) - { - let edge2 = &edges[edge2_ix as usize]; - let edge_delta = (edge.fpos as i32 - edge2.fpos as i32).abs(); - let segment2 = &segments[segment2_ix as usize]; - let segment_delta = (segment.pos as i32 - segment2.pos as i32).abs(); - if segment_delta < edge_delta { - segment2.edge_ix - } else { - Some(edge2_ix) - } - } else if let Some(segment2_ix) = segment2_ix { - segments[segment2_ix as usize].edge_ix - } else { - edge2_ix - }; - if is_serif { - edges[edge_ix].serif_ix = edge2_ix; - edges[edge2_ix.unwrap() as usize].flags |= Edge::SERIF; - } else { - edges[edge_ix].link_ix = edge2_ix; - } - } - if segment_ix == last_segment_ix { - break; - } - segment_ix = next_segment_ix - .map(|ix| ix as usize) - .unwrap_or(last_segment_ix); - } - let edge = &mut edges[edge_ix]; - edge.flags = Edge::NORMAL; - if roundness > 0 && roundness >= straightness { - edge.flags |= Edge::ROUND; - } - // Drop serifs for linked edges - if edge.serif_ix.is_some() && edge.link_ix.is_some() { - edge.serif_ix = None; - } - } -} - -/// Compute all edges which lie within blue zones. -/// -/// For Latin, this is only done for the vertical axis. -/// -/// See -pub(crate) fn compute_blue_edges( - axis: &mut Axis, - scale: &Scale, - unscaled_blues: &[UnscaledBlue], - blues: &[ScaledBlue], - group: ScriptGroup, -) { - // For the default script group, don't compute blues in the horizontal - // direction - // See - if axis.dim != Axis::VERTICAL && group == ScriptGroup::Default { - return; - } - let axis_scale = if axis.dim == Axis::HORIZONTAL { - scale.x_scale - } else { - scale.y_scale - }; - // Initial threshold - let initial_best_dest = fixed_mul(scale.units_per_em / 40, axis_scale).min(64 / 2); - for edge in &mut axis.edges { - let mut best_blue = None; - let mut best_is_neutral = false; - // Initial threshold as a fraction of em size with a max distance - // of 0.5 pixels - let mut best_dist = initial_best_dest; - for (unscaled_blue, blue) in unscaled_blues.iter().zip(blues) { - // Ignore inactive blue zones - if !blue.is_active { - continue; - } - let is_top = blue.zones.is_top_like(); - let is_neutral = blue.zones.is_neutral(); - let is_major_dir = edge.dir == axis.major_dir; - // Both directions are handled for neutral blues - if is_top ^ is_major_dir || is_neutral { - // Compare to reference position - let (ref_pos, matching_blue) = if group == ScriptGroup::Default { - (unscaled_blue.position, blue.position) - } else { - // For CJK, we take the blue with the smallest delta - // from the edge - // See - if (edge.fpos as i32 - unscaled_blue.position).abs() - > (edge.fpos as i32 - unscaled_blue.overshoot).abs() - { - (unscaled_blue.overshoot, blue.overshoot) - } else { - (unscaled_blue.position, blue.position) - } - }; - let dist = fixed_mul((edge.fpos as i32 - ref_pos).abs(), axis_scale); - if dist < best_dist { - best_dist = dist; - best_blue = Some(matching_blue); - best_is_neutral = is_neutral; - } - if group == ScriptGroup::Default { - // Now compare to overshoot position for the default script - // group - // See - if edge.flags & Edge::ROUND != 0 && dist != 0 && !is_neutral { - let is_under_ref = (edge.fpos as i32) < unscaled_blue.position; - if is_top ^ is_under_ref { - let dist = fixed_mul( - (edge.fpos as i32 - unscaled_blue.overshoot).abs(), - axis_scale, - ); - if dist < best_dist { - best_dist = dist; - best_blue = Some(blue.overshoot); - best_is_neutral = is_neutral; - } - } - } - } - } - } - if let Some(best_blue) = best_blue { - edge.blue_edge = Some(best_blue); - if best_is_neutral { - edge.flags |= Edge::NEUTRAL; - } - } - } -} - -#[cfg(test)] -mod tests { - use super::{ - super::super::{ - metrics::{self, ScaledWidth}, - outline::Outline, - shape::{Shaper, ShaperMode}, - style, - }, - super::segments, - *, - }; - use crate::{attribute::Style, MetadataProvider}; - use raw::{types::GlyphId, FontRef, TableProvider}; - - #[test] - fn edges_default() { - let expected_h_edges = [ - Edge { - fpos: 15, - opos: 15, - pos: 15, - flags: Edge::ROUND, - dir: Direction::Up, - blue_edge: None, - link_ix: Some(3), - serif_ix: None, - scale: 0, - first_ix: 1, - last_ix: 1, - }, - Edge { - fpos: 123, - opos: 126, - pos: 126, - flags: 0, - dir: Direction::Up, - blue_edge: None, - link_ix: Some(2), - serif_ix: None, - scale: 0, - first_ix: 0, - last_ix: 0, - }, - Edge { - fpos: 186, - opos: 190, - pos: 190, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: Some(1), - serif_ix: None, - scale: 0, - first_ix: 4, - last_ix: 4, - }, - Edge { - fpos: 205, - opos: 210, - pos: 210, - flags: Edge::ROUND, - dir: Direction::Down, - blue_edge: None, - link_ix: Some(0), - serif_ix: None, - scale: 0, - first_ix: 3, - last_ix: 3, - }, - ]; - let expected_v_edges = [ - Edge { - fpos: -240, - opos: -246, - pos: -246, - flags: 0, - dir: Direction::Left, - blue_edge: Some(ScaledWidth { - scaled: -246, - fitted: -256, - }), - link_ix: None, - serif_ix: Some(1), - scale: 0, - first_ix: 3, - last_ix: 3, - }, - Edge { - fpos: 481, - opos: 493, - pos: 493, - flags: 0, - dir: Direction::Left, - blue_edge: None, - link_ix: Some(2), - serif_ix: None, - scale: 0, - first_ix: 0, - last_ix: 0, - }, - Edge { - fpos: 592, - opos: 606, - pos: 606, - flags: Edge::ROUND | Edge::SERIF, - dir: Direction::Right, - blue_edge: Some(ScaledWidth { - scaled: 606, - fitted: 576, - }), - link_ix: Some(1), - serif_ix: None, - scale: 0, - first_ix: 2, - last_ix: 2, - }, - Edge { - fpos: 647, - opos: 663, - pos: 663, - flags: 0, - dir: Direction::Right, - blue_edge: None, - link_ix: None, - serif_ix: Some(2), - scale: 0, - first_ix: 1, - last_ix: 1, - }, - ]; - check_edges( - font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, - GlyphId::new(9), - style::StyleClass::HEBR, - &expected_h_edges, - &expected_v_edges, - ); - } - - #[test] - fn edges_cjk() { - let expected_h_edges = [ - Edge { - fpos: 138, - opos: 141, - pos: 141, - flags: 0, - dir: Direction::Up, - blue_edge: None, - link_ix: Some(1), - serif_ix: None, - scale: 0, - first_ix: 8, - last_ix: 8, - }, - Edge { - fpos: 201, - opos: 206, - pos: 206, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: Some(0), - serif_ix: None, - scale: 0, - first_ix: 7, - last_ix: 7, - }, - Edge { - fpos: 458, - opos: 469, - pos: 469, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 2, - last_ix: 2, - }, - Edge { - fpos: 569, - opos: 583, - pos: 583, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 6, - last_ix: 6, - }, - Edge { - fpos: 670, - opos: 686, - pos: 686, - flags: 0, - dir: Direction::Up, - blue_edge: None, - link_ix: Some(6), - serif_ix: None, - scale: 0, - first_ix: 1, - last_ix: 1, - }, - Edge { - fpos: 693, - opos: 710, - pos: 710, - flags: 0, - dir: Direction::Up, - blue_edge: None, - link_ix: None, - serif_ix: Some(7), - scale: 0, - first_ix: 4, - last_ix: 4, - }, - Edge { - fpos: 731, - opos: 749, - pos: 749, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: Some(4), - serif_ix: None, - scale: 0, - first_ix: 0, - last_ix: 0, - }, - Edge { - fpos: 849, - opos: 869, - pos: 869, - flags: 0, - dir: Direction::Up, - blue_edge: None, - link_ix: Some(8), - serif_ix: None, - scale: 0, - first_ix: 5, - last_ix: 5, - }, - Edge { - fpos: 911, - opos: 933, - pos: 933, - flags: 0, - dir: Direction::Down, - blue_edge: None, - link_ix: Some(7), - serif_ix: None, - scale: 0, - first_ix: 3, - last_ix: 3, - }, - ]; - let expected_v_edges = [ - Edge { - fpos: -78, - opos: -80, - pos: -80, - flags: Edge::ROUND, - dir: Direction::Left, - blue_edge: Some(ScaledWidth { - scaled: -80, - fitted: -64, - }), - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 8, - last_ix: 8, - }, - Edge { - fpos: 3, - opos: 3, - pos: 3, - flags: Edge::ROUND, - dir: Direction::Right, - blue_edge: None, - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 4, - last_ix: 4, - }, - Edge { - fpos: 133, - opos: 136, - pos: 136, - flags: Edge::ROUND, - dir: Direction::Left, - blue_edge: None, - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 2, - last_ix: 2, - }, - Edge { - fpos: 547, - opos: 560, - pos: 560, - flags: 0, - dir: Direction::Left, - blue_edge: None, - link_ix: None, - serif_ix: Some(5), - scale: 0, - first_ix: 6, - last_ix: 6, - }, - Edge { - fpos: 576, - opos: 590, - pos: 590, - flags: 0, - dir: Direction::Right, - blue_edge: None, - link_ix: Some(5), - serif_ix: None, - scale: 0, - first_ix: 5, - last_ix: 5, - }, - Edge { - fpos: 576, - opos: 590, - pos: 590, - flags: 0, - dir: Direction::Left, - blue_edge: None, - link_ix: Some(4), - serif_ix: None, - scale: 0, - first_ix: 7, - last_ix: 7, - }, - Edge { - fpos: 729, - opos: 746, - pos: 746, - flags: 0, - dir: Direction::Left, - blue_edge: None, - link_ix: Some(7), - serif_ix: None, - scale: 0, - first_ix: 1, - last_ix: 1, - }, - Edge { - fpos: 758, - opos: 776, - pos: 776, - flags: 0, - dir: Direction::Right, - blue_edge: None, - link_ix: Some(6), - serif_ix: None, - scale: 0, - first_ix: 0, - last_ix: 3, - }, - Edge { - fpos: 788, - opos: 807, - pos: 807, - flags: Edge::ROUND, - dir: Direction::Left, - blue_edge: None, - link_ix: None, - serif_ix: None, - scale: 0, - first_ix: 9, - last_ix: 9, - }, - ]; - check_edges( - font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, - GlyphId::new(9), - style::StyleClass::HANI, - &expected_h_edges, - &expected_v_edges, - ); - } - - fn check_edges( - font_data: &[u8], - glyph_id: GlyphId, - style_class: usize, - expected_h_edges: &[Edge], - expected_v_edges: &[Edge], - ) { - let font = FontRef::new(font_data).unwrap(); - let shaper = Shaper::new(&font, ShaperMode::Nominal); - let class = &style::STYLE_CLASSES[style_class]; - let unscaled_metrics = - metrics::compute_unscaled_style_metrics(&shaper, Default::default(), class); - let scale = metrics::Scale::new( - 16.0, - font.head().unwrap().units_per_em() as i32, - Style::Normal, - Default::default(), - class.script.group, - ); - let scaled_metrics = metrics::scale_style_metrics(&unscaled_metrics, scale); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(glyph_id).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axes = [ - Axis::new(Axis::HORIZONTAL, outline.orientation), - Axis::new(Axis::VERTICAL, outline.orientation), - ]; - for (dim, axis) in axes.iter_mut().enumerate() { - segments::compute_segments(&mut outline, axis, class.script.group); - segments::link_segments( - &outline, - axis, - scaled_metrics.axes[dim].scale, - class.script.group, - unscaled_metrics.axes[dim].max_width(), - ); - compute_edges( - axis, - &scaled_metrics.axes[dim], - class.script.hint_top_to_bottom, - scaled_metrics.axes[1].scale, - class.script.group, - ); - compute_blue_edges( - axis, - &scale, - &unscaled_metrics.axes[dim].blues, - &scaled_metrics.axes[dim].blues, - class.script.group, - ); - } - assert_eq!(axes[Axis::HORIZONTAL].edges.as_slice(), expected_h_edges); - assert_eq!(axes[Axis::VERTICAL].edges.as_slice(), expected_v_edges); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,246 +0,0 @@ -//! Topology analysis of segments and edges. - -mod edges; -mod segments; - -use super::{ - metrics::ScaledWidth, - outline::{Direction, Orientation, Point}, -}; -use crate::collections::SmallVec; - -pub(crate) use edges::{compute_blue_edges, compute_edges}; -pub(crate) use segments::{compute_segments, link_segments}; - -/// Maximum number of segments and edges stored inline. -/// -/// See -const MAX_INLINE_SEGMENTS: usize = 18; -const MAX_INLINE_EDGES: usize = 12; - -/// Either horizontal or vertical. -/// -/// A type alias because it's used as an index. -pub type Dimension = usize; - -/// Segments and edges for one dimension of an outline. -/// -/// See -#[derive(Clone, Default, Debug)] -pub struct Axis { - /// Either horizontal or vertical. - pub dim: Dimension, - /// Depends on dimension and outline orientation. - pub major_dir: Direction, - /// Collection of segments for the axis. - pub segments: SmallVec, - /// Collection of edges for the axis. - pub edges: SmallVec, -} - -impl Axis { - /// X coordinates, i.e. vertical segments and edges. - pub const HORIZONTAL: Dimension = 0; - /// Y coordinates, i.e. horizontal segments and edges. - pub const VERTICAL: Dimension = 1; -} - -impl Axis { - #[cfg(test)] - pub fn new(dim: Dimension, orientation: Option) -> Self { - let mut axis = Self::default(); - axis.reset(dim, orientation); - axis - } - - pub fn reset(&mut self, dim: Dimension, orientation: Option) { - self.dim = dim; - self.major_dir = match (dim, orientation) { - (Self::HORIZONTAL, Some(Orientation::Clockwise)) => Direction::Down, - (Self::VERTICAL, Some(Orientation::Clockwise)) => Direction::Right, - (Self::HORIZONTAL, _) => Direction::Up, - (Self::VERTICAL, _) => Direction::Left, - _ => Direction::None, - }; - self.segments.clear(); - self.edges.clear(); - } -} - -impl Axis { - /// Inserts the given edge into the sorted edge list. - /// - /// See - pub fn insert_edge(&mut self, edge: Edge, top_to_bottom_hinting: bool) { - self.edges.push(edge); - let edges = self.edges.as_mut_slice(); - // If this is the first edge, we're done. - if edges.len() == 1 { - return; - } - // Now move it into place - let mut ix = edges.len() - 1; - while ix > 0 { - let prev_ix = ix - 1; - let prev_fpos = edges[prev_ix].fpos; - if (top_to_bottom_hinting && prev_fpos > edge.fpos) - || (!top_to_bottom_hinting && prev_fpos < edge.fpos) - { - break; - } - // Edges with the same position and minor direction should appear - // before those with the major direction - if prev_fpos == edge.fpos && edge.dir == self.major_dir { - break; - } - let prev_edge = edges[prev_ix]; - edges[ix] = prev_edge; - ix -= 1; - } - edges[ix] = edge; - } - - /// Links the given segment and edge. - pub fn append_segment_to_edge(&mut self, segment_ix: usize, edge_ix: usize) { - let edge = &mut self.edges[edge_ix]; - let first_ix = edge.first_ix; - let last_ix = edge.last_ix; - edge.last_ix = segment_ix as u16; - let segment = &mut self.segments[segment_ix]; - segment.edge_next_ix = Some(first_ix); - self.segments[last_ix as usize].edge_next_ix = Some(segment_ix as u16); - } -} - -/// Sequence of points with a single dominant direction. -/// -/// See -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] -pub(crate) struct Segment { - /// Flags describing the properties of the segment. - pub flags: u8, - /// Dominant direction of the segment. - pub dir: Direction, - /// Position of the segment. - pub pos: i16, - /// Deviation from segment position. - pub delta: i16, - /// Minimum coordinate of the segment. - pub min_coord: i16, - /// Maximum coordinate of the segment. - pub max_coord: i16, - /// Hinted segment height. - pub height: i16, - /// Used during stem matching. - pub score: i32, - /// Used during stem matching. - pub len: i32, - /// Index of best candidate for a stem link. - pub link_ix: Option, - /// Index of best candidate for a serif link. - pub serif_ix: Option, - /// Index of first point in the outline. - pub first_ix: u16, - /// Index of last point in the outline. - pub last_ix: u16, - /// Index of edge that is associated with the segment. - pub edge_ix: Option, - /// Index of next segment in edge's segment list. - pub edge_next_ix: Option, -} - -/// Segment flags. -/// -/// Note: these are the same as edge flags. -/// -/// See -impl Segment { - pub const NORMAL: u8 = 0; - pub const ROUND: u8 = 1; - pub const SERIF: u8 = 2; - pub const DONE: u8 = 4; - pub const NEUTRAL: u8 = 8; -} - -impl Segment { - pub fn first(&self) -> usize { - self.first_ix as usize - } - - pub fn first_point<'a>(&self, points: &'a [Point]) -> &'a Point { - &points[self.first()] - } - - pub fn last(&self) -> usize { - self.last_ix as usize - } - - pub fn last_point<'a>(&self, points: &'a [Point]) -> &'a Point { - &points[self.last()] - } - - pub fn edge<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { - edges.get(self.edge_ix.map(|ix| ix as usize)?) - } - - /// Returns the next segment in this segment's parent edge. - pub fn next_in_edge<'a>(&self, segments: &'a [Segment]) -> Option<&'a Segment> { - segments.get(self.edge_next_ix.map(|ix| ix as usize)?) - } - - pub fn link<'a>(&self, segments: &'a [Segment]) -> Option<&'a Segment> { - segments.get(self.link_ix.map(|ix| ix as usize)?) - } -} - -/// Sequence of segments used for grid-fitting. -/// -/// See -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] -pub(crate) struct Edge { - /// Original, unscaled position in font units. - pub fpos: i16, - /// Original, scaled position. - pub opos: i32, - /// Current position. - pub pos: i32, - /// Edge flags. - pub flags: u8, - /// Edge direction. - pub dir: Direction, - /// Present if this is a blue edge. - pub blue_edge: Option, - /// Index of linked edge. - pub link_ix: Option, - /// Index of primary edge for serif. - pub serif_ix: Option, - /// Used to speed up edge interpolation. - pub scale: i32, - /// Index of first segment in edge. - pub first_ix: u16, - /// Index of last segment in edge. - pub last_ix: u16, -} - -/// Edge flags. -/// -/// Note: these are the same as segment flags. -/// -/// See -impl Edge { - pub const NORMAL: u8 = Segment::NORMAL; - pub const ROUND: u8 = Segment::ROUND; - pub const SERIF: u8 = Segment::SERIF; - pub const DONE: u8 = Segment::DONE; - pub const NEUTRAL: u8 = Segment::NEUTRAL; -} - -impl Edge { - pub fn link<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { - edges.get(self.link_ix.map(|ix| ix as usize)?) - } - - pub fn serif<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { - edges.get(self.serif_ix.map(|ix| ix as usize)?) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1071 +0,0 @@ -//! Segment computation and linking. -//! -//! A segment is a series of at least two consecutive points that are -//! appropriately aligned along a coordinate axis. -//! -//! The linking stage associates pairs of segments to form stems and -//! identifies serifs with a post-process pass. - -use super::super::{ - derived_constant, - metrics::fixed_div, - outline::Outline, - style::ScriptGroup, - topo::{Axis, Dimension, Segment}, -}; -use raw::tables::glyf::PointFlags; - -// Bounds for score, position and coordinate values. -// See -const MAX_SCORE: i32 = 32000; -const MIN_SCORE: i32 = -32000; - -/// Computes segments for the Latin writing system. -/// -/// See -pub(crate) fn compute_segments( - outline: &mut Outline, - axis: &mut Axis, - _group: ScriptGroup, -) -> bool { - assign_point_uvs(outline, axis.dim); - if !build_segments(outline, axis) { - return false; - } - adjust_segment_heights(outline, axis); - // This is never actually executed due to a bug in FreeType - // See point 2 at - // if group != ScriptGroup::Default { - // _detect_round_segments_cjk(outline, axis); - // } - true -} - -/// Link segments to form stems and serifs. -/// -/// If `max_width` is provided, use it to refine the scoring function. -/// -/// See -pub(crate) fn link_segments( - outline: &Outline, - axis: &mut Axis, - scale: i32, - group: ScriptGroup, - max_width: Option, -) { - if group == ScriptGroup::Default { - link_segments_default(outline, axis, max_width); - } else { - link_segments_cjk(outline, axis, scale) - } -} - -/// Link segments to form stems and serifs. -/// -/// If `max_width` is provided, use it to refine the scoring function. -/// -/// See -fn link_segments_default(outline: &Outline, axis: &mut Axis, max_width: Option) { - let max_width = max_width.unwrap_or_default(); - // Heuristic value to set up a minimum for overlapping - let len_threshold = derived_constant(outline.units_per_em, 8).max(1); - // Heuristic value to weight lengths - let len_score = derived_constant(outline.units_per_em, 6000); - // Heuristic value to weight distances (not a latin constant since - // it works on multiples of stem width) - let dist_score = 3000; - // Compare each segment to the others.. O(n^2) - let segments = axis.segments.as_mut_slice(); - for ix1 in 0..segments.len() { - let seg1 = segments[ix1]; - if seg1.dir != axis.major_dir { - continue; - } - let pos1 = seg1.pos as i32; - // Search for stems having opposite directions with seg1 to the - // "left" of seg2 - for ix2 in 0..segments.len() { - let seg1 = segments[ix1]; - let seg2 = segments[ix2]; - let pos2 = seg2.pos as i32; - if seg1.dir.is_opposite(seg2.dir) && pos2 > pos1 { - // Compute distance between the segments - // Note: the min/max functions chosen here are intentional - let min = seg1.min_coord.max(seg2.min_coord) as i32; - let max = seg1.max_coord.min(seg2.max_coord) as i32; - // Compute maximum coordinate difference or how much they - // overlap - let len = max - min; - if len >= len_threshold { - // verbatim from FreeType: - // "The score is the sum of two demerits indicating the - // `badness' of a fit, measured along the segments' main axis - // and orthogonal to it, respectively. - // - // - The less overlapping along the main axis, the worse it - // is, causing a larger demerit. - // - // - The nearer the orthogonal distance to a stem width, the - // better it is, causing a smaller demerit. For simplicity, - // however, we only increase the demerit for values that - // exceed the largest stem width." - // See - let dist = pos2 - pos1; - let dist_demerit = if max_width != 0 { - // Distance demerits are based on multiples of max_width - let delta = (dist << 10) / max_width - (1 << 10); - if delta > 10_000 { - MAX_SCORE - } else if delta > 0 { - delta * delta / dist_score - } else { - 0 - } - } else { - dist - }; - let score = dist_demerit + len_score / len; - if score < seg1.score { - let seg1 = &mut segments[ix1]; - seg1.score = score; - seg1.link_ix = Some(ix2 as u16); - } - if score < seg2.score { - let seg2 = &mut segments[ix2]; - seg2.score = score; - seg2.link_ix = Some(ix1 as u16); - } - } - } - } - } - // Now compute "serif" segments - // See - for ix1 in 0..segments.len() { - let Some(ix2) = segments[ix1].link_ix else { - continue; - }; - let seg2_link = segments[ix2 as usize].link_ix; - if seg2_link != Some(ix1 as u16) { - let seg1 = &mut segments[ix1]; - seg1.link_ix = None; - seg1.serif_ix = seg2_link; - } - } -} - -/// Link segments to form stems and serifs for the CJK script group. -/// -/// See -fn link_segments_cjk(outline: &Outline, axis: &mut Axis, scale: i32) { - // Heuristic value to set up a minimum for overlapping - let len_threshold = derived_constant(outline.units_per_em, 8); - let dist_threshold = fixed_div(64 * 3, scale); - // Compare each segment to the others.. O(n^2) - let segments = axis.segments.as_mut_slice(); - for ix1 in 0..segments.len() { - let seg1 = segments[ix1]; - if seg1.dir != axis.major_dir { - continue; - } - let pos1 = seg1.pos as i32; - // Search for stems having opposite directions with seg1 to the - // "left" of seg2 - for ix2 in 0..segments.len() { - let seg1 = segments[ix1]; - let seg2 = segments[ix2]; - if ix1 == ix2 || !seg1.dir.is_opposite(seg2.dir) { - continue; - } - let pos2 = seg2.pos as i32; - let dist = pos2 - pos1; - if dist < 0 { - continue; - } - // Compute distance between the segments - // Note: the min/max functions chosen here are intentional - let min = seg1.min_coord.max(seg2.min_coord) as i32; - let max = seg1.max_coord.min(seg2.max_coord) as i32; - // Compute maximum coordinate difference or how much they - // overlap - let len = max - min; - if len >= len_threshold { - let check_seg = |seg: &Segment| { - // Some more magic heuristics... - // See - (dist * 8 < seg.score * 9) && (dist * 8 < seg.score * 7 || seg.len < len) - }; - if check_seg(&seg1) { - let seg = &mut segments[ix1]; - seg.score = dist; - seg.len = len; - seg.link_ix = Some(ix2 as _); - } - if check_seg(&seg2) { - let seg = &mut segments[ix2]; - seg.score = dist; - seg.len = len; - seg.link_ix = Some(ix1 as _); - } - } - } - } - // Now compute "serif" segments - // See - for ix1 in 0..segments.len() { - let seg1 = segments[ix1]; - if seg1.score >= dist_threshold { - continue; - } - let Some(link1) = seg1.link(segments).copied() else { - continue; - }; - // Unwrap is fine because we checked for existence above - let link1_ix = seg1.link_ix.unwrap() as usize; - if link1.link_ix != Some(ix1 as u16) || link1.pos <= seg1.pos { - continue; - } - for ix2 in 0..segments.len() { - let seg2 = segments[ix2]; - if seg2.pos > seg1.pos || ix1 == ix2 { - continue; - } - let Some(link2) = seg2.link(segments).copied() else { - continue; - }; - if link2.link_ix != Some(ix2 as u16) || link2.pos < link1.pos { - continue; - } - if seg1.pos == seg2.pos && link1.pos == link2.pos { - continue; - } - if seg2.score <= seg1.score || seg1.score * 4 <= seg2.score { - continue; - } - if seg1.len >= seg2.len * 3 { - // Again, we definitely have a valid link2 - let link2_ix = seg2.link_ix.unwrap() as usize; - for seg in segments.iter_mut() { - let link_ix = seg.link_ix; - if link_ix == Some(ix2 as u16) { - seg.link_ix = None; - seg.serif_ix = Some(link1_ix as u16); - } else if link_ix == Some(link2_ix as u16) { - seg.link_ix = None; - seg.serif_ix = Some(ix1 as u16); - } - } - } else { - segments[ix1].link_ix = None; - segments[link1_ix].link_ix = None; - break; - } - } - } - for ix1 in 0..segments.len() { - let seg1 = segments[ix1]; - let Some(seg2) = seg1.link(segments).copied() else { - continue; - }; - if seg2.link_ix != Some(ix1 as u16) { - segments[ix1].link_ix = None; - if seg2.score < dist_threshold || seg1.score < seg2.score * 4 { - segments[ix1].serif_ix = seg2.link_ix; - } - } - } -} - -/// Set the (u, v) values to font unit coords for each point depending -/// on the axis dimension. -/// -/// See -fn assign_point_uvs(outline: &mut Outline, dim: Dimension) { - if dim == Axis::HORIZONTAL { - for point in &mut outline.points { - point.u = point.fx; - point.v = point.fy; - } - } else { - for point in &mut outline.points { - point.u = point.fy; - point.v = point.fx; - } - } -} - -/// Build the set of segments for each contour. -/// -/// See -fn build_segments(outline: &mut Outline, axis: &mut Axis) -> bool { - let flat_threshold = outline.units_per_em / 14; - axis.segments.clear(); - let major_dir = axis.major_dir.normalize(); - let mut segment_dir = major_dir; - let points = outline.points.as_mut_slice(); - for contour in &outline.contours { - let is_single_point_contour = contour.range().len() == 1; - let mut point_ix = contour.first(); - let mut last_ix = contour.prev(point_ix); - let mut state = State::default(); - let mut prev_state = state; - let mut prev_segment_ix: Option = None; - let mut segment_ix = 0; - // Check if we're starting on an edge and if so, find - // the starting point - if points[point_ix].out_dir.is_same_axis(major_dir) - && points[last_ix].out_dir.is_same_axis(major_dir) - { - last_ix = point_ix; - loop { - point_ix = contour.prev(point_ix); - if !points[point_ix].out_dir.is_same_axis(major_dir) { - point_ix = contour.next(point_ix); - break; - } - if point_ix == last_ix { - break; - } - } - } - last_ix = point_ix; - let mut on_edge = false; - let mut passed = false; - loop { - if on_edge { - // Get min and max position - let point = points[point_ix]; - state.min_pos = state.min_pos.min(point.u); - state.max_pos = state.max_pos.max(point.u); - // Get min and max coordinate and flags - let v = point.v; - if v < state.min_coord { - state.min_coord = v; - state.min_flags = point.flags; - } - if v > state.max_coord { - state.max_coord = v; - state.max_flags = point.flags; - } - // Get min and max coord of on curve points - if point.is_on_curve() { - state.min_on_coord = state.min_on_coord.min(point.v); - state.max_on_coord = state.max_on_coord.max(point.v); - } - if point.out_dir != segment_dir || point_ix == last_ix { - if prev_segment_ix.is_none() - || axis.segments[segment_ix].first_ix - != axis.segments[prev_segment_ix.unwrap()].last_ix - { - // The points are different signifying that we are - // leaving an edge, so create a new segment - let segment = &mut axis.segments[segment_ix]; - segment.last_ix = point_ix as u16; - state.apply_to_segment(segment, flat_threshold); - prev_segment_ix = Some(segment_ix); - prev_state = state; - } else { - // The points are the same, so merge the segments - let prev_segment = &mut axis.segments[prev_segment_ix.unwrap()]; - if prev_segment.last_point(points).in_dir == point.in_dir { - // We have identical directions; unify segments - // and update constraints - state.min_pos = prev_state.min_pos.min(state.min_pos); - state.max_pos = prev_state.max_pos.max(state.max_pos); - if prev_state.min_coord < state.min_coord { - state.min_coord = prev_state.min_coord; - state.min_flags = prev_state.min_flags; - } - if prev_state.max_coord > state.max_coord { - state.max_coord = prev_state.max_coord; - state.max_flags = prev_state.max_flags; - } - state.min_on_coord = prev_state.min_on_coord.min(state.min_on_coord); - state.max_on_coord = prev_state.max_on_coord.max(state.max_on_coord); - prev_segment.last_ix = point_ix as u16; - state.apply_to_segment(prev_segment, flat_threshold); - } else { - // We have different directions; use the - // properties of the longer segment - if (prev_state.max_coord - prev_state.min_coord).abs() - > (state.max_coord - state.min_coord).abs() - { - // Discard current segment - prev_state.min_pos = prev_state.min_pos.min(state.min_pos); - prev_state.max_pos = prev_state.max_pos.max(state.max_pos); - prev_segment.last_ix = point_ix as u16; - prev_segment.pos = - ((prev_state.min_pos + prev_state.max_pos) >> 1) as i16; - prev_segment.delta = - ((prev_state.max_pos - prev_state.min_pos) >> 1) as i16; - } else { - // Discard previous segment - state.min_pos = state.min_pos.min(prev_state.min_pos); - state.max_pos = state.max_pos.max(prev_state.max_pos); - let mut segment = axis.segments[segment_ix]; - segment.last_ix = point_ix as u16; - state.apply_to_segment(&mut segment, flat_threshold); - axis.segments[prev_segment_ix.unwrap()] = segment; - prev_state = state; - } - } - axis.segments.pop(); - } - on_edge = false; - } - } - if point_ix == last_ix { - if passed { - break; - } - passed = true; - } - let point = points[point_ix]; - if !on_edge && (point.out_dir.is_same_axis(major_dir) || is_single_point_contour) { - if axis.segments.len() > 1000 { - axis.segments.clear(); - return false; - } - segment_ix = axis.segments.len(); - segment_dir = point.out_dir; - let mut segment = Segment { - dir: segment_dir, - first_ix: point_ix as u16, - last_ix: point_ix as u16, - score: MAX_SCORE, - ..Default::default() - }; - state.min_pos = point.u; - state.max_pos = point.u; - state.min_coord = point.v; - state.max_coord = point.v; - state.min_flags = point.flags; - state.max_flags = point.flags; - if !point.is_on_curve() { - state.min_on_coord = MAX_SCORE; - state.max_on_coord = MIN_SCORE; - } else { - state.min_on_coord = point.v; - state.max_on_coord = point.v; - } - on_edge = true; - if is_single_point_contour { - segment.pos = state.min_pos as i16; - if !point.is_on_curve() { - segment.flags |= Segment::ROUND; - } - segment.min_coord = point.v as i16; - segment.max_coord = point.v as i16; - segment.height = 0; - on_edge = false; - } - axis.segments.push(segment); - } - point_ix = contour.next(point_ix); - } - } - true -} - -/// Slightly increase the height of segments when it makes sense to better -/// detect and ignore serifs. -/// -/// See -fn adjust_segment_heights(outline: &mut Outline, axis: &mut Axis) { - let points = outline.points.as_slice(); - for segment in &mut axis.segments { - let first = segment.first_point(points); - let last = segment.last_point(points); - fn adjust_height(segment: &mut Segment, v1: i32, v2: i32) { - segment.height = (segment.height as i32 + ((v1 - v2) >> 1)) as i16; - } - let prev = &points[first.prev()]; - let next = &points[last.next()]; - if first.v < last.v { - if prev.v < first.v { - adjust_height(segment, first.v, prev.v); - } - if next.v > last.v { - adjust_height(segment, next.v, last.v); - } - } else { - if prev.v > first.v { - adjust_height(segment, prev.v, first.v); - } - if next.v < last.v { - adjust_height(segment, last.v, next.v); - } - } - } -} - -/// Performs the additional step of detecting round segments for the CJK script -/// group. -/// -/// See -fn _detect_round_segments_cjk(outline: &mut Outline, axis: &mut Axis) { - let points = outline.points.as_slice(); - // A segment is considered round if it doesn't have successive on-curve - // points - for segment in &mut axis.segments { - segment.flags &= !Segment::ROUND; - let mut point_ix = segment.first(); - let last_ix = segment.last(); - let first_point = &points[point_ix]; - let mut is_prev_on_curve = first_point.is_on_curve(); - point_ix = first_point.next(); - loop { - let point = &points[point_ix]; - let is_on_curve = point.is_on_curve(); - if is_prev_on_curve && is_on_curve { - // Two on-curves in a row means we're not a round segment - break; - } - is_prev_on_curve = is_on_curve; - point_ix = point.next(); - if point_ix == last_ix { - // We've reached the last point without two successive - // on-curves so we're round - segment.flags |= Segment::ROUND; - break; - } - } - } -} - -/// Capture current and previous state while computing segments. -/// -/// Values measured along a segment (point.v) are called "coordinates" and -/// values orthogonal to it (point.u) are called "positions" -#[derive(Copy, Clone)] -struct State { - min_pos: i32, - max_pos: i32, - min_coord: i32, - max_coord: i32, - min_flags: PointFlags, - max_flags: PointFlags, - min_on_coord: i32, - max_on_coord: i32, -} - -impl Default for State { - fn default() -> Self { - // - Self { - min_pos: MAX_SCORE, - max_pos: MIN_SCORE, - min_coord: MAX_SCORE, - max_coord: MIN_SCORE, - min_flags: PointFlags::default(), - max_flags: PointFlags::default(), - min_on_coord: MAX_SCORE, - max_on_coord: MIN_SCORE, - } - } -} - -impl State { - fn apply_to_segment(&self, segment: &mut Segment, flat_threshold: i32) { - segment.pos = ((self.min_pos + self.max_pos) >> 1) as i16; - segment.delta = ((self.max_pos - self.min_pos) >> 1) as i16; - // A segment is round if either end point is a - // control and the length of the on points in - // between fits within a heuristic limit. - if (!self.min_flags.is_on_curve() || !self.max_flags.is_on_curve()) - && (self.max_on_coord - self.min_on_coord) < flat_threshold - { - segment.flags |= Segment::ROUND; - } - segment.min_coord = self.min_coord as i16; - segment.max_coord = self.max_coord as i16; - segment.height = segment.max_coord - segment.min_coord; - } -} - -#[cfg(test)] -mod tests { - use super::{super::super::outline::Direction, *}; - use crate::MetadataProvider; - use raw::{types::GlyphId, FontRef}; - - #[test] - fn horizontal_segments() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::new(8)).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axis = Axis::new(Axis::HORIZONTAL, outline.orientation); - compute_segments(&mut outline, &mut axis, ScriptGroup::Default); - link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); - let segments = retain_segment_test_fields(&axis.segments); - let expected = [ - Segment { - flags: 0, - dir: Direction::Up, - pos: 55, - delta: 0, - min_coord: 26, - max_coord: 360, - height: 372, - link_ix: Some(3), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 112, - delta: 0, - min_coord: 481, - max_coord: 504, - height: 34, - link_ix: Some(2), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 168, - delta: 0, - min_coord: 483, - max_coord: 504, - height: 26, - link_ix: Some(1), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 109, - delta: 0, - min_coord: 109, - max_coord: 366, - height: 288, - link_ix: Some(0), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 453, - delta: 0, - min_coord: 169, - max_coord: 432, - height: 304, - link_ix: Some(7), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Up, - pos: 62, - delta: 0, - min_coord: 517, - max_coord: 566, - height: 76, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Down, - pos: 103, - delta: 0, - min_coord: 619, - max_coord: 647, - height: 41, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 507, - delta: 0, - min_coord: 40, - max_coord: 485, - height: 498, - link_ix: Some(4), - serif_ix: None, - ..Default::default() - }, - ]; - assert_eq!(segments, &expected); - } - - #[test] - fn vertical_segments() { - let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::new(8)).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axis = Axis::new(Axis::VERTICAL, outline.orientation); - compute_segments(&mut outline, &mut axis, ScriptGroup::Default); - link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); - let segments = retain_segment_test_fields(&axis.segments); - let expected = [ - Segment { - flags: 0, - dir: Direction::Left, - pos: 0, - delta: 0, - min_coord: 85, - max_coord: 470, - height: 418, - link_ix: Some(2), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 504, - delta: 0, - min_coord: 112, - max_coord: 168, - height: 56, - link_ix: Some(3), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 109, - delta: 0, - min_coord: 109, - max_coord: 427, - height: 327, - link_ix: Some(0), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Left, - pos: 483, - delta: 0, - min_coord: 86, - max_coord: 400, - height: 352, - link_ix: Some(1), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 647, - delta: 0, - min_coord: 76, - max_coord: 103, - height: 29, - link_ix: None, - serif_ix: Some(1), - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 592, - delta: 0, - min_coord: 131, - max_coord: 437, - height: 346, - link_ix: None, - serif_ix: Some(1), - ..Default::default() - }, - ]; - assert_eq!(segments, &expected); - } - - #[test] - fn cjk_horizontal_segments() { - let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::new(9)).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axis = Axis::new(Axis::HORIZONTAL, outline.orientation); - compute_segments(&mut outline, &mut axis, ScriptGroup::Cjk); - link_segments(&outline, &mut axis, 67109, ScriptGroup::Cjk, None); - let segments = retain_segment_test_fields(&axis.segments); - let expected = [ - Segment { - flags: 0, - dir: Direction::Down, - pos: 731, - delta: 0, - min_coord: 155, - max_coord: 676, - height: 524, - link_ix: Some(1), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 670, - delta: 0, - min_coord: 133, - max_coord: 712, - height: 579, - link_ix: Some(0), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 458, - delta: 0, - min_coord: 741, - max_coord: 757, - height: 88, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 911, - delta: 0, - min_coord: -9, - max_coord: 791, - height: 821, - link_ix: Some(5), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 693, - delta: 0, - min_coord: -7, - max_coord: 9, - height: 18, - link_ix: None, - serif_ix: Some(5), - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 849, - delta: 0, - min_coord: 11, - max_coord: 829, - height: 823, - link_ix: Some(3), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 569, - delta: 0, - min_coord: 547, - max_coord: 576, - height: 29, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Down, - pos: 201, - delta: 0, - min_coord: -57, - max_coord: 540, - height: 599, - link_ix: Some(8), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Up, - pos: 138, - delta: 0, - min_coord: -78, - max_coord: 543, - height: 640, - link_ix: Some(7), - serif_ix: None, - ..Default::default() - }, - ]; - assert_eq!(segments, &expected); - } - - #[test] - fn cjk_vertical_segments() { - let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::new(9)).unwrap(); - let mut outline = Outline::default(); - outline.fill(&glyph, Default::default()).unwrap(); - let mut axis = Axis::new(Axis::VERTICAL, outline.orientation); - compute_segments(&mut outline, &mut axis, ScriptGroup::Cjk); - link_segments(&outline, &mut axis, 67109, ScriptGroup::Cjk, None); - let segments = retain_segment_test_fields(&axis.segments); - let expected = [ - Segment { - flags: 0, - dir: Direction::Right, - pos: 758, - delta: 0, - min_coord: 280, - max_coord: 545, - height: 288, - link_ix: Some(1), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Left, - pos: 729, - delta: 0, - min_coord: 288, - max_coord: 674, - height: 391, - link_ix: Some(0), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Left, - pos: 133, - delta: 0, - min_coord: 670, - max_coord: 693, - height: 34, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 757, - delta: 0, - min_coord: 393, - max_coord: 458, - height: 70, - link_ix: None, - serif_ix: Some(0), - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Right, - pos: 3, - delta: 2, - min_coord: 727, - max_coord: 838, - height: 133, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Right, - pos: 576, - delta: 0, - min_coord: 397, - max_coord: 569, - height: 177, - link_ix: Some(7), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Left, - pos: 547, - delta: 0, - min_coord: 387, - max_coord: 569, - height: 182, - link_ix: None, - serif_ix: Some(7), - ..Default::default() - }, - Segment { - flags: 0, - dir: Direction::Left, - pos: 576, - delta: 0, - min_coord: 536, - max_coord: 546, - height: 10, - link_ix: Some(5), - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Left, - pos: -78, - delta: 0, - min_coord: 138, - max_coord: 161, - height: 34, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - Segment { - flags: 1, - dir: Direction::Left, - pos: 788, - delta: 0, - min_coord: 262, - max_coord: 294, - height: 46, - link_ix: None, - serif_ix: None, - ..Default::default() - }, - ]; - assert_eq!(segments, &expected); - } - - // Retain the fields that are valid and comparable after - // the segment pass. - fn retain_segment_test_fields(segments: &[Segment]) -> Vec { - segments - .iter() - .map(|segment| Segment { - flags: segment.flags, - dir: segment.dir, - pos: segment.pos, - delta: segment.delta, - min_coord: segment.min_coord, - max_coord: segment.max_coord, - height: segment.height, - link_ix: segment.link_ix, - serif_ix: segment.serif_ix, - ..Default::default() - }) - .collect() - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1502 +0,0 @@ -//! CFF hinting. - -use read_fonts::{ - tables::postscript::{charstring::CommandSink, dict::Blues}, - types::Fixed, -}; - -// "Default values for OS/2 typoAscender/Descender.." -// See -const ICF_TOP: Fixed = Fixed::from_i32(880); -const ICF_BOTTOM: Fixed = Fixed::from_i32(-120); - -// -const MAX_BLUES: usize = 7; -const MAX_OTHER_BLUES: usize = 5; -const MAX_BLUE_ZONES: usize = MAX_BLUES + MAX_OTHER_BLUES; - -// -const MAX_HINTS: usize = 96; - -// One bit per stem hint -// -const HINT_MASK_SIZE: usize = (MAX_HINTS + 7) / 8; - -// Constant for hint adjustment and em box hint placement. -// -const MIN_COUNTER: Fixed = Fixed::from_bits(0x8000); - -// -const EPSILON: Fixed = Fixed::from_bits(1); - -/// Parameters used to generate the stem and counter zones for the hinting -/// algorithm. -#[derive(Clone)] -pub(crate) struct HintParams { - pub blues: Blues, - pub family_blues: Blues, - pub other_blues: Blues, - pub family_other_blues: Blues, - pub blue_scale: Fixed, - pub blue_shift: Fixed, - pub blue_fuzz: Fixed, - pub language_group: i32, -} - -impl Default for HintParams { - fn default() -> Self { - Self { - blues: Blues::default(), - other_blues: Blues::default(), - family_blues: Blues::default(), - family_other_blues: Blues::default(), - // See - blue_scale: Fixed::from_f64(0.039625), - blue_shift: Fixed::from_i32(7), - blue_fuzz: Fixed::ONE, - language_group: 0, - } - } -} - -/// See -#[derive(Copy, Clone, PartialEq, Default, Debug)] -struct BlueZone { - is_bottom: bool, - cs_bottom_edge: Fixed, - cs_top_edge: Fixed, - cs_flat_edge: Fixed, - ds_flat_edge: Fixed, -} - -/// Hinting state for a PostScript subfont. -/// -/// Note that hinter states depend on the scale, subfont index and -/// variation coordinates of a glyph. They can be retained and reused -/// if those values remain the same. -#[derive(Copy, Clone, PartialEq, Default)] -pub(crate) struct HintState { - scale: Fixed, - blue_scale: Fixed, - blue_shift: Fixed, - blue_fuzz: Fixed, - language_group: i32, - suppress_overshoot: bool, - do_em_box_hints: bool, - boost: Fixed, - darken_y: Fixed, - zones: [BlueZone; MAX_BLUE_ZONES], - zone_count: usize, -} - -impl HintState { - pub fn new(params: &HintParams, scale: Fixed) -> Self { - let mut state = Self { - scale, - blue_scale: params.blue_scale, - blue_shift: params.blue_shift, - blue_fuzz: params.blue_fuzz, - language_group: params.language_group, - suppress_overshoot: false, - do_em_box_hints: false, - boost: Fixed::ZERO, - darken_y: Fixed::ZERO, - zones: [BlueZone::default(); MAX_BLUE_ZONES], - zone_count: 0, - }; - state.build_zones(params); - state - } - - fn zones(&self) -> &[BlueZone] { - &self.zones[..self.zone_count] - } - - /// Initialize zones from the set of blues values. - /// - /// See - fn build_zones(&mut self, params: &HintParams) { - self.do_em_box_hints = false; - // - match (self.language_group, params.blues.values().len()) { - (1, 2) => { - let blues = params.blues.values(); - if blues[0].0 < ICF_BOTTOM - && blues[0].1 < ICF_BOTTOM - && blues[1].0 > ICF_TOP - && blues[1].1 > ICF_TOP - { - // FreeType generates synthetic hints here. We'll do it - // later when building the hint map. - self.do_em_box_hints = true; - return; - } - } - (1, 0) => { - self.do_em_box_hints = true; - return; - } - _ => {} - } - let mut zones = [BlueZone::default(); MAX_BLUE_ZONES]; - let mut max_zone_height = Fixed::ZERO; - let mut zone_ix = 0usize; - // Copy blues and other blues to a combined array of top and bottom zones. - for blue in params.blues.values().iter().take(MAX_BLUES) { - // FreeType loads blues as integers and then expands to 16.16 - // at initialization. We load them as 16.16 so floor them here - // to ensure we match. - // - let bottom = blue.0.floor(); - let top = blue.1.floor(); - let zone_height = top - bottom; - if zone_height < Fixed::ZERO { - // Reject zones with negative height - continue; - } - max_zone_height = max_zone_height.max(zone_height); - let zone = &mut zones[zone_ix]; - zone.cs_bottom_edge = bottom; - zone.cs_top_edge = top; - if zone_ix == 0 { - // First blue value is bottom zone - zone.is_bottom = true; - zone.cs_flat_edge = top; - } else { - // Remaining blue values are top zones - zone.is_bottom = false; - // Adjust both edges of top zone upward by twice darkening amount - zone.cs_top_edge += twice(self.darken_y); - zone.cs_bottom_edge += twice(self.darken_y); - zone.cs_flat_edge = zone.cs_bottom_edge; - } - zone_ix += 1; - } - for blue in params.other_blues.values().iter().take(MAX_OTHER_BLUES) { - let bottom = blue.0.floor(); - let top = blue.1.floor(); - let zone_height = top - bottom; - if zone_height < Fixed::ZERO { - // Reject zones with negative height - continue; - } - max_zone_height = max_zone_height.max(zone_height); - let zone = &mut zones[zone_ix]; - // All "other" blues are bottom zone - zone.is_bottom = true; - zone.cs_bottom_edge = bottom; - zone.cs_top_edge = top; - zone.cs_flat_edge = top; - zone_ix += 1; - } - // Adjust for family blues - let units_per_pixel = Fixed::ONE / self.scale; - for zone in &mut zones[..zone_ix] { - let flat = zone.cs_flat_edge; - let mut min_diff = Fixed::MAX; - if zone.is_bottom { - // In a bottom zone, the top edge is the flat edge. - // Search family other blues for bottom zones. Look for the - // closest edge that is within the one pixel threshold. - for blue in params.family_other_blues.values() { - let family_flat = blue.1; - let diff = (flat - family_flat).abs(); - if diff < min_diff && diff < units_per_pixel { - zone.cs_flat_edge = family_flat; - min_diff = diff; - if diff == Fixed::ZERO { - break; - } - } - } - // Check the first member of family blues, which is a bottom - // zone - if !params.family_blues.values().is_empty() { - let family_flat = params.family_blues.values()[0].1; - let diff = (flat - family_flat).abs(); - if diff < min_diff && diff < units_per_pixel { - zone.cs_flat_edge = family_flat; - } - } - } else { - // In a top zone, the bottom edge is the flat edge. - // Search family blues for top zones, skipping the first, which - // is a bottom zone. Look for closest family edge that is - // within the one pixel threshold. - for blue in params.family_blues.values().iter().skip(1) { - let family_flat = blue.0 + twice(self.darken_y); - let diff = (flat - family_flat).abs(); - if diff < min_diff && diff < units_per_pixel { - zone.cs_flat_edge = family_flat; - min_diff = diff; - if diff == Fixed::ZERO { - break; - } - } - } - } - } - if max_zone_height > Fixed::ZERO && self.blue_scale > (Fixed::ONE / max_zone_height) { - // Clamp at maximum scale - self.blue_scale = Fixed::ONE / max_zone_height; - } - // Suppress overshoot and boost blue zones at small sizes - if self.scale < self.blue_scale { - self.suppress_overshoot = true; - self.boost = - Fixed::from_f64(0.6) - Fixed::from_f64(0.6).mul_div(self.scale, self.blue_scale); - // boost must remain less than 0.5, or baseline could go negative - self.boost = self.boost.min(Fixed::from_bits(0x7FFF)); - } - if self.darken_y != Fixed::ZERO { - self.boost = Fixed::ZERO; - } - // Set device space alignment for each zone; apply boost amount before - // rounding flat edge - let scale = self.scale; - let boost = self.boost; - for zone in &mut zones[..zone_ix] { - let boost = if zone.is_bottom { -boost } else { boost }; - zone.ds_flat_edge = (zone.cs_flat_edge * scale + boost).round(); - } - self.zones = zones; - self.zone_count = zone_ix; - } - - /// Check whether a hint is captured by one of the blue zones. - /// - /// See - fn capture(&self, bottom_edge: &mut Hint, top_edge: &mut Hint) -> bool { - // We use some wrapping arithmetic on this value below to avoid panics - // on overflow and match FreeType's behavior - // See - let fuzz = self.blue_fuzz; - let mut captured = false; - let mut adjustment = Fixed::ZERO; - for zone in self.zones() { - if zone.is_bottom - && bottom_edge.is_bottom() - && zone.cs_bottom_edge.wrapping_sub(fuzz) <= bottom_edge.cs_coord - && bottom_edge.cs_coord <= zone.cs_top_edge.wrapping_add(fuzz) - { - // Bottom edge captured by bottom zone. - adjustment = if self.suppress_overshoot { - zone.ds_flat_edge - } else if zone.cs_top_edge.wrapping_sub(bottom_edge.cs_coord) >= self.blue_shift { - // Guarantee minimum of 1 pixel overshoot - bottom_edge - .ds_coord - .round() - .min(zone.ds_flat_edge - Fixed::ONE) - } else { - bottom_edge.ds_coord.round() - }; - adjustment -= bottom_edge.ds_coord; - captured = true; - break; - } - if !zone.is_bottom - && top_edge.is_top() - && zone.cs_bottom_edge.wrapping_sub(fuzz) <= top_edge.cs_coord - && top_edge.cs_coord <= zone.cs_top_edge.wrapping_add(fuzz) - { - // Top edge captured by top zone. - adjustment = if self.suppress_overshoot { - zone.ds_flat_edge - } else if top_edge.cs_coord.wrapping_sub(zone.cs_bottom_edge) >= self.blue_shift { - // Guarantee minimum of 1 pixel overshoot - top_edge - .ds_coord - .round() - .max(zone.ds_flat_edge + Fixed::ONE) - } else { - top_edge.ds_coord.round() - }; - adjustment -= top_edge.ds_coord; - captured = true; - break; - } - } - if captured { - // Move both edges and mark them as "locked" - if bottom_edge.is_valid() { - bottom_edge.ds_coord += adjustment; - bottom_edge.lock(); - } - if top_edge.is_valid() { - top_edge.ds_coord += adjustment; - top_edge.lock(); - } - } - captured - } -} - -/// -#[derive(Copy, Clone, Default)] -struct StemHint { - /// If true, device space position is valid - is_used: bool, - // Character space position - min: Fixed, - max: Fixed, - // Device space position after first use - ds_min: Fixed, - ds_max: Fixed, -} - -// Hint flags -const GHOST_BOTTOM: u8 = 0x1; -const GHOST_TOP: u8 = 0x2; -const PAIR_BOTTOM: u8 = 0x4; -const PAIR_TOP: u8 = 0x8; -const LOCKED: u8 = 0x10; -const SYNTHETIC: u8 = 0x20; - -/// -#[derive(Copy, Clone, PartialEq, Default, Debug)] -struct Hint { - flags: u8, - /// Index in original stem hint array (if not synthetic) - index: u8, - cs_coord: Fixed, - ds_coord: Fixed, - scale: Fixed, -} - -impl Hint { - fn is_valid(&self) -> bool { - self.flags != 0 - } - - fn is_bottom(&self) -> bool { - self.flags & (GHOST_BOTTOM | PAIR_BOTTOM) != 0 - } - - fn is_top(&self) -> bool { - self.flags & (GHOST_TOP | PAIR_TOP) != 0 - } - - fn is_pair(&self) -> bool { - self.flags & (PAIR_BOTTOM | PAIR_TOP) != 0 - } - - fn is_pair_top(&self) -> bool { - self.flags & PAIR_TOP != 0 - } - - fn is_locked(&self) -> bool { - self.flags & LOCKED != 0 - } - - fn is_synthetic(&self) -> bool { - self.flags & SYNTHETIC != 0 - } - - fn lock(&mut self) { - self.flags |= LOCKED - } - - /// Hint initialization from an incoming stem hint. - /// - /// See - fn setup( - &mut self, - stem: &StemHint, - index: u8, - origin: Fixed, - scale: Fixed, - darken_y: Fixed, - is_bottom: bool, - ) { - // "Ghost hints" are used to align a single edge rather than a - // stem-- think the top and bottom edges of an uppercase - // sans-serif I. - // These are encoded internally with stem hints of width -21 - // and -20 for bottom and top hints, respectively. - const GHOST_BOTTOM_WIDTH: Fixed = Fixed::from_i32(-21); - const GHOST_TOP_WIDTH: Fixed = Fixed::from_i32(-20); - let width = stem.max - stem.min; - if width == GHOST_BOTTOM_WIDTH { - if is_bottom { - self.cs_coord = stem.max; - self.flags = GHOST_BOTTOM; - } else { - self.flags = 0; - } - } else if width == GHOST_TOP_WIDTH { - if !is_bottom { - self.cs_coord = stem.min; - self.flags = GHOST_TOP; - } else { - self.flags = 0; - } - } else if width < Fixed::ZERO { - // If width < 0, this is an inverted pair. We follow FreeType and - // swap the coordinates - if is_bottom { - self.cs_coord = stem.max; - self.flags = PAIR_BOTTOM; - } else { - self.cs_coord = stem.min; - self.flags = PAIR_TOP; - } - } else { - // This is a normal pair - if is_bottom { - self.cs_coord = stem.min; - self.flags = PAIR_BOTTOM; - } else { - self.cs_coord = stem.max; - self.flags = PAIR_TOP; - } - } - if self.is_top() { - // For top hints, adjust character space position up by twice the - // darkening amount - self.cs_coord += twice(darken_y); - } - self.cs_coord += origin; - self.scale = scale; - self.index = index; - // If original stem hint was used, copy the position - if self.flags != 0 && stem.is_used { - if self.is_top() { - self.ds_coord = stem.ds_max; - } else { - self.ds_coord = stem.ds_min; - } - self.lock(); - } else { - self.ds_coord = self.cs_coord * scale; - } - } -} - -/// Collection of adjusted hint edges. -/// -/// -#[derive(Copy, Clone)] -struct HintMap { - edges: [Hint; MAX_HINTS], - len: usize, - is_valid: bool, - scale: Fixed, -} - -impl HintMap { - fn new(scale: Fixed) -> Self { - Self { - edges: [Hint::default(); MAX_HINTS], - len: 0, - is_valid: false, - scale, - } - } - - fn clear(&mut self) { - self.len = 0; - self.is_valid = false; - } - - /// Transform character space coordinate to device space. - /// - /// Based on - fn transform(&self, coord: Fixed) -> Fixed { - if self.len == 0 { - return coord * self.scale; - } - let limit = self.len - 1; - let mut i = 0; - while i < limit && coord >= self.edges[i + 1].cs_coord { - i += 1; - } - while i > 0 && coord < self.edges[i].cs_coord { - i -= 1; - } - let first_edge = &self.edges[0]; - if i == 0 && coord < first_edge.cs_coord { - // Special case for points below first edge: use uniform scale - ((coord - first_edge.cs_coord) * self.scale) + first_edge.ds_coord - } else { - // Use highest edge where cs_coord >= edge.cs_coord - let edge = &self.edges[i]; - ((coord - edge.cs_coord) * edge.scale) + edge.ds_coord - } - } - - /// Insert hint edges into map, sorted by character space coordinate. - /// - /// Based on - fn insert(&mut self, bottom: &Hint, top: &Hint, initial: Option<&HintMap>) { - let (is_pair, mut first_edge) = if !bottom.is_valid() { - // Bottom is invalid: insert only top edge - (false, *top) - } else if !top.is_valid() { - // Top is invalid: insert only bottom edge - (false, *bottom) - } else { - // We have a valid pair! - (true, *bottom) - }; - let mut second_edge = *top; - if is_pair && top.cs_coord < bottom.cs_coord { - // Paired edges must be in proper order. FT just ignores the hint. - return; - } - let edge_count = if is_pair { 2 } else { 1 }; - if self.len + edge_count > MAX_HINTS { - // Won't fit. Again, ignore. - return; - } - // Find insertion index that keeps the edge list sorted - let mut insert_ix = 0; - while insert_ix < self.len { - if self.edges[insert_ix].cs_coord >= first_edge.cs_coord { - break; - } - insert_ix += 1; - } - // Discard hints that overlap in character space - if insert_ix < self.len { - let current = &self.edges[insert_ix]; - // Existing edge is the same - if (current.cs_coord == first_edge.cs_coord) - // Pair straddles the next edge - || (is_pair && current.cs_coord <= second_edge.cs_coord) - // Inserting between paired edges - || current.is_pair_top() - { - return; - } - } - // Recompute device space locations using initial hint map - if !first_edge.is_locked() { - if let Some(initial) = initial { - if is_pair { - // Preserve stem width: position center of stem with - // initial hint map and two edges with nominal scale - // - let mid = - initial.transform(midpoint(first_edge.cs_coord, second_edge.cs_coord)); - let half_width = half(second_edge.cs_coord - first_edge.cs_coord) * self.scale; - first_edge.ds_coord = mid - half_width; - second_edge.ds_coord = mid + half_width; - } else { - first_edge.ds_coord = initial.transform(first_edge.cs_coord); - } - } - } - // Now discard hints that overlap in device space: - if insert_ix > 0 && first_edge.ds_coord < self.edges[insert_ix - 1].ds_coord { - // Inserting after an existing edge - return; - } - if insert_ix < self.len - && ((is_pair && second_edge.ds_coord > self.edges[insert_ix].ds_coord) - || first_edge.ds_coord > self.edges[insert_ix].ds_coord) - { - // Inserting before an existing edge - return; - } - // If we're inserting in the middle, make room in the edge array - if insert_ix != self.len { - let mut src_index = self.len - 1; - let mut dst_index = self.len + edge_count - 1; - loop { - self.edges[dst_index] = self.edges[src_index]; - if src_index == insert_ix { - break; - } - src_index -= 1; - dst_index -= 1; - } - } - self.edges[insert_ix] = first_edge; - if is_pair { - self.edges[insert_ix + 1] = second_edge; - } - self.len += edge_count; - } - - /// Adjust hint pairs so that one of the two edges is on a pixel boundary. - /// - /// Based on - fn adjust(&mut self) { - let mut saved = [(0usize, Fixed::ZERO); MAX_HINTS]; - let mut saved_count = 0usize; - let mut i = 0; - // From FT with adjustments for variable names: - // "First pass is bottom-up (font hint order) without look-ahead. - // Locked edges are already adjusted. - // Unlocked edges begin with ds_coord from `initial_map'. - // Save edges that are not optimally adjusted in `saved' array, - // and process them in second pass." - let limit = self.len; - while i < limit { - let is_pair = self.edges[i].is_pair(); - let j = if is_pair { i + 1 } else { i }; - if !self.edges[i].is_locked() { - // We can adjust hint edges that are not locked - let frac_down = self.edges[i].ds_coord.fract(); - let frac_up = self.edges[j].ds_coord.fract(); - // There are four possibilities. We compute them all. - // (moves down are negative) - let down_move_down = Fixed::ZERO - frac_down; - let up_move_down = Fixed::ZERO - frac_up; - let down_move_up = if frac_down == Fixed::ZERO { - Fixed::ZERO - } else { - Fixed::ONE - frac_down - }; - let up_move_up = if frac_up == Fixed::ZERO { - Fixed::ZERO - } else { - Fixed::ONE - frac_up - }; - // Smallest move up - let move_up = down_move_up.min(up_move_up); - // Smallest move down - let move_down = down_move_down.max(up_move_down); - let mut save_edge = false; - let adjustment; - // Check for room to move up: - // 1. We're at the top of the array, or - // 2. The next edge is at or above the proposed move up - if j >= self.len - 1 - || self.edges[j + 1].ds_coord - >= (self.edges[j].ds_coord + move_up + MIN_COUNTER) - { - // Also check for room to move down... - if i == 0 - || self.edges[i - 1].ds_coord - <= (self.edges[i].ds_coord + move_down - MIN_COUNTER) - { - // .. and move the smallest distance - adjustment = if -move_down < move_up { - move_down - } else { - move_up - }; - } else { - adjustment = move_up; - } - } else if i == 0 - || self.edges[i - 1].ds_coord - <= (self.edges[i].ds_coord + move_down - MIN_COUNTER) - { - // We can move down - adjustment = move_down; - // True if the move is not optimum - save_edge = move_up < -move_down; - } else { - // We can't move either way without overlapping - adjustment = Fixed::ZERO; - save_edge = true; - } - // Capture non-optimal adjustments and save them for a second - // pass. This is only possible if the edge above is unlocked - // and can be moved. - if save_edge && j < self.len - 1 && !self.edges[j + 1].is_locked() { - // (index, desired adjustment) - saved[saved_count] = (j, move_up - adjustment); - saved_count += 1; - } - // Apply the adjustment - self.edges[i].ds_coord += adjustment; - if is_pair { - self.edges[j].ds_coord += adjustment; - } - } - // Compute the new edge scale - if i > 0 && self.edges[i].cs_coord != self.edges[i - 1].cs_coord { - let a = self.edges[i]; - let b = self.edges[i - 1]; - self.edges[i - 1].scale = (a.ds_coord - b.ds_coord) / (a.cs_coord - b.cs_coord); - } - if is_pair { - if self.edges[j].cs_coord != self.edges[j - 1].cs_coord { - let a = self.edges[j]; - let b = self.edges[j - 1]; - self.edges[j - 1].scale = (a.ds_coord - b.ds_coord) / (a.cs_coord - b.cs_coord); - } - i += 1; - } - i += 1; - } - // Second pass tries to move non-optimal edges up if the first - // pass created room - for (j, adjustment) in saved[..saved_count].iter().copied().rev() { - if self.edges[j + 1].ds_coord >= (self.edges[j].ds_coord + adjustment + MIN_COUNTER) { - self.edges[j].ds_coord += adjustment; - if self.edges[j].is_pair() { - self.edges[j - 1].ds_coord += adjustment; - } - } - } - } - - /// Builds a hintmap from hints and mask. - /// - /// If `initial_map` is invalid, this recurses one level to initialize - /// it. If `is_initial` is true, simply build the initial map. - /// - /// Based on - fn build( - &mut self, - state: &HintState, - mask: Option, - mut initial_map: Option<&mut HintMap>, - stems: &mut [StemHint], - origin: Fixed, - is_initial: bool, - ) { - let scale = state.scale; - let darken_y = Fixed::ZERO; - if !is_initial { - if let Some(initial_map) = &mut initial_map { - if !initial_map.is_valid { - // Note: recursive call here to build the initial map if it - // is provided and invalid - initial_map.build(state, Some(HintMask::all()), None, stems, origin, true); - } - } - } - let initial_map = initial_map.map(|x| x as &HintMap); - self.clear(); - // If the mask is missing or invalid, assume all hints are active - let mut mask = mask.unwrap_or_else(HintMask::all); - if !mask.is_valid { - mask = HintMask::all(); - } - if state.do_em_box_hints { - // FreeType generates these during blues initialization. Do - // it here just to avoid carrying the extra state in the - // already large HintState struct. - // - let mut bottom = Hint::default(); - bottom.cs_coord = ICF_BOTTOM - EPSILON; - bottom.ds_coord = (bottom.cs_coord * scale).round() - MIN_COUNTER; - bottom.scale = scale; - bottom.flags = GHOST_BOTTOM | LOCKED | SYNTHETIC; - let mut top = Hint::default(); - top.cs_coord = ICF_TOP + EPSILON + twice(state.darken_y); - top.ds_coord = (top.cs_coord * scale).round() + MIN_COUNTER; - top.scale = scale; - top.flags = GHOST_TOP | LOCKED | SYNTHETIC; - let invalid = Hint::default(); - self.insert(&bottom, &invalid, initial_map); - self.insert(&invalid, &top, initial_map); - } - let mut tmp_mask = mask; - // FreeType iterates over the hint mask with some fancy bit logic. We - // do the simpler thing and loop over the stems. - // - for (i, stem) in stems.iter().enumerate() { - if !tmp_mask.get(i) { - continue; - } - let hint_ix = i as u8; - let mut bottom = Hint::default(); - let mut top = Hint::default(); - bottom.setup(stem, hint_ix, origin, scale, darken_y, true); - top.setup(stem, hint_ix, origin, scale, darken_y, false); - // Insert hints that are locked or captured by a blue zone - if bottom.is_locked() || top.is_locked() || state.capture(&mut bottom, &mut top) { - if is_initial { - self.insert(&bottom, &top, None); - } else { - self.insert(&bottom, &top, initial_map); - } - // Avoid processing this hint in the second pass - tmp_mask.clear(i); - } - } - if is_initial { - // Heuristic: insert a point at (0, 0) if it's not covered by a - // mapping. Ensures a lock at baseline for glyphs missing a - // baseline hint. - if self.len == 0 - || self.edges[0].cs_coord > Fixed::ZERO - || self.edges[self.len - 1].cs_coord < Fixed::ZERO - { - let edge = Hint { - flags: GHOST_BOTTOM | LOCKED | SYNTHETIC, - scale, - ..Default::default() - }; - let invalid = Hint::default(); - self.insert(&edge, &invalid, None); - } - } else { - // Insert hints that were skipped in the first pass - for (i, stem) in stems.iter().enumerate() { - if !tmp_mask.get(i) { - continue; - } - let hint_ix = i as u8; - let mut bottom = Hint::default(); - let mut top = Hint::default(); - bottom.setup(stem, hint_ix, origin, scale, darken_y, true); - top.setup(stem, hint_ix, origin, scale, darken_y, false); - self.insert(&bottom, &top, initial_map); - } - } - // Adjust edges that are not locked to blue zones - self.adjust(); - if !is_initial { - // Save position of edges that were used by the hint map. - for edge in &self.edges[..self.len] { - if edge.is_synthetic() { - continue; - } - let stem = &mut stems[edge.index as usize]; - if edge.is_top() { - stem.ds_max = edge.ds_coord; - } else { - stem.ds_min = edge.ds_coord; - } - stem.is_used = true; - } - } - self.is_valid = true; - } -} - -/// Bitmask that specifies which hints are currently active. -/// -/// "Each bit of the mask, starting with the most-significant bit of -/// the first byte, represents the corresponding hint zone in the -/// order in which the hints were declared at the beginning of -/// the charstring." -/// -/// See -/// Also -#[derive(Copy, Clone, PartialEq, Default)] -struct HintMask { - mask: [u8; HINT_MASK_SIZE], - is_valid: bool, -} - -impl HintMask { - fn new(bytes: &[u8]) -> Option { - let len = bytes.len(); - if len > HINT_MASK_SIZE { - return None; - } - let mut mask = Self::default(); - mask.mask[..len].copy_from_slice(&bytes[..len]); - mask.is_valid = true; - Some(mask) - } - - fn all() -> Self { - Self { - mask: [0xFF; HINT_MASK_SIZE], - is_valid: true, - } - } - - fn clear(&mut self, bit: usize) { - self.mask[bit >> 3] &= !msb_mask(bit); - } - - fn get(&self, bit: usize) -> bool { - self.mask[bit >> 3] & msb_mask(bit) != 0 - } -} - -/// Returns a bit mask for the selected bit with the -/// most significant bit at index 0. -fn msb_mask(bit: usize) -> u8 { - 1 << (7 - (bit & 0x7)) -} - -pub(super) struct HintingSink<'a, S> { - state: &'a HintState, - sink: &'a mut S, - stem_hints: [StemHint; MAX_HINTS], - stem_count: u8, - mask: HintMask, - initial_map: HintMap, - map: HintMap, - /// Most recent move_to in character space. - start_point: Option<[Fixed; 2]>, - /// Most recent line_to. First two elements are coords in character - /// space and the last two are in device space. - pending_line: Option<[Fixed; 4]>, -} - -impl<'a, S: CommandSink> HintingSink<'a, S> { - pub fn new(state: &'a HintState, sink: &'a mut S) -> Self { - let scale = state.scale; - Self { - state, - sink, - stem_hints: [StemHint::default(); MAX_HINTS], - stem_count: 0, - mask: HintMask::all(), - initial_map: HintMap::new(scale), - map: HintMap::new(scale), - start_point: None, - pending_line: None, - } - } - - pub fn finish(&mut self) { - self.maybe_close_subpath(); - } - - fn maybe_close_subpath(&mut self) { - // This requires some explanation. The hint mask can be modified - // during charstring evaluation which changes the set of hints that - // are applied. FreeType ensures that the closing line for any subpath - // is transformed with the same hint map as the starting point for the - // subpath. This is done by stashing a copy of the hint map that is - // active when a new subpath is started. Unlike FreeType, we make use - // of close elements, so we can cheat a bit here and avoid the - // extra hintmap. If we're closing an open subpath and have a pending - // line and the line is not equal to the start point in character - // space, then we emit the saved device space coordinates for the - // line. If the coordinates do match in character space, we omit - // that line. The unconditional close command ensures that the - // start and end points coincide. - // Note: this doesn't apply to subpaths that end in cubics. - match (self.start_point.take(), self.pending_line.take()) { - (Some(start), Some([cs_x, cs_y, ds_x, ds_y])) => { - if start != [cs_x, cs_y] { - self.sink.line_to(ds_x, ds_y); - } - self.sink.close(); - } - (Some(_), _) => self.sink.close(), - _ => {} - } - } - - fn flush_pending_line(&mut self) { - if let Some([_, _, x, y]) = self.pending_line.take() { - self.sink.line_to(x, y); - } - } - - fn hint(&mut self, coord: Fixed) -> Fixed { - if !self.map.is_valid { - self.build_hint_map(Some(self.mask), Fixed::ZERO); - } - trunc(self.map.transform(coord)) - } - - fn scale(&self, coord: Fixed) -> Fixed { - trunc(coord * self.state.scale) - } - - fn add_stem(&mut self, min: Fixed, max: Fixed) { - let index = self.stem_count as usize; - if index >= MAX_HINTS || self.map.is_valid { - return; - } - let stem = &mut self.stem_hints[index]; - stem.min = min; - stem.max = max; - stem.is_used = false; - stem.ds_min = Fixed::ZERO; - stem.ds_max = Fixed::ZERO; - self.stem_count = index as u8 + 1; - } - - fn build_hint_map(&mut self, mask: Option, origin: Fixed) { - self.map.build( - self.state, - mask, - Some(&mut self.initial_map), - &mut self.stem_hints[..self.stem_count as usize], - origin, - false, - ); - } -} - -impl CommandSink for HintingSink<'_, S> { - fn hstem(&mut self, min: Fixed, max: Fixed) { - self.add_stem(min, max); - } - - fn hint_mask(&mut self, mask: &[u8]) { - // For invalid hint masks, FreeType assumes all hints are active. - // See - let mask = HintMask::new(mask).unwrap_or_else(HintMask::all); - if mask != self.mask { - self.mask = mask; - self.map.is_valid = false; - } - } - - fn counter_mask(&mut self, mask: &[u8]) { - // For counter masks, we build a temporary hint map "just to - // place and lock those stems participating in the counter - // mask." Building the map modifies the stem hint array as a - // side effect. - // See - let mask = HintMask::new(mask).unwrap_or_else(HintMask::all); - let mut map = HintMap::new(self.state.scale); - map.build( - self.state, - Some(mask), - Some(&mut self.initial_map), - &mut self.stem_hints[..self.stem_count as usize], - Fixed::ZERO, - false, - ); - } - - fn move_to(&mut self, x: Fixed, y: Fixed) { - self.maybe_close_subpath(); - self.start_point = Some([x, y]); - let x = self.scale(x); - let y = self.hint(y); - self.sink.move_to(x, y); - } - - fn line_to(&mut self, x: Fixed, y: Fixed) { - self.flush_pending_line(); - let ds_x = self.scale(x); - let ds_y = self.hint(y); - self.pending_line = Some([x, y, ds_x, ds_y]); - } - - fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { - self.flush_pending_line(); - let cx1 = self.scale(cx1); - let cy1 = self.hint(cy1); - let cx2 = self.scale(cx2); - let cy2 = self.hint(cy2); - let x = self.scale(x); - let y = self.hint(y); - self.sink.curve_to(cx1, cy1, cx2, cy2, x, y); - } - - fn close(&mut self) { - // We emit close commands based on the sequence of moves. - // See `maybe_close_subpath` - } -} - -/// FreeType converts from 16.16 to 26.6 by truncation. We keep our -/// values in 16.16 so simply zero the low 10 bits to match the -/// precision when converting to f32. -fn trunc(value: Fixed) -> Fixed { - Fixed::from_bits(value.to_bits() & !0x3FF) -} - -fn half(value: Fixed) -> Fixed { - Fixed::from_bits(value.to_bits() / 2) -} - -fn twice(value: Fixed) -> Fixed { - Fixed::from_bits(value.to_bits().wrapping_mul(2)) -} - -/// Computes midpoint between `a` and `b`, avoiding overflow if the sum -/// of the high 16 bits exceeds `i16::MAX`. -fn midpoint(a: Fixed, b: Fixed) -> Fixed { - a + half(b - a) -} - -#[cfg(test)] -mod tests { - use read_fonts::{tables::postscript::charstring::CommandSink, types::F2Dot14, FontRef}; - - use super::{ - BlueZone, Blues, Fixed, Hint, HintMap, HintMask, HintParams, HintState, HintingSink, - StemHint, GHOST_BOTTOM, GHOST_TOP, HINT_MASK_SIZE, LOCKED, PAIR_BOTTOM, PAIR_TOP, - }; - - fn make_hint_state() -> HintState { - fn make_blues(values: &[f64]) -> Blues { - Blues::new(values.iter().copied().map(Fixed::from_f64)) - } - // - // - // - // - // - let params = HintParams { - blues: make_blues(&[ - -15.0, 0.0, 536.0, 547.0, 571.0, 582.0, 714.0, 726.0, 760.0, 772.0, - ]), - other_blues: make_blues(&[-255.0, -240.0]), - blue_scale: Fixed::from_f64(0.05), - blue_shift: Fixed::from_i32(7), - blue_fuzz: Fixed::ZERO, - ..Default::default() - }; - HintState::new(¶ms, Fixed::ONE / Fixed::from_i32(64)) - } - - #[test] - fn scaled_blue_zones() { - let state = make_hint_state(); - assert!(!state.do_em_box_hints); - assert_eq!(state.zone_count, 6); - assert_eq!(state.boost, Fixed::from_bits(27035)); - assert!(state.suppress_overshoot); - // FreeType generates the following zones: - let expected_zones = &[ - // csBottomEdge -983040 int - // csTopEdge 0 int - // csFlatEdge 0 int - // dsFlatEdge 0 int - // bottomZone 1 '\x1' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(-983040), - is_bottom: true, - ..Default::default() - }, - // csBottomEdge 35127296 int - // csTopEdge 35848192 int - // csFlatEdge 35127296 int - // dsFlatEdge 589824 int - // bottomZone 0 '\0' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(35127296), - cs_top_edge: Fixed::from_bits(35848192), - cs_flat_edge: Fixed::from_bits(35127296), - ds_flat_edge: Fixed::from_bits(589824), - is_bottom: false, - }, - // csBottomEdge 37421056 int - // csTopEdge 38141952 int - // csFlatEdge 37421056 int - // dsFlatEdge 589824 int - // bottomZone 0 '\0' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(37421056), - cs_top_edge: Fixed::from_bits(38141952), - cs_flat_edge: Fixed::from_bits(37421056), - ds_flat_edge: Fixed::from_bits(589824), - is_bottom: false, - }, - // csBottomEdge 46792704 int - // csTopEdge 47579136 int - // csFlatEdge 46792704 int - // dsFlatEdge 786432 int - // bottomZone 0 '\0' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(46792704), - cs_top_edge: Fixed::from_bits(47579136), - cs_flat_edge: Fixed::from_bits(46792704), - ds_flat_edge: Fixed::from_bits(786432), - is_bottom: false, - }, - // csBottomEdge 49807360 int - // csTopEdge 50593792 int - // csFlatEdge 49807360 int - // dsFlatEdge 786432 int - // bottomZone 0 '\0' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(49807360), - cs_top_edge: Fixed::from_bits(50593792), - cs_flat_edge: Fixed::from_bits(49807360), - ds_flat_edge: Fixed::from_bits(786432), - is_bottom: false, - }, - // csBottomEdge -16711680 int - // csTopEdge -15728640 int - // csFlatEdge -15728640 int - // dsFlatEdge -262144 int - // bottomZone 1 '\x1' unsigned char - BlueZone { - cs_bottom_edge: Fixed::from_bits(-16711680), - cs_top_edge: Fixed::from_bits(-15728640), - cs_flat_edge: Fixed::from_bits(-15728640), - ds_flat_edge: Fixed::from_bits(-262144), - is_bottom: true, - }, - ]; - assert_eq!(state.zones(), expected_zones); - } - - #[test] - fn blue_zone_capture() { - let state = make_hint_state(); - let bottom_edge = Hint { - flags: PAIR_BOTTOM, - ds_coord: Fixed::from_f64(2.3), - ..Default::default() - }; - let top_edge = Hint { - flags: PAIR_TOP, - // This value chosen to fit within the first "top" blue zone - cs_coord: Fixed::from_bits(35127297), - ds_coord: Fixed::from_f64(2.3), - ..Default::default() - }; - // Capture both - { - let (mut bottom_edge, mut top_edge) = (bottom_edge, top_edge); - assert!(state.capture(&mut bottom_edge, &mut top_edge)); - assert!(bottom_edge.is_locked()); - assert!(top_edge.is_locked()); - } - // Capture none - { - // Used to guarantee the edges are below all blue zones and will - // not be captured - let min_cs_coord = Fixed::MIN; - let mut bottom_edge = Hint { - cs_coord: min_cs_coord, - ..bottom_edge - }; - let mut top_edge = Hint { - cs_coord: min_cs_coord, - ..top_edge - }; - assert!(!state.capture(&mut bottom_edge, &mut top_edge)); - assert!(!bottom_edge.is_locked()); - assert!(!top_edge.is_locked()); - } - // Capture bottom, ignore invalid top - { - let mut bottom_edge = bottom_edge; - let mut top_edge = Hint { - // Empty flags == invalid hint - flags: 0, - ..top_edge - }; - assert!(state.capture(&mut bottom_edge, &mut top_edge)); - assert!(bottom_edge.is_locked()); - assert!(!top_edge.is_locked()); - } - // Capture top, ignore invalid bottom - { - let mut bottom_edge = Hint { - // Empty flags == invalid hint - flags: 0, - ..bottom_edge - }; - let mut top_edge = top_edge; - assert!(state.capture(&mut bottom_edge, &mut top_edge)); - assert!(!bottom_edge.is_locked()); - assert!(top_edge.is_locked()); - } - } - - #[test] - fn hint_mask_ops() { - const MAX_BITS: usize = HINT_MASK_SIZE * 8; - let all_bits = HintMask::all(); - for i in 0..MAX_BITS { - assert!(all_bits.get(i)); - } - let odd_bits = HintMask::new(&[0b01010101; HINT_MASK_SIZE]).unwrap(); - for i in 0..MAX_BITS { - assert_eq!(i & 1 != 0, odd_bits.get(i)); - } - let mut cleared_bits = odd_bits; - for i in 0..MAX_BITS { - if i & 1 != 0 { - cleared_bits.clear(i); - } - } - assert_eq!(cleared_bits.mask, HintMask::default().mask); - } - - #[test] - fn hint_mapping() { - let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); - let cff_font = super::super::Outlines::new(&font).unwrap(); - let state = cff_font - .subfont(0, Some(8.0), &[F2Dot14::from_f32(-1.0); 2]) - .unwrap() - .hint_state; - let mut initial_map = HintMap::new(state.scale); - let mut map = HintMap::new(state.scale); - // Stem hints from Cantarell-VF.otf glyph id 2 - let mut stems = [ - StemHint { - min: Fixed::from_bits(1376256), - max: Fixed::ZERO, - ..Default::default() - }, - StemHint { - min: Fixed::from_bits(16318464), - max: Fixed::from_bits(17563648), - ..Default::default() - }, - StemHint { - min: Fixed::from_bits(45481984), - max: Fixed::from_bits(44171264), - ..Default::default() - }, - ]; - map.build( - &state, - Some(HintMask::all()), - Some(&mut initial_map), - &mut stems, - Fixed::ZERO, - false, - ); - // FT generates the following hint map: - // - // index csCoord dsCoord scale flags - // 0 0.00 0.00 526 gbL - // 1 249.00 250.14 524 pb - // 1 268.00 238.22 592 pt - // 2 694.00 750.41 524 gtL - let expected_edges = [ - Hint { - index: 0, - cs_coord: Fixed::from_f64(0.0), - ds_coord: Fixed::from_f64(0.0), - scale: Fixed::from_bits(526), - flags: GHOST_BOTTOM | LOCKED, - }, - Hint { - index: 1, - cs_coord: Fixed::from_bits(16318464), - ds_coord: Fixed::from_bits(131072), - scale: Fixed::from_bits(524), - flags: PAIR_BOTTOM, - }, - Hint { - index: 1, - cs_coord: Fixed::from_bits(17563648), - ds_coord: Fixed::from_bits(141028), - scale: Fixed::from_bits(592), - flags: PAIR_TOP, - }, - Hint { - index: 2, - cs_coord: Fixed::from_bits(45481984), - ds_coord: Fixed::from_bits(393216), - scale: Fixed::from_bits(524), - flags: GHOST_TOP | LOCKED, - }, - ]; - assert_eq!(expected_edges, &map.edges[..map.len]); - // And FT generates the following mappings - let mappings = [ - // (coord in font units, expected hinted coord in device space) in 16.16 - (0, 0), // 0 -> 0 - (44302336, 382564), // 676 -> 5.828125 - (45481984, 393216), // 694 -> 6 - (16318464, 131072), // 249 -> 2 - (17563648, 141028), // 268 -> 2.140625 - (49676288, 426752), // 758 -> 6.5 - (56754176, 483344), // 866 -> 7.375 - (57868288, 492252), // 883 -> 7.5 - (50069504, 429896), // 764 -> 6.546875 - ]; - for (coord, expected) in mappings { - assert_eq!( - map.transform(Fixed::from_bits(coord)), - Fixed::from_bits(expected) - ); - } - } - - #[test] - fn midpoint_avoids_overflow() { - // We encountered an overflow in the HintMap::insert midpoint - // calculation for glyph id 950 at size 74 in - // KawkabMono-Bold v0.501 . - // Test that our midpoint function doesn't overflow when the sum of - // the high 16 bits of the two values exceeds i16::MAX. - let a = i16::MAX as i32; - let b = a - 1; - assert!(a + b > i16::MAX as i32); - let mid = super::midpoint(Fixed::from_i32(a), Fixed::from_i32(b)); - assert_eq!((a + b) / 2, mid.to_bits() >> 16); - } - - /// HintingSink is mostly pass-through. This test captures the logic - /// around omission of pending lines that match subpath start. - /// See HintingSink::maybe_close_subpath for details. - #[test] - fn hinting_sink_omits_closing_line_that_matches_start() { - let state = HintState { - scale: Fixed::ONE, - ..Default::default() - }; - let mut path = Path::default(); - let mut sink = HintingSink::new(&state, &mut path); - let move1_2 = [Fixed::from_f64(1.0), Fixed::from_f64(2.0)]; - let line2_3 = [Fixed::from_f64(2.0), Fixed::from_f64(3.0)]; - let line1_2 = [Fixed::from_f64(1.0), Fixed::from_f64(2.0)]; - let line3_4 = [Fixed::from_f64(3.0), Fixed::from_f64(4.0)]; - let curve = [ - Fixed::from_f64(3.0), - Fixed::from_f64(4.0), - Fixed::from_f64(5.0), - Fixed::from_f64(6.0), - Fixed::from_f64(1.0), - Fixed::from_f64(2.0), - ]; - // First subpath, closing line matches start - sink.move_to(move1_2[0], move1_2[1]); - sink.line_to(line2_3[0], line2_3[1]); - sink.line_to(line1_2[0], line1_2[1]); - // Second subpath, closing line does not match start - sink.move_to(move1_2[0], move1_2[1]); - sink.line_to(line2_3[0], line2_3[1]); - sink.line_to(line3_4[0], line3_4[1]); - // Third subpath, ends with cubic. Still emits a close command - // even though end point matches start. - sink.move_to(move1_2[0], move1_2[1]); - sink.line_to(line2_3[0], line2_3[1]); - sink.curve_to(curve[0], curve[1], curve[2], curve[3], curve[4], curve[5]); - sink.finish(); - // Subpaths always end with a close command. If a final line coincides - // with the start of a subpath, it is omitted. - assert_eq!( - &path.0, - &[ - // First subpath - MoveTo(move1_2), - LineTo(line2_3), - // line1_2 is omitted - Close, - // Second subpath - MoveTo(move1_2), - LineTo(line2_3), - LineTo(line3_4), - Close, - // Third subpath - MoveTo(move1_2), - LineTo(line2_3), - CurveTo(curve), - Close, - ] - ); - } - - #[derive(Copy, Clone, PartialEq, Debug)] - enum Command { - MoveTo([Fixed; 2]), - LineTo([Fixed; 2]), - CurveTo([Fixed; 6]), - Close, - } - - use Command::*; - - #[derive(Default)] - struct Path(Vec); - - impl CommandSink for Path { - fn move_to(&mut self, x: Fixed, y: Fixed) { - self.0.push(MoveTo([x, y])); - } - fn line_to(&mut self, x: Fixed, y: Fixed) { - self.0.push(LineTo([x, y])); - } - fn curve_to(&mut self, cx0: Fixed, cy0: Fixed, cx1: Fixed, cy1: Fixed, x: Fixed, y: Fixed) { - self.0.push(CurveTo([cx0, cy0, cx1, cy1, x, y])); - } - fn close(&mut self) { - self.0.push(Close); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,852 +0,0 @@ -//! Support for scaling CFF outlines. - -mod hint; - -use super::{GlyphHMetrics, OutlinePen}; -use hint::{HintParams, HintState, HintingSink}; -use raw::FontRef; -use read_fonts::{ - tables::{ - postscript::{ - charstring::{self, CommandSink}, - dict, BlendState, Error, FdSelect, Index, - }, - variations::ItemVariationStore, - }, - types::{F2Dot14, Fixed, GlyphId}, - FontData, FontRead, ReadError, TableProvider, -}; -use std::ops::Range; - -/// Type for loading, scaling and hinting outlines in CFF/CFF2 tables. -/// -/// The skrifa crate provides a higher level interface for this that handles -/// caching and abstracting over the different outline formats. Consider using -/// that if detailed control over resources is not required. -/// -/// # Subfonts -/// -/// CFF tables can contain multiple logical "subfonts" which determine the -/// state required for processing some subset of glyphs. This state is -/// accessed using the [`FDArray and FDSelect`](https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf#page=28) -/// operators to select an appropriate subfont for any given glyph identifier. -/// This process is exposed on this type with the -/// [`subfont_index`](Self::subfont_index) method to retrieve the subfont -/// index for the requested glyph followed by using the -/// [`subfont`](Self::subfont) method to create an appropriately configured -/// subfont for that glyph. -#[derive(Clone)] -pub(crate) struct Outlines<'a> { - pub(crate) font: FontRef<'a>, - pub(crate) glyph_metrics: GlyphHMetrics<'a>, - offset_data: FontData<'a>, - global_subrs: Index<'a>, - top_dict: TopDict<'a>, - version: u16, - units_per_em: u16, -} - -impl<'a> Outlines<'a> { - /// Creates a new scaler for the given font. - /// - /// This will choose an underlying CFF2 or CFF table from the font, in that - /// order. - pub fn new(font: &FontRef<'a>) -> Option { - let units_per_em = font.head().ok()?.units_per_em(); - Self::from_cff2(font, units_per_em).or_else(|| Self::from_cff(font, units_per_em)) - } - - pub fn from_cff(font: &FontRef<'a>, units_per_em: u16) -> Option { - let cff1 = font.cff().ok()?; - let glyph_metrics = GlyphHMetrics::new(font)?; - // "The Name INDEX in the CFF data must contain only one entry; - // that is, there must be only one font in the CFF FontSet" - // So we always pass 0 for Top DICT index when reading from an - // OpenType font. - // - let top_dict_data = cff1.top_dicts().get(0).ok()?; - let top_dict = TopDict::new(cff1.offset_data().as_bytes(), top_dict_data, false).ok()?; - Some(Self { - font: font.clone(), - glyph_metrics, - offset_data: cff1.offset_data(), - global_subrs: cff1.global_subrs().into(), - top_dict, - version: 1, - units_per_em, - }) - } - - pub fn from_cff2(font: &FontRef<'a>, units_per_em: u16) -> Option { - let cff2 = font.cff2().ok()?; - let glyph_metrics = GlyphHMetrics::new(font)?; - let table_data = cff2.offset_data().as_bytes(); - let top_dict = TopDict::new(table_data, cff2.top_dict_data(), true).ok()?; - Some(Self { - font: font.clone(), - glyph_metrics, - offset_data: cff2.offset_data(), - global_subrs: cff2.global_subrs().into(), - top_dict, - version: 2, - units_per_em, - }) - } - - pub fn is_cff2(&self) -> bool { - self.version == 2 - } - - pub fn units_per_em(&self) -> u16 { - self.units_per_em - } - - /// Returns the number of available glyphs. - pub fn glyph_count(&self) -> usize { - self.top_dict.charstrings.count() as usize - } - - /// Returns the number of available subfonts. - pub fn subfont_count(&self) -> u32 { - // All CFF fonts have at least one logical subfont. - self.top_dict.font_dicts.count().max(1) - } - - /// Returns the subfont (or Font DICT) index for the given glyph - /// identifier. - pub fn subfont_index(&self, glyph_id: GlyphId) -> u32 { - // For CFF tables, an FDSelect index will be present for CID-keyed - // fonts. Otherwise, the Top DICT will contain an entry for the - // "global" Private DICT. - // See - // - // CFF2 tables always contain a Font DICT and an FDSelect is only - // present if the size of the DICT is greater than 1. - // See - // - // In both cases, we return a subfont index of 0 when FDSelect is missing. - self.top_dict - .fd_select - .as_ref() - .and_then(|select| select.font_index(glyph_id)) - .unwrap_or(0) as u32 - } - - /// Creates a new subfont for the given index, size, normalized - /// variation coordinates and hinting state. - /// - /// The index of a subfont for a particular glyph can be retrieved with - /// the [`subfont_index`](Self::subfont_index) method. - pub fn subfont( - &self, - index: u32, - size: Option, - coords: &[F2Dot14], - ) -> Result { - let private_dict_range = self.private_dict_range(index)?; - let blend_state = self - .top_dict - .var_store - .clone() - .map(|store| BlendState::new(store, coords, 0)) - .transpose()?; - let private_dict = PrivateDict::new(self.offset_data, private_dict_range, blend_state)?; - let scale = match size { - Some(ppem) if self.units_per_em > 0 => { - // Note: we do an intermediate scale to 26.6 to ensure we - // match FreeType - Some( - Fixed::from_bits((ppem * 64.) as i32) - / Fixed::from_bits(self.units_per_em as i32), - ) - } - _ => None, - }; - // When hinting, use a modified scale factor - // - let hint_scale = Fixed::from_bits((scale.unwrap_or(Fixed::ONE).to_bits() + 32) / 64); - let hint_state = HintState::new(&private_dict.hint_params, hint_scale); - Ok(Subfont { - is_cff2: self.is_cff2(), - scale, - subrs_offset: private_dict.subrs_offset, - hint_state, - store_index: private_dict.store_index, - }) - } - - /// Loads and scales an outline for the given subfont instance, glyph - /// identifier and normalized variation coordinates. - /// - /// Before calling this method, use [`subfont_index`](Self::subfont_index) - /// to retrieve the subfont index for the desired glyph and then - /// [`subfont`](Self::subfont) to create an instance of the subfont for a - /// particular size and location in variation space. - /// Creating subfont instances is not free, so this process is exposed in - /// discrete steps to allow for caching. - /// - /// The result is emitted to the specified pen. - pub fn draw( - &self, - subfont: &Subfont, - glyph_id: GlyphId, - coords: &[F2Dot14], - hint: bool, - pen: &mut impl OutlinePen, - ) -> Result<(), Error> { - let charstring_data = self.top_dict.charstrings.get(glyph_id.to_u32() as usize)?; - let subrs = subfont.subrs(self)?; - let blend_state = subfont.blend_state(self, coords)?; - let mut pen_sink = PenSink::new(pen); - let mut simplifying_adapter = NopFilteringSink::new(&mut pen_sink); - // Only apply hinting if we have a scale - if hint && subfont.scale.is_some() { - let mut hinting_adapter = - HintingSink::new(&subfont.hint_state, &mut simplifying_adapter); - charstring::evaluate( - charstring_data, - self.global_subrs.clone(), - subrs, - blend_state, - &mut hinting_adapter, - )?; - hinting_adapter.finish(); - } else { - let mut scaling_adapter = - ScalingSink26Dot6::new(&mut simplifying_adapter, subfont.scale); - charstring::evaluate( - charstring_data, - self.global_subrs.clone(), - subrs, - blend_state, - &mut scaling_adapter, - )?; - } - simplifying_adapter.finish(); - Ok(()) - } - - fn private_dict_range(&self, subfont_index: u32) -> Result, Error> { - if self.top_dict.font_dicts.count() != 0 { - // If we have a font dict array, extract the private dict range - // from the font dict at the given index. - let font_dict_data = self.top_dict.font_dicts.get(subfont_index as usize)?; - let mut range = None; - for entry in dict::entries(font_dict_data, None) { - if let dict::Entry::PrivateDictRange(r) = entry? { - range = Some(r); - break; - } - } - range - } else { - // Use the private dict range from the top dict. - // Note: "A Private DICT is required but may be specified as having - // a length of 0 if there are no non-default values to be stored." - // - let range = self.top_dict.private_dict_range.clone(); - Some(range.start as usize..range.end as usize) - } - .ok_or(Error::MissingPrivateDict) - } -} - -/// Specifies local subroutines and hinting parameters for some subset of -/// glyphs in a CFF or CFF2 table. -/// -/// This type is designed to be cacheable to avoid re-evaluating the private -/// dict every time a charstring is processed. -/// -/// For variable fonts, this is dependent on a location in variation space. -#[derive(Clone)] -pub(crate) struct Subfont { - is_cff2: bool, - scale: Option, - subrs_offset: Option, - pub(crate) hint_state: HintState, - store_index: u16, -} - -impl Subfont { - /// Returns the local subroutine index. - pub fn subrs<'a>(&self, scaler: &Outlines<'a>) -> Result>, Error> { - if let Some(subrs_offset) = self.subrs_offset { - let offset_data = scaler.offset_data.as_bytes(); - let index_data = offset_data.get(subrs_offset..).unwrap_or_default(); - Ok(Some(Index::new(index_data, self.is_cff2)?)) - } else { - Ok(None) - } - } - - /// Creates a new blend state for the given normalized variation - /// coordinates. - pub fn blend_state<'a>( - &self, - scaler: &Outlines<'a>, - coords: &'a [F2Dot14], - ) -> Result>, Error> { - if let Some(var_store) = scaler.top_dict.var_store.clone() { - Ok(Some(BlendState::new(var_store, coords, self.store_index)?)) - } else { - Ok(None) - } - } -} - -/// Entries that we parse from the Private DICT to support charstring -/// evaluation. -#[derive(Default)] -struct PrivateDict { - hint_params: HintParams, - subrs_offset: Option, - store_index: u16, -} - -impl PrivateDict { - fn new( - data: FontData, - range: Range, - blend_state: Option>, - ) -> Result { - let private_dict_data = data.read_array(range.clone())?; - let mut dict = Self::default(); - for entry in dict::entries(private_dict_data, blend_state) { - use dict::Entry::*; - match entry? { - BlueValues(values) => dict.hint_params.blues = values, - FamilyBlues(values) => dict.hint_params.family_blues = values, - OtherBlues(values) => dict.hint_params.other_blues = values, - FamilyOtherBlues(values) => dict.hint_params.family_blues = values, - BlueScale(value) => dict.hint_params.blue_scale = value, - BlueShift(value) => dict.hint_params.blue_shift = value, - BlueFuzz(value) => dict.hint_params.blue_fuzz = value, - LanguageGroup(group) => dict.hint_params.language_group = group, - // Subrs offset is relative to the private DICT - SubrsOffset(offset) => { - dict.subrs_offset = Some( - range - .start - .checked_add(offset) - .ok_or(ReadError::OutOfBounds)?, - ) - } - VariationStoreIndex(index) => dict.store_index = index, - _ => {} - } - } - Ok(dict) - } -} - -/// Entries that we parse from the Top DICT that are required to support -/// charstring evaluation. -#[derive(Clone, Default)] -struct TopDict<'a> { - charstrings: Index<'a>, - font_dicts: Index<'a>, - fd_select: Option>, - private_dict_range: Range, - var_store: Option>, -} - -impl<'a> TopDict<'a> { - fn new(table_data: &'a [u8], top_dict_data: &'a [u8], is_cff2: bool) -> Result { - let mut items = TopDict::default(); - for entry in dict::entries(top_dict_data, None) { - match entry? { - dict::Entry::CharstringsOffset(offset) => { - items.charstrings = - Index::new(table_data.get(offset..).unwrap_or_default(), is_cff2)?; - } - dict::Entry::FdArrayOffset(offset) => { - items.font_dicts = - Index::new(table_data.get(offset..).unwrap_or_default(), is_cff2)?; - } - dict::Entry::FdSelectOffset(offset) => { - items.fd_select = Some(FdSelect::read(FontData::new( - table_data.get(offset..).unwrap_or_default(), - ))?); - } - dict::Entry::PrivateDictRange(range) => { - items.private_dict_range = range.start as u32..range.end as u32; - } - dict::Entry::VariationStoreOffset(offset) if is_cff2 => { - // IVS is preceded by a 2 byte length, but ensure that - // we don't overflow - // See - let offset = offset.checked_add(2).ok_or(ReadError::OutOfBounds)?; - items.var_store = Some(ItemVariationStore::read(FontData::new( - table_data.get(offset..).unwrap_or_default(), - ))?); - } - _ => {} - } - } - Ok(items) - } -} - -/// Command sink that sends the results of charstring evaluation to -/// an [OutlinePen]. -struct PenSink<'a, P>(&'a mut P); - -impl<'a, P> PenSink<'a, P> { - fn new(pen: &'a mut P) -> Self { - Self(pen) - } -} - -impl

    CommandSink for PenSink<'_, P> -where - P: OutlinePen, -{ - fn move_to(&mut self, x: Fixed, y: Fixed) { - self.0.move_to(x.to_f32(), y.to_f32()); - } - - fn line_to(&mut self, x: Fixed, y: Fixed) { - self.0.line_to(x.to_f32(), y.to_f32()); - } - - fn curve_to(&mut self, cx0: Fixed, cy0: Fixed, cx1: Fixed, cy1: Fixed, x: Fixed, y: Fixed) { - self.0.curve_to( - cx0.to_f32(), - cy0.to_f32(), - cx1.to_f32(), - cy1.to_f32(), - x.to_f32(), - y.to_f32(), - ); - } - - fn close(&mut self) { - self.0.close(); - } -} - -/// Command sink adapter that applies a scaling factor. -/// -/// This assumes a 26.6 scaling factor packed into a Fixed and thus, -/// this is not public and exists only to match FreeType's exact -/// scaling process. -struct ScalingSink26Dot6<'a, S> { - inner: &'a mut S, - scale: Option, -} - -impl<'a, S> ScalingSink26Dot6<'a, S> { - fn new(sink: &'a mut S, scale: Option) -> Self { - Self { scale, inner: sink } - } - - fn scale(&self, coord: Fixed) -> Fixed { - // The following dance is necessary to exactly match FreeType's - // application of scaling factors. This seems to be the result - // of merging the contributed Adobe code while not breaking the - // FreeType public API. - // - // The first two steps apply to both scaled and unscaled outlines: - // - // 1. Multiply by 1/64 - // - let a = coord * Fixed::from_bits(0x0400); - // 2. Truncate the bottom 10 bits. Combined with the division by 64, - // converts to font units. - // - let b = Fixed::from_bits(a.to_bits() >> 10); - if let Some(scale) = self.scale { - // Scaled case: - // 3. Multiply by the original scale factor (to 26.6) - // - let c = b * scale; - // 4. Convert from 26.6 to 16.16 - Fixed::from_bits(c.to_bits() << 10) - } else { - // Unscaled case: - // 3. Convert from integer to 16.16 - Fixed::from_bits(b.to_bits() << 16) - } - } -} - -impl CommandSink for ScalingSink26Dot6<'_, S> { - fn hstem(&mut self, y: Fixed, dy: Fixed) { - self.inner.hstem(y, dy); - } - - fn vstem(&mut self, x: Fixed, dx: Fixed) { - self.inner.vstem(x, dx); - } - - fn hint_mask(&mut self, mask: &[u8]) { - self.inner.hint_mask(mask); - } - - fn counter_mask(&mut self, mask: &[u8]) { - self.inner.counter_mask(mask); - } - - fn move_to(&mut self, x: Fixed, y: Fixed) { - self.inner.move_to(self.scale(x), self.scale(y)); - } - - fn line_to(&mut self, x: Fixed, y: Fixed) { - self.inner.line_to(self.scale(x), self.scale(y)); - } - - fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { - self.inner.curve_to( - self.scale(cx1), - self.scale(cy1), - self.scale(cx2), - self.scale(cy2), - self.scale(x), - self.scale(y), - ); - } - - fn close(&mut self) { - self.inner.close(); - } -} - -/// Command sink adapter that suppresses degenerate move and line commands. -/// -/// FreeType avoids emitting empty contours and zero length lines to prevent -/// artifacts when stem darkening is enabled. We don't support stem darkening -/// because it's not enabled by any of our clients but we remove the degenerate -/// elements regardless to match the output. -/// -/// See -struct NopFilteringSink<'a, S> { - start: Option<(Fixed, Fixed)>, - last: Option<(Fixed, Fixed)>, - pending_move: Option<(Fixed, Fixed)>, - inner: &'a mut S, -} - -impl<'a, S> NopFilteringSink<'a, S> -where - S: CommandSink, -{ - fn new(inner: &'a mut S) -> Self { - Self { - start: None, - last: None, - pending_move: None, - inner, - } - } - - fn flush_pending_move(&mut self) { - if let Some((x, y)) = self.pending_move.take() { - if let Some((last_x, last_y)) = self.start { - if self.last != self.start { - self.inner.line_to(last_x, last_y); - } - } - self.start = Some((x, y)); - self.last = None; - self.inner.move_to(x, y); - } - } - - pub fn finish(&mut self) { - if let Some((x, y)) = self.start { - if self.last != self.start { - self.inner.line_to(x, y); - } - self.inner.close(); - } - } -} - -impl CommandSink for NopFilteringSink<'_, S> -where - S: CommandSink, -{ - fn hstem(&mut self, y: Fixed, dy: Fixed) { - self.inner.hstem(y, dy); - } - - fn vstem(&mut self, x: Fixed, dx: Fixed) { - self.inner.vstem(x, dx); - } - - fn hint_mask(&mut self, mask: &[u8]) { - self.inner.hint_mask(mask); - } - - fn counter_mask(&mut self, mask: &[u8]) { - self.inner.counter_mask(mask); - } - - fn move_to(&mut self, x: Fixed, y: Fixed) { - self.pending_move = Some((x, y)); - } - - fn line_to(&mut self, x: Fixed, y: Fixed) { - if self.pending_move == Some((x, y)) { - return; - } - self.flush_pending_move(); - if self.last == Some((x, y)) || (self.last.is_none() && self.start == Some((x, y))) { - return; - } - self.inner.line_to(x, y); - self.last = Some((x, y)); - } - - fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { - self.flush_pending_move(); - self.last = Some((x, y)); - self.inner.curve_to(cx1, cy1, cx2, cy2, x, y); - } - - fn close(&mut self) { - if self.pending_move.is_none() { - self.inner.close(); - self.start = None; - self.last = None; - } - } -} - -#[cfg(test)] -mod tests { - use super::{super::pen::SvgPen, *}; - use crate::{ - outline::{HintingInstance, HintingOptions}, - prelude::{LocationRef, Size}, - MetadataProvider, - }; - use raw::tables::cff2::Cff2; - use read_fonts::{test_helpers::BeBuffer, FontRef}; - - #[test] - fn unscaled_scaling_sink_produces_integers() { - let nothing = &mut (); - let sink = ScalingSink26Dot6::new(nothing, None); - for coord in [50.0, 50.1, 50.125, 50.5, 50.9] { - assert_eq!(sink.scale(Fixed::from_f64(coord)).to_f32(), 50.0); - } - } - - #[test] - fn scaled_scaling_sink() { - let ppem = 20.0; - let upem = 1000.0; - // match FreeType scaling with intermediate conversion to 26.6 - let scale = Fixed::from_bits((ppem * 64.) as i32) / Fixed::from_bits(upem as i32); - let nothing = &mut (); - let sink = ScalingSink26Dot6::new(nothing, Some(scale)); - let inputs = [ - // input coord, expected scaled output - (0.0, 0.0), - (8.0, 0.15625), - (16.0, 0.3125), - (32.0, 0.640625), - (72.0, 1.4375), - (128.0, 2.5625), - ]; - for (coord, expected) in inputs { - assert_eq!( - sink.scale(Fixed::from_f64(coord)).to_f32(), - expected, - "scaling coord {coord}" - ); - } - } - - #[test] - fn read_cff_static() { - let font = FontRef::new(font_test_data::NOTO_SERIF_DISPLAY_TRIMMED).unwrap(); - let cff = Outlines::new(&font).unwrap(); - assert!(!cff.is_cff2()); - assert!(cff.top_dict.var_store.is_none()); - assert!(cff.top_dict.font_dicts.count() == 0); - assert!(!cff.top_dict.private_dict_range.is_empty()); - assert!(cff.top_dict.fd_select.is_none()); - assert_eq!(cff.subfont_count(), 1); - assert_eq!(cff.subfont_index(GlyphId::new(1)), 0); - assert_eq!(cff.global_subrs.count(), 17); - } - - #[test] - fn read_cff2_static() { - let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); - let cff = Outlines::new(&font).unwrap(); - assert!(cff.is_cff2()); - assert!(cff.top_dict.var_store.is_some()); - assert!(cff.top_dict.font_dicts.count() != 0); - assert!(cff.top_dict.private_dict_range.is_empty()); - assert!(cff.top_dict.fd_select.is_none()); - assert_eq!(cff.subfont_count(), 1); - assert_eq!(cff.subfont_index(GlyphId::new(1)), 0); - assert_eq!(cff.global_subrs.count(), 0); - } - - #[test] - fn read_example_cff2_table() { - let cff2 = Cff2::read(FontData::new(font_test_data::cff2::EXAMPLE)).unwrap(); - let top_dict = - TopDict::new(cff2.offset_data().as_bytes(), cff2.top_dict_data(), true).unwrap(); - assert!(top_dict.var_store.is_some()); - assert!(top_dict.font_dicts.count() != 0); - assert!(top_dict.private_dict_range.is_empty()); - assert!(top_dict.fd_select.is_none()); - assert_eq!(cff2.global_subrs().count(), 0); - } - - #[test] - fn cff2_variable_outlines_match_freetype() { - compare_glyphs( - font_test_data::CANTARELL_VF_TRIMMED, - font_test_data::CANTARELL_VF_TRIMMED_GLYPHS, - ); - } - - #[test] - fn cff_static_outlines_match_freetype() { - compare_glyphs( - font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, - font_test_data::NOTO_SERIF_DISPLAY_TRIMMED_GLYPHS, - ); - } - - #[test] - fn unhinted_ends_with_close() { - let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); - let glyph = font.outline_glyphs().get(GlyphId::new(1)).unwrap(); - let mut svg = SvgPen::default(); - glyph.draw(Size::unscaled(), &mut svg).unwrap(); - assert!(svg.to_string().ends_with('Z')); - } - - #[test] - fn hinted_ends_with_close() { - let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); - let glyphs = font.outline_glyphs(); - let hinter = HintingInstance::new( - &glyphs, - Size::unscaled(), - LocationRef::default(), - HintingOptions::default(), - ) - .unwrap(); - let glyph = glyphs.get(GlyphId::new(1)).unwrap(); - let mut svg = SvgPen::default(); - glyph.draw(&hinter, &mut svg).unwrap(); - assert!(svg.to_string().ends_with('Z')); - } - - /// Ensure we don't reject an empty Private DICT - #[test] - fn empty_private_dict() { - let font = FontRef::new(font_test_data::MATERIAL_ICONS_SUBSET).unwrap(); - let outlines = super::Outlines::new(&font).unwrap(); - assert!(outlines.top_dict.private_dict_range.is_empty()); - assert!(outlines.private_dict_range(0).unwrap().is_empty()); - } - - /// Fuzzer caught add with overflow when computing subrs offset. - /// See - #[test] - fn subrs_offset_overflow() { - // A private DICT with an overflowing subrs offset - let private_dict = BeBuffer::new() - .push(0u32) // pad so that range doesn't start with 0 and we overflow - .push(29u8) // integer operator - .push(-1i32) // integer value - .push(19u8) // subrs offset operator - .to_vec(); - // Just don't panic with overflow - assert!( - PrivateDict::new(FontData::new(&private_dict), 4..private_dict.len(), None).is_err() - ); - } - - // Fuzzer caught add with overflow when computing offset to - // var store. - // See - #[test] - fn top_dict_ivs_offset_overflow() { - // A top DICT with a var store offset of -1 which will cause an - // overflow - let top_dict = BeBuffer::new() - .push(29u8) // integer operator - .push(-1i32) // integer value - .push(24u8) // var store offset operator - .to_vec(); - // Just don't panic with overflow - assert!(TopDict::new(&[], &top_dict, true).is_err()); - } - - /// Actually apply a scale when the computed scale factor is - /// equal to Fixed::ONE. - /// - /// Specifically, when upem = 512 and ppem = 8, this results in - /// a scale factor of 65536 which was being interpreted as an - /// unscaled draw request. - #[test] - fn proper_scaling_when_factor_equals_fixed_one() { - let font = FontRef::new(font_test_data::MATERIAL_ICONS_SUBSET).unwrap(); - assert_eq!(font.head().unwrap().units_per_em(), 512); - let glyphs = font.outline_glyphs(); - let glyph = glyphs.get(GlyphId::new(1)).unwrap(); - let mut svg = SvgPen::with_precision(6); - glyph - .draw((Size::new(8.0), LocationRef::default()), &mut svg) - .unwrap(); - // This was initially producing unscaled values like M405.000... - assert!(svg.starts_with("M6.328125,7.000000 L1.671875,7.000000")); - } - - /// For the given font data and extracted outlines, parse the extracted - /// outline data into a set of expected values and compare these with the - /// results generated by the scaler. - /// - /// This will compare all outlines at various sizes and (for variable - /// fonts), locations in variation space. - fn compare_glyphs(font_data: &[u8], expected_outlines: &str) { - use super::super::testing; - let font = FontRef::new(font_data).unwrap(); - let expected_outlines = testing::parse_glyph_outlines(expected_outlines); - let outlines = super::Outlines::new(&font).unwrap(); - let mut path = testing::Path::default(); - for expected_outline in &expected_outlines { - if expected_outline.size == 0.0 && !expected_outline.coords.is_empty() { - continue; - } - let size = (expected_outline.size != 0.0).then_some(expected_outline.size); - path.elements.clear(); - let subfont = outlines - .subfont( - outlines.subfont_index(expected_outline.glyph_id), - size, - &expected_outline.coords, - ) - .unwrap(); - outlines - .draw( - &subfont, - expected_outline.glyph_id, - &expected_outline.coords, - false, - &mut path, - ) - .unwrap(); - if path.elements != expected_outline.path { - panic!( - "mismatch in glyph path for id {} (size: {}, coords: {:?}): path: {:?} expected_path: {:?}", - expected_outline.glyph_id, - expected_outline.size, - expected_outline.coords, - &path.elements, - &expected_outline.path - ); - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,86 +0,0 @@ -//! Error types associated with outlines. - -use core::fmt; -use read_fonts::types::GlyphId; - -pub use read_fonts::{tables::postscript::Error as CffError, ReadError}; - -pub use super::glyf::HintError; -pub use super::path::ToPathError; - -/// Errors that may occur when drawing glyphs. -#[derive(Clone, Debug)] -pub enum DrawError { - /// No viable sources were available. - NoSources, - /// The requested glyph was not present in the font. - GlyphNotFound(GlyphId), - /// Exceeded memory limits when loading a glyph. - InsufficientMemory, - /// Exceeded a recursion limit when loading a glyph. - RecursionLimitExceeded(GlyphId), - /// Error occurred during hinting. - HintingFailed(HintError), - /// An anchor point had invalid indices. - InvalidAnchorPoint(GlyphId, u16), - /// Error occurred while loading a PostScript (CFF/CFF2) glyph. - PostScript(CffError), - /// Conversion from outline to path failed. - ToPath(ToPathError), - /// Error occurred when reading font data. - Read(ReadError), - /// HarfBuzz style drawing with hints is not supported - // Error rather than silently returning unhinted per f2f discussion. - HarfBuzzHintingUnsupported, -} - -impl From for DrawError { - fn from(value: HintError) -> Self { - Self::HintingFailed(value) - } -} - -impl From for DrawError { - fn from(e: ToPathError) -> Self { - Self::ToPath(e) - } -} - -impl From for DrawError { - fn from(e: ReadError) -> Self { - Self::Read(e) - } -} - -impl From for DrawError { - fn from(value: CffError) -> Self { - Self::PostScript(value) - } -} - -impl fmt::Display for DrawError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::NoSources => write!(f, "No glyph sources are available for the given font"), - Self::GlyphNotFound(gid) => write!(f, "Glyph {gid} was not found in the given font"), - Self::InsufficientMemory => write!(f, "exceeded memory limits"), - Self::RecursionLimitExceeded(gid) => write!( - f, - "Recursion limit ({}) exceeded when loading composite component {gid}", - super::GLYF_COMPOSITE_RECURSION_LIMIT, - ), - Self::HintingFailed(e) => write!(f, "{e}"), - Self::InvalidAnchorPoint(gid, index) => write!( - f, - "Invalid anchor point index ({index}) for composite glyph {gid}", - ), - Self::PostScript(e) => write!(f, "{e}"), - Self::ToPath(e) => write!(f, "{e}"), - Self::Read(e) => write!(f, "{e}"), - Self::HarfBuzzHintingUnsupported => write!( - f, - "HarfBuzz style paths with hinting is not (yet?) supported" - ), - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,387 +0,0 @@ -use core::ops::RangeInclusive; - -use raw::tables::glyf::PointCoord; -use read_fonts::{ - tables::glyf::{PointFlags, PointMarker}, - tables::gvar::{GlyphDelta, Gvar}, - tables::variations::TupleVariation, - types::{F2Dot14, Fixed, GlyphId, Point}, - ReadError, -}; - -use super::PHANTOM_POINT_COUNT; - -#[derive(Copy, Clone, Debug)] -pub(super) enum AvailableVarMetrics { - /// Full variable metrics with advances and side-bearings. - All, - /// Variable advances but not side-bearings. - Advances, - /// No variable metrics table. - None, -} - -/// Compute a set of deltas for the component offsets of a composite glyph. -/// -/// Interpolation is meaningless for component offsets so this is a -/// specialized function that skips the expensive bits. -pub(super) fn composite_glyph( - gvar: &Gvar, - glyph_id: GlyphId, - coords: &[F2Dot14], - deltas: &mut [Point], -) -> Result<(), ReadError> { - compute_deltas_for_glyph(gvar, glyph_id, coords, deltas, |scalar, tuple, deltas| { - for tuple_delta in tuple.deltas() { - let ix = tuple_delta.position as usize; - if let Some(delta) = deltas.get_mut(ix) { - *delta += tuple_delta.apply_scalar(scalar); - } - } - Ok(()) - })?; - Ok(()) -} - -pub(super) struct SimpleGlyph<'a, C: PointCoord> { - pub points: &'a [Point], - pub flags: &'a mut [PointFlags], - pub contours: &'a [u16], -} - -/// Compute a set of deltas for the points in a simple glyph. -/// -/// This function will use interpolation to infer missing deltas for tuples -/// that contain sparse sets. The `iup_buffer` buffer is temporary storage -/// used for this and the length must be >= glyph.points.len(). -pub(super) fn simple_glyph( - gvar: &Gvar, - glyph_id: GlyphId, - coords: &[F2Dot14], - var_metrics: AvailableVarMetrics, - glyph: SimpleGlyph, - iup_buffer: &mut [Point], - deltas: &mut [Point], -) -> Result<(), ReadError> -where - C: PointCoord, - D: PointCoord, - D: From, -{ - if iup_buffer.len() < glyph.points.len() || glyph.points.len() < PHANTOM_POINT_COUNT { - return Err(ReadError::InvalidArrayLen); - } - for delta in deltas.iter_mut() { - *delta = Default::default(); - } - if gvar.glyph_variation_data(glyph_id).is_err() { - // Empty variation data for a glyph is not an error. - return Ok(()); - }; - let SimpleGlyph { - points, - flags, - contours, - } = glyph; - // Determine which phantom points to modify based on the presence and - // content of the HVAR table. - let actual_len = match var_metrics { - // Modify LSB and advance - AvailableVarMetrics::None => points.len() - 2, - // Modify only LSB - AvailableVarMetrics::Advances => points.len() - 3, - // Modify nothing - AvailableVarMetrics::All => points.len() - PHANTOM_POINT_COUNT, - }; - let deltas = &mut deltas[..actual_len]; - compute_deltas_for_glyph(gvar, glyph_id, coords, deltas, |scalar, tuple, deltas| { - // Infer missing deltas by interpolation. - // Prepare our working buffer by converting the points to 16.16 - // and clearing the HAS_DELTA flags. - for ((flag, point), iup_point) in flags.iter_mut().zip(points).zip(&mut iup_buffer[..]) { - *iup_point = point.map(D::from); - flag.clear_marker(PointMarker::HAS_DELTA); - } - for tuple_delta in tuple.deltas() { - let ix = tuple_delta.position as usize; - if let (Some(flag), Some(point)) = (flags.get_mut(ix), iup_buffer.get_mut(ix)) { - flag.set_marker(PointMarker::HAS_DELTA); - *point += tuple_delta.apply_scalar(scalar); - } - } - interpolate_deltas(points, flags, contours, &mut iup_buffer[..]) - .ok_or(ReadError::OutOfBounds)?; - for ((delta, point), iup_point) in deltas.iter_mut().zip(points).zip(iup_buffer.iter()) { - *delta += *iup_point - point.map(D::from); - } - Ok(()) - })?; - Ok(()) -} - -/// The common parts of simple and complex glyph processing -fn compute_deltas_for_glyph( - gvar: &Gvar, - glyph_id: GlyphId, - coords: &[F2Dot14], - deltas: &mut [Point], - mut apply_tuple_missing_deltas_fn: impl FnMut( - Fixed, - TupleVariation, - &mut [Point], - ) -> Result<(), ReadError>, -) -> Result<(), ReadError> -where - C: PointCoord, - D: PointCoord, - D: From, -{ - for delta in deltas.iter_mut() { - *delta = Default::default(); - } - let Ok(var_data) = gvar.glyph_variation_data(glyph_id) else { - // Empty variation data for a glyph is not an error. - return Ok(()); - }; - for (tuple, scalar) in var_data.active_tuples_at(coords) { - // Fast path: tuple contains all points, we can simply accumulate - // the deltas directly. - if tuple.has_deltas_for_all_points() { - for (delta, tuple_delta) in deltas.iter_mut().zip(tuple.deltas()) { - *delta += tuple_delta.apply_scalar(scalar); - } - } else { - // Slow path is, annoyingly, different for simple vs composite - // so let the caller handle it - apply_tuple_missing_deltas_fn(scalar, tuple, deltas)?; - } - } - Ok(()) -} - -/// Interpolate points without delta values, similar to the IUP hinting -/// instruction. -/// -/// Modeled after the FreeType implementation: -/// -fn interpolate_deltas( - points: &[Point], - flags: &[PointFlags], - contours: &[u16], - out_points: &mut [Point], -) -> Option<()> -where - C: PointCoord, - D: PointCoord, - D: From, -{ - let mut jiggler = Jiggler { points, out_points }; - let mut point_ix = 0usize; - for &end_point_ix in contours { - let end_point_ix = end_point_ix as usize; - let first_point_ix = point_ix; - // Search for first point that has a delta. - while point_ix <= end_point_ix && !flags.get(point_ix)?.has_marker(PointMarker::HAS_DELTA) { - point_ix += 1; - } - // If we didn't find any deltas, no variations in the current tuple - // apply, so skip it. - if point_ix > end_point_ix { - continue; - } - let first_delta_ix = point_ix; - let mut cur_delta_ix = point_ix; - point_ix += 1; - // Search for next point that has a delta... - while point_ix <= end_point_ix { - if flags.get(point_ix)?.has_marker(PointMarker::HAS_DELTA) { - // ... and interpolate intermediate points. - jiggler.interpolate( - cur_delta_ix + 1..=point_ix - 1, - RefPoints(cur_delta_ix, point_ix), - )?; - cur_delta_ix = point_ix; - } - point_ix += 1; - } - // If we only have a single delta, shift the contour. - if cur_delta_ix == first_delta_ix { - jiggler.shift(first_point_ix..=end_point_ix, cur_delta_ix)?; - } else { - // Otherwise, handle remaining points at beginning and end of - // contour. - jiggler.interpolate( - cur_delta_ix + 1..=end_point_ix, - RefPoints(cur_delta_ix, first_delta_ix), - )?; - if first_delta_ix > 0 { - jiggler.interpolate( - first_point_ix..=first_delta_ix - 1, - RefPoints(cur_delta_ix, first_delta_ix), - )?; - } - } - } - Some(()) -} - -struct RefPoints(usize, usize); - -struct Jiggler<'a, C, D> -where - C: PointCoord, - D: PointCoord, - D: From, -{ - points: &'a [Point], - out_points: &'a mut [Point], -} - -impl Jiggler<'_, C, D> -where - C: PointCoord, - D: PointCoord, - D: From, -{ - /// Shift the coordinates of all points in the specified range using the - /// difference given by the point at `ref_ix`. - /// - /// Modeled after the FreeType implementation: - fn shift(&mut self, range: RangeInclusive, ref_ix: usize) -> Option<()> { - let ref_in = self.points.get(ref_ix)?.map(D::from); - let ref_out = self.out_points.get(ref_ix)?; - let delta = *ref_out - ref_in; - if delta.x == D::zeroed() && delta.y == D::zeroed() { - return Some(()); - } - // Apply the reference point delta to the entire range excluding the - // reference point itself which would apply the delta twice. - for out_point in self.out_points.get_mut(*range.start()..ref_ix)? { - *out_point += delta; - } - for out_point in self.out_points.get_mut(ref_ix + 1..=*range.end())? { - *out_point += delta; - } - Some(()) - } - - /// Interpolate the coordinates of all points in the specified range using - /// `ref1_ix` and `ref2_ix` as the reference point indices. - /// - /// Modeled after the FreeType implementation: - /// - /// For details on the algorithm, see: - fn interpolate(&mut self, range: RangeInclusive, ref_points: RefPoints) -> Option<()> { - if range.is_empty() { - return Some(()); - } - // FreeType uses pointer tricks to handle x and y coords with a single piece of code. - // Try a macro instead. - macro_rules! interp_coord { - ($coord:ident) => { - let RefPoints(mut ref1_ix, mut ref2_ix) = ref_points; - if self.points.get(ref1_ix)?.$coord > self.points.get(ref2_ix)?.$coord { - core::mem::swap(&mut ref1_ix, &mut ref2_ix); - } - let in1 = D::from(self.points.get(ref1_ix)?.$coord); - let in2 = D::from(self.points.get(ref2_ix)?.$coord); - let out1 = self.out_points.get(ref1_ix)?.$coord; - let out2 = self.out_points.get(ref2_ix)?.$coord; - // If the reference points have the same coordinate but different delta, - // inferred delta is zero. Otherwise interpolate. - if in1 != in2 || out1 == out2 { - let scale = if in1 != in2 { - (out2 - out1) / (in2 - in1) - } else { - D::zeroed() - }; - let d1 = out1 - in1; - let d2 = out2 - in2; - for (point, out_point) in self - .points - .get(range.clone())? - .iter() - .zip(self.out_points.get_mut(range.clone())?) - { - let mut out = D::from(point.$coord); - if out <= in1 { - out += d1; - } else if out >= in2 { - out += d2; - } else { - out = out1 + (out - in1) * scale; - } - out_point.$coord = out; - } - } - }; - } - interp_coord!(x); - interp_coord!(y); - Some(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn make_points(tuples: &[(i32, i32)]) -> Vec> { - tuples.iter().map(|&(x, y)| Point::new(x, y)).collect() - } - - fn make_working_points_and_flags( - points: &[Point], - deltas: &[Point], - ) -> (Vec>, Vec) { - let working_points = points - .iter() - .zip(deltas) - .map(|(point, delta)| point.map(Fixed::from_i32) + delta.map(Fixed::from_i32)) - .collect(); - let flags = deltas - .iter() - .map(|delta| { - let mut flags = PointFlags::default(); - if delta.x != 0 || delta.y != 0 { - flags.set_marker(PointMarker::HAS_DELTA); - } - flags - }) - .collect(); - (working_points, flags) - } - - #[test] - fn shift() { - let points = make_points(&[(245, 630), (260, 700), (305, 680)]); - // Single delta triggers a full contour shift. - let deltas = make_points(&[(20, -10), (0, 0), (0, 0)]); - let (mut working_points, flags) = make_working_points_and_flags(&points, &deltas); - interpolate_deltas(&points, &flags, &[2], &mut working_points).unwrap(); - let expected = &[ - Point::new(265, 620).map(Fixed::from_i32), - Point::new(280, 690).map(Fixed::from_i32), - Point::new(325, 670).map(Fixed::from_i32), - ]; - assert_eq!(&working_points, expected); - } - - #[test] - fn interpolate() { - // Test taken from the spec: - // https://learn.microsoft.com/en-us/typography/opentype/spec/gvar#inferred-deltas-for-un-referenced-point-numbers - // with a minor adjustment to account for the precision of our fixed point math. - let points = make_points(&[(245, 630), (260, 700), (305, 680)]); - let deltas = make_points(&[(28, -62), (0, 0), (-42, -57)]); - let (mut working_points, flags) = make_working_points_and_flags(&points, &deltas); - interpolate_deltas(&points, &flags, &[2], &mut working_points).unwrap(); - assert_eq!( - working_points[1], - Point::new( - Fixed::from_f64(260.0 + 10.4999237060547), - Fixed::from_f64(700.0 - 57.0) - ) - ); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -//! Tracking function call state. - -use super::{definition::Definition, error::HintErrorKind, program::Program}; - -// FreeType provides a call stack with a depth of 32. -// See -const MAX_DEPTH: usize = 32; - -/// Record of an active invocation of a function or instruction -/// definition. -/// -/// See -#[derive(Copy, Clone, Default)] -pub struct CallRecord { - pub caller_program: Program, - pub return_pc: usize, - pub current_count: u32, - pub definition: Definition, -} - -/// Tracker for nested active function or instruction calls. -#[derive(Default)] -pub struct CallStack { - records: [CallRecord; MAX_DEPTH], - len: usize, -} - -impl CallStack { - pub fn clear(&mut self) { - self.len = 0; - } - - pub fn push(&mut self, record: CallRecord) -> Result<(), HintErrorKind> { - let top = self - .records - .get_mut(self.len) - .ok_or(HintErrorKind::CallStackOverflow)?; - *top = record; - self.len += 1; - Ok(()) - } - - pub fn peek(&self) -> Option<&CallRecord> { - self.records.get(self.len.checked_sub(1)?) - } - - pub fn pop(&mut self) -> Result { - let record = *self.peek().ok_or(HintErrorKind::CallStackUnderflow)?; - self.len -= 1; - Ok(record) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn stack_overflow() { - let mut stack = CallStack::default(); - for i in 0..MAX_DEPTH { - stack.push(record_with_key(i)).unwrap(); - } - assert!(matches!( - stack.push(CallRecord::default()), - Err(HintErrorKind::CallStackOverflow) - )); - } - - #[test] - fn stack_underflow() { - assert!(matches!( - CallStack::default().pop(), - Err(HintErrorKind::CallStackUnderflow) - )); - } - - #[test] - fn stack_push_pop() { - let mut stack = CallStack::default(); - for i in 0..MAX_DEPTH { - stack.push(record_with_key(i)).unwrap(); - } - for i in (0..MAX_DEPTH).rev() { - assert_eq!(stack.pop().unwrap().definition.key(), i as i32); - } - } - - fn record_with_key(key: usize) -> CallRecord { - CallRecord { - caller_program: Program::Glyph, - return_pc: 0, - current_count: 1, - definition: Definition::new(Program::Font, 0..0, key as i32), - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -//! Copy-on-write buffer for CVT and storage area. - -/// Backing store for the CVT and storage area. -/// -/// The CVT and storage area are initialized in the control value program -/// with values that are relevant to a particular size and hinting -/// configuration. However, some fonts contain code in glyph programs -/// that write to these buffers. Any modifications made in a glyph program -/// should not affect future glyphs and thus should not persist beyond -/// execution of that program. To solve this problem, a copy of the buffer -/// is made on the first write in a glyph program and all changes are -/// discarded on completion. -/// -/// For more context, see -/// -/// # Implementation notes -/// -/// The current implementation defers the copy but not the allocation. This -/// is to support the guarantee of no heap allocation when operating on user -/// provided memory. Investigation of hinted Noto fonts suggests that writing -/// to CVT/Storage in glyph programs is common for ttfautohinted fonts so the -/// speculative allocation is likely worthwhile. -pub struct CowSlice<'a> { - data: &'a [i32], - data_mut: &'a mut [i32], - /// True if we've initialized the mutable slice - use_mut: bool, -} - -impl<'a> CowSlice<'a> { - /// Creates a new copy-on-write slice with the given buffers. - /// - /// The `data` buffer is expected to contain the initial data and the content - /// of `data_mut` is ignored unless the [`set`](Self::set) method is called - /// in which case a copy will be made from `data` to `data_mut` and the - /// mutable buffer will be used for all further access. - /// - /// Returns [`CowSliceSizeMismatchError`] if `data.len() != data_mut.len()`. - pub fn new( - data: &'a [i32], - data_mut: &'a mut [i32], - ) -> Result { - if data.len() != data_mut.len() { - return Err(CowSliceSizeMismatchError(data.len(), data_mut.len())); - } - Ok(Self { - data, - data_mut, - use_mut: false, - }) - } - - /// Creates a new copy-on-write slice with the given mutable buffer. - /// - /// This avoids an extra copy and allocation in contexts where the data is - /// already assumed to be mutable (i.e. when executing `fpgm` and `prep` - /// programs). - pub fn new_mut(data_mut: &'a mut [i32]) -> Self { - Self { - use_mut: true, - data: &[], - data_mut, - } - } - - /// Returns the value at the given index. - /// - /// If mutable data has been initialized, reads from that buffer. Otherwise - /// reads from the immutable buffer. - pub fn get(&self, index: usize) -> Option { - if self.use_mut { - self.data_mut.get(index).copied() - } else { - self.data.get(index).copied() - } - } - - /// Writes a value to the given index. - /// - /// If the mutable buffer hasn't been initialized, first performs a full - /// buffer copy. - pub fn set(&mut self, index: usize, value: i32) -> Option<()> { - // Copy from immutable to mutable buffer if we haven't already - if !self.use_mut { - self.data_mut.copy_from_slice(self.data); - self.use_mut = true; - } - *self.data_mut.get_mut(index)? = value; - Some(()) - } - - pub fn len(&self) -> usize { - if self.use_mut { - self.data_mut.len() - } else { - self.data.len() - } - } -} - -/// Error returned when the sizes of the immutable and mutable buffers -/// mismatch when constructing a [`CowSlice`]. -#[derive(Clone, Debug)] -pub struct CowSliceSizeMismatchError(usize, usize); - -impl std::fmt::Display for CowSliceSizeMismatchError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "size mismatch for immutable and mutable buffers: data.len() = {}, data_mut.len() = {}", - self.0, self.1 - ) - } -} - -#[cfg(test)] -mod tests { - use super::{CowSlice, CowSliceSizeMismatchError}; - - #[test] - fn size_mismatch_error() { - let data_mut = &mut [0, 0]; - let result = CowSlice::new(&[1, 2, 3], data_mut); - assert!(matches!(result, Err(CowSliceSizeMismatchError(3, 2)))) - } - - #[test] - fn copy_on_write() { - let data = std::array::from_fn::<_, 16, _>(|i| i as i32); - let mut data_mut = [0i32; 16]; - let mut slice = CowSlice::new(&data, &mut data_mut).unwrap(); - // Not mutable yet - assert!(!slice.use_mut); - for i in 0..data.len() { - assert_eq!(slice.get(i).unwrap(), i as i32); - } - // Modify all values - for i in 0..data.len() { - let value = slice.get(i).unwrap(); - slice.set(i, value * 2).unwrap(); - } - // Now we're mutable - assert!(slice.use_mut); - for i in 0..data.len() { - assert_eq!(slice.get(i).unwrap(), i as i32 * 2); - } - } - - #[test] - fn out_of_bounds() { - let data_mut = &mut [1, 2]; - let slice = CowSlice::new_mut(data_mut); - assert_eq!(slice.get(0), Some(1)); - assert_eq!(slice.get(1), Some(2)); - assert_eq!(slice.get(2), None); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -//! Control value table. - -use super::{cow_slice::CowSlice, error::HintErrorKind, F26Dot6}; - -/// Backing store for the control value table. -/// -/// This is just a wrapper for [`CowSlice`] that converts out of bounds -/// accesses to appropriate errors. -pub struct Cvt<'a>(CowSlice<'a>); - -impl Cvt<'_> { - pub fn get(&self, index: usize) -> Result { - self.0 - .get(index) - .map(F26Dot6::from_bits) - .ok_or(HintErrorKind::InvalidCvtIndex(index)) - } - - pub fn set(&mut self, index: usize, value: F26Dot6) -> Result<(), HintErrorKind> { - self.0 - .set(index, value.to_bits()) - .ok_or(HintErrorKind::InvalidCvtIndex(index)) - } - - pub fn len(&self) -> usize { - self.0.len() - } -} - -impl<'a> From> for Cvt<'a> { - fn from(value: CowSlice<'a>) -> Self { - Self(value) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,265 +0,0 @@ -//! Management of function and instruction definitions. - -use core::ops::Range; - -use super::{error::HintErrorKind, program::Program}; - -/// Code range and properties for a function or instruction definition. -// Note: this type is designed to support allocation from user memory -// so make sure the fields are all tightly packed and only use integral -// types. -// See -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -#[repr(C)] -pub struct Definition { - start: u32, - end: u32, - /// The function number for an FDEF or opcode for an IDEF. - key: i32, - _pad: u16, - program: u8, - is_active: u8, -} - -impl Definition { - /// Creates a new definition with the given program, code range and - /// key. - /// - /// The key is either a function number or opcode for function and - /// instruction definitions respectively. - pub fn new(program: Program, code_range: Range, key: i32) -> Self { - Self { - program: program as u8, - // Table sizes are specified in u32 so valid ranges will - // always fit. - start: code_range.start as u32, - end: code_range.end as u32, - key, - _pad: 0, - is_active: 1, - } - } - - /// Returns the program that contains this definition. - pub fn program(&self) -> Program { - match self.program { - 0 => Program::Font, - 1 => Program::ControlValue, - _ => Program::Glyph, - } - } - - /// Returns the function number or opcode. - #[cfg(test)] - pub fn key(&self) -> i32 { - self.key - } - - /// Returns the byte range of the code for this definition in the source - /// program. - pub fn code_range(&self) -> Range { - self.start as usize..self.end as usize - } - - /// Returns true if this definition entry has been defined by a program. - pub fn is_active(&self) -> bool { - self.is_active != 0 - } -} - -/// Map of function number or opcode to code definitions. -/// -/// The `Ref` vs `Mut` distinction exists because these can be modified -/// from the font and control value programs but not from a glyph program. -/// In addition, hinting instance state is immutable once initialized so -/// this captures that in a type safe way. -pub enum DefinitionMap<'a> { - Ref(&'a [Definition]), - Mut(&'a mut [Definition]), -} - -impl DefinitionMap<'_> { - /// Attempts to allocate a new definition entry with the given key. - /// - /// Overriding a definition is legal, so if an existing active entry - /// is found with the same key, that one will be returned. Otherwise, - /// an inactive entry will be chosen. - pub fn allocate(&mut self, key: i32) -> Result<&mut Definition, HintErrorKind> { - let Self::Mut(defs) = self else { - return Err(HintErrorKind::DefinitionInGlyphProgram); - }; - // First, see if we can use key as an index. - // - // For function definitions in well-behaved fonts (that is, where - // function numbers fall within 0..max_function_defs) this will - // always work. - // - // For instruction definitions, this will likely never work - // because the number of instruction definitions is usually small - // (nearly always 0) and the available opcodes are in the higher - // ranges of u8 space. - let ix = if defs - .get(key as usize) - .filter(|def| !def.is_active() || def.key == key) - .is_some() - { - // If the entry is inactive or the key matches, we're good. - key as usize - } else { - // Otherwise, walk backward looking for an active entry with - // a matching key. Keep track of the inactive entry with the - // highest index. - let mut last_inactive_ix = None; - for (i, def) in defs.iter().enumerate().rev() { - if def.is_active() { - if def.key == key { - last_inactive_ix = Some(i); - break; - } - } else if last_inactive_ix.is_none() { - last_inactive_ix = Some(i); - } - } - last_inactive_ix.ok_or(HintErrorKind::TooManyDefinitions)? - }; - let def = defs.get_mut(ix).ok_or(HintErrorKind::TooManyDefinitions)?; - *def = Definition::new(Program::Font, 0..0, key); - Ok(def) - } - - /// Returns the definition with the given key. - pub fn get(&self, key: i32) -> Result<&Definition, HintErrorKind> { - let defs = match self { - Self::Mut(defs) => *defs, - Self::Ref(defs) => *defs, - }; - // Fast path, try to use key as index. - if let Some(def) = defs.get(key as usize) { - if def.is_active() && def.key == key { - return Ok(def); - } - } - // Otherwise, walk backward doing a linear search. - for def in defs.iter().rev() { - if def.is_active() && def.key == key { - return Ok(def); - } - } - Err(HintErrorKind::InvalidDefinition(key as _)) - } - - /// Returns a reference to the underlying definition slice. - #[cfg(test)] - fn as_slice(&self) -> &[Definition] { - match self { - Self::Ref(defs) => defs, - Self::Mut(defs) => defs, - } - } - - /// If the map is mutable, resets all definitions to the default - /// value. - pub fn reset(&mut self) { - if let Self::Mut(defs) = self { - defs.fill(Default::default()) - } - } -} - -/// State containing font defined functions and instructions. -pub struct DefinitionState<'a> { - pub functions: DefinitionMap<'a>, - pub instructions: DefinitionMap<'a>, -} - -impl<'a> DefinitionState<'a> { - pub fn new(functions: DefinitionMap<'a>, instructions: DefinitionMap<'a>) -> Self { - Self { - functions, - instructions, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn too_many_and_invalid() { - let mut buf = vec![Default::default(); 32]; - let mut map = DefinitionMap::Mut(&mut buf); - for i in 0..32 { - map.allocate(i).unwrap(); - } - assert!(matches!( - map.allocate(33), - Err(HintErrorKind::TooManyDefinitions) - )); - assert!(matches!( - map.get(33), - Err(HintErrorKind::InvalidDefinition(33)) - )); - } - - /// Test dense allocation where all keys map directly to indices. This is - /// the case for function definitions in well behaved fonts. - #[test] - fn allocate_dense() { - let mut buf = vec![Default::default(); 32]; - let mut map = DefinitionMap::Mut(&mut buf); - for i in 0..32 { - map.allocate(i).unwrap(); - } - for (i, def) in map.as_slice().iter().enumerate() { - let key = i as i32; - map.get(key).unwrap(); - assert_eq!(def.key, key); - } - } - - /// Test sparse allocation where keys never map to indices. This is - /// generally the case for instruction definitions and would apply - /// to fonts with function definition numbers that all fall outside - /// the range 0..max_function_defs. - #[test] - fn allocate_sparse() { - let mut buf = vec![Default::default(); 3]; - let mut map = DefinitionMap::Mut(&mut buf); - let keys = [42, 88, 107]; - for key in keys { - map.allocate(key).unwrap(); - } - for key in keys { - assert_eq!(map.get(key).unwrap().key, key); - } - } - - /// Test mixed allocation where some keys map to indices and others are - /// subject to fallback allocation. This would be the case for fonts - /// with function definition numbers where some fall inside the range - /// 0..max_function_defs but others don't. - #[test] - fn allocate_mixed() { - let mut buf = vec![Default::default(); 10]; - let mut map = DefinitionMap::Mut(&mut buf); - let keys = [ - 0, 1, 2, 3, // Directly mapped to indices - 123456, -42, -5555, // Fallback allocated - 5, // Also directly mapped - 7, // Would be direct but blocked by prior fallback - ]; - for key in keys { - map.allocate(key).unwrap(); - } - // Check backing store directly to ensure the expected allocation - // pattern. - let expected = [0, 1, 2, 3, 0, 5, 7, -5555, -42, 123456]; - let mapped_keys: Vec<_> = map.as_slice().iter().map(|def| def.key).collect(); - assert_eq!(&expected, mapped_keys.as_slice()); - // Check that all keys are mapped - for key in keys { - assert_eq!(map.get(key).unwrap().key, key); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -//! Arithmetic and math instructions. -//! -//! Implements 10 instructions. -//! -//! See - -use super::{super::math, Engine, HintErrorKind, OpResult}; - -impl Engine<'_> { - /// ADD[] (0x60) - /// - /// Pops: n1, n2 (F26Dot6) - /// Pushes: (n2 + n1) - /// - /// Pops n1 and n2 off the stack and pushes the sum of the two elements - /// onto the stack. - /// - /// See - /// and - pub(super) fn op_add(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok(a.wrapping_add(b))) - } - - /// SUB[] (0x61) - /// - /// Pops: n1, n2 (F26Dot6) - /// Pushes: (n2 - n1) - /// - /// Pops n1 and n2 off the stack and pushes the difference of the two - /// elements onto the stack. - /// - /// See - /// and - pub(super) fn op_sub(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok(a.wrapping_sub(b))) - } - - /// DIV[] (0x62) - /// - /// Pops: n1, n2 (F26Dot6) - /// Pushes: (n2 / n1) - /// - /// Pops n1 and n2 off the stack and pushes onto the stack the quotient - /// obtained by dividing n2 by n1. Note that this truncates rather than - /// rounds the value. - /// - /// See - /// and - pub(super) fn op_div(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| { - if b == 0 { - Err(HintErrorKind::DivideByZero) - } else { - Ok(math::mul_div_no_round(a, 64, b)) - } - }) - } - - /// MUL[] (0x63) - /// - /// Pops: n1, n2 (F26Dot6) - /// Pushes: (n2 * n1) - /// - /// Pops n1 and n2 off the stack and pushes onto the stack the product of - /// the two elements. - /// - /// See - /// and - pub(super) fn op_mul(&mut self) -> OpResult { - self.value_stack - .apply_binary(|a, b| Ok(math::mul_div(a, b, 64))) - } - - /// ABS[] (0x64) - /// - /// Pops: n - /// Pushes: |n|: absolute value of n (F26Dot6) - /// - /// Pops n off the stack and pushes onto the stack the absolute value of n. - /// - /// See - /// and - pub(super) fn op_abs(&mut self) -> OpResult { - self.value_stack.apply_unary(|n| Ok(n.wrapping_abs())) - } - - /// NEG[] (0x65) - /// - /// Pops: n1 - /// Pushes: -n1: negation of n1 (F26Dot6) - /// - /// This instruction pops n1 off the stack and pushes onto the stack the - /// negated value of n1. - /// - /// See - /// and - pub(super) fn op_neg(&mut self) -> OpResult { - self.value_stack.apply_unary(|n1| Ok(n1.wrapping_neg())) - } - - /// FLOOR[] (0x66) - /// - /// Pops: n1: number whose floor is desired (F26Dot6) - /// Pushes: n: floor of n1 (F26Dot6) - /// - /// Pops n1 and returns n, the greatest integer value less than or equal to n1. - /// - /// See - /// and - pub(super) fn op_floor(&mut self) -> OpResult { - self.value_stack.apply_unary(|n1| Ok(math::floor(n1))) - } - - /// CEILING[] (0x67) - /// - /// Pops: n1: number whose ceiling is desired (F26Dot6) - /// Pushes: n: ceiling of n1 (F26Dot6) - /// - /// Pops n1 and returns n, the least integer value greater than or equal to n1. - /// - /// See - /// and - pub(super) fn op_ceiling(&mut self) -> OpResult { - self.value_stack.apply_unary(|n1| Ok(math::ceil(n1))) - } - - /// MAX[] (0x8B) - /// - /// Pops: e1, e2 - /// Pushes: maximum of e1 and e2 - /// - /// Pops two elements, e1 and e2, from the stack and pushes the larger of - /// these two quantities onto the stack. - /// - /// See - /// and - pub(super) fn op_max(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok(a.max(b))) - } - - /// MIN[] (0x8C) - /// - /// Pops: e1, e2 - /// Pushes: minimum of e1 and e2 - /// - /// Pops two elements, e1 and e2, from the stack and pushes the smaller - /// of these two quantities onto the stack. - /// - /// See - /// and - pub(super) fn op_min(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok(a.min(b))) - } -} - -#[cfg(test)] -mod tests { - use super::{super::MockEngine, math, HintErrorKind}; - - /// Test the binary operations that don't require fixed point - /// arithmetic. - #[test] - fn simple_binops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - for b in -10..=10 { - let input = &[a, b]; - engine.test_exec(input, a + b, |engine| { - engine.op_add().unwrap(); - }); - engine.test_exec(input, a - b, |engine| { - engine.op_sub().unwrap(); - }); - engine.test_exec(input, a.max(b), |engine| { - engine.op_max().unwrap(); - }); - engine.test_exec(input, a.min(b), |engine| { - engine.op_min().unwrap(); - }); - } - } - } - - /// Test the unary operations that don't require fixed point - /// arithmetic. - #[test] - fn simple_unops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - let input = &[a]; - engine.test_exec(input, -a, |engine| { - engine.op_neg().unwrap(); - }); - engine.test_exec(input, a.abs(), |engine| { - engine.op_abs().unwrap(); - }); - } - } - - #[test] - fn f26dot6_binops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - for b in -10..=10 { - let a = a * 64 + 30; - let b = b * 64 - 30; - let input = &[a, b]; - engine.test_exec(input, math::mul_div(a, b, 64), |engine| { - engine.op_mul().unwrap(); - }); - if b != 0 { - engine.test_exec(input, math::mul_div_no_round(a, 64, b), |engine| { - engine.op_div().unwrap(); - }); - } else { - engine.value_stack.push(a).unwrap(); - engine.value_stack.push(b).unwrap(); - assert!(matches!(engine.op_div(), Err(HintErrorKind::DivideByZero))); - } - } - } - } - - #[test] - fn f26dot6_unops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - for b in -10..=10 { - let a = a * 64 + b; - let input = &[a]; - engine.test_exec(input, math::floor(a), |engine| { - engine.op_floor().unwrap(); - }); - engine.test_exec(input, math::ceil(a), |engine| { - engine.op_ceiling().unwrap(); - }); - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,319 +0,0 @@ -//! Managing the flow of control. -//! -//! Implements 6 instructions. -//! -//! See - -use read_fonts::tables::glyf::bytecode::Opcode; - -use super::{Engine, HintErrorKind, OpResult}; - -impl Engine<'_> { - /// If test. - /// - /// IF[] (0x58) - /// - /// Pops: e: stack element - /// - /// Tests the element popped off the stack: if it is zero (FALSE), the - /// instruction pointer is jumped to the next ELSE or EIF instruction - /// in the instruction stream. If the element at the top of the stack is - /// nonzero (TRUE), the next instruction in the instruction stream is - /// executed. Execution continues until an ELSE instruction is encountered - /// or an EIF instruction ends the IF. If an else statement is found before - /// the EIF, the instruction pointer is moved to the EIF statement. - /// - /// See - /// and - pub(super) fn op_if(&mut self) -> OpResult { - if self.value_stack.pop()? == 0 { - // The condition variable is false so we jump to the next - // ELSE or EIF but we have to skip intermediate IF/ELSE/EIF - // instructions. - let mut nest_depth = 1; - let mut out = false; - while !out { - let opcode = self.decode_next_opcode()?; - match opcode { - Opcode::IF => nest_depth += 1, - Opcode::ELSE => out = nest_depth == 1, - Opcode::EIF => { - nest_depth -= 1; - out = nest_depth == 0; - } - _ => {} - } - } - } - Ok(()) - } - - /// Else. - /// - /// ELSE[] (0x1B) - /// - /// Marks the start of the sequence of instructions that are to be executed - /// if an IF instruction encounters a FALSE value on the stack. This - /// sequence of instructions is terminated with an EIF instruction. - /// - /// See - /// and - pub(super) fn op_else(&mut self) -> OpResult { - let mut nest_depth = 1; - while nest_depth != 0 { - let opcode = self.decode_next_opcode()?; - match opcode { - Opcode::IF => nest_depth += 1, - Opcode::EIF => nest_depth -= 1, - _ => {} - } - } - Ok(()) - } - - /// End if. - /// - /// EIF[] (0x59) - /// - /// Marks the end of an IF[] instruction. - /// - /// See - /// and - pub(super) fn op_eif(&mut self) -> OpResult { - // Nothing - Ok(()) - } - - /// Jump relative on true. - /// - /// JROT[] (0x78) - /// - /// Pops: e: stack element - /// offset: number of bytes to move the instruction pointer - /// - /// Pops and tests the element value, and then pops the offset. If the - /// element value is non-zero (TRUE), the signed offset will be added - /// to the instruction pointer and execution will be resumed at the address - /// obtained. Otherwise, the jump is not taken and the next instruction in - /// the instruction stream is executed. The jump is relative to the position - /// of the instruction itself. That is, the instruction pointer is still - /// pointing at the JROT[ ] instruction when offset is added to obtain the - /// new address. - /// - /// See - /// and - pub(super) fn op_jrot(&mut self) -> OpResult { - let e = self.value_stack.pop()?; - self.do_jump(e != 0) - } - - /// Jump. - /// - /// JMPR[] (0x1C) - /// - /// Pops: offset: number of bytes to move the instruction pointer - /// - /// The signed offset is added to the instruction pointer and execution - /// is resumed at the new location in the instruction steam. The jump is - /// relative to the position of the instruction itself. That is, the - /// instruction pointer is still pointing at the JROT[] instruction when - /// offset is added to obtain the new address. - /// - /// See - /// and - pub(super) fn op_jmpr(&mut self) -> OpResult { - self.do_jump(true) - } - - /// Jump relative on false. - /// - /// JROF[] (0x78) - /// - /// Pops: e: stack element - /// offset: number of bytes to move the instruction pointer - /// - /// Pops and tests the element value, and then pops the offset. If the - /// element value is non-zero (TRUE), the signed offset will be added - /// to the instruction pointer and execution will be resumed at the address - /// obtained. Otherwise, the jump is not taken and the next instruction in - /// the instruction stream is executed. The jump is relative to the position - /// of the instruction itself. That is, the instruction pointer is still - /// pointing at the JROT[ ] instruction when offset is added to obtain the - /// new address. - /// - /// Pops and tests the element value, and then pops the offset. If the - /// element value is zero (FALSE), the signed offset will be added to the - /// nstruction pointer and execution will be resumed at the address - /// obtainted. Otherwise, the jump is not taken and the next instruction - /// in the instruction stream is executed. The jump is relative to the - /// position of the instruction itself. That is, the instruction pointer is - /// still pointing at the JROT[ ] instruction when the offset is added to - /// obtain the new address. - /// - /// See - /// and - pub(super) fn op_jrof(&mut self) -> OpResult { - let e = self.value_stack.pop()?; - self.do_jump(e == 0) - } - - /// Common code for jump instructions. - /// - /// See - fn do_jump(&mut self, test: bool) -> OpResult { - // Offset is relative to previous jump instruction and decoder is - // already pointing to next instruction, so subtract one - let jump_offset = self.value_stack.pop()?.wrapping_sub(1); - if test { - if jump_offset < 0 { - if jump_offset == -1 { - // If the offset is -1, we'll just loop in place... forever - return Err(HintErrorKind::InvalidJump); - } - self.loop_budget.doing_backward_jump()?; - } - self.program.decoder.pc = self - .program - .decoder - .pc - .wrapping_add_signed(jump_offset as isize); - } - Ok(()) - } - - fn decode_next_opcode(&mut self) -> Result { - Ok(self - .program - .decoder - .decode() - .ok_or(HintErrorKind::UnexpectedEndOfBytecode)?? - .opcode) - } -} - -#[cfg(test)] -mod tests { - use super::{super::MockEngine, HintErrorKind, Opcode}; - - #[test] - fn if_else() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Some code with nested ifs - #[rustfmt::skip] - let ops = [ - IF, - ADD, // 1 - SUB, - IF, - MUL, // 4 - DIV, - ELSE, // 8 - IUP0, // 7 - IUP1, - EIF, - ELSE, // 10 - RUTG, // 11 - IF, - EIF, - EIF // 14 - ]; - let bytecode = ops.map(|op| op as u8); - engine.program.decoder.bytecode = bytecode.as_slice(); - // Outer if - { - // push a true value to enter the first branch - engine.program.decoder.pc = 1; - engine.value_stack.push(1).unwrap(); - engine.op_if().unwrap(); - assert_eq!(engine.program.decoder.pc, 1); - // false enters the else branch - engine.program.decoder.pc = 1; - engine.value_stack.push(0).unwrap(); - engine.op_if().unwrap(); - assert_eq!(engine.program.decoder.pc, 11); - } - // Inner if - { - // push a true value to enter the first branch - engine.program.decoder.pc = 4; - engine.value_stack.push(1).unwrap(); - engine.op_if().unwrap(); - assert_eq!(engine.program.decoder.pc, 4); - // false enters the else branch - engine.program.decoder.pc = 4; - engine.value_stack.push(0).unwrap(); - engine.op_if().unwrap(); - assert_eq!(engine.program.decoder.pc, 7); - } - // Else with nested if - { - // This jumps to the instruction after the next EIF, skipping any - // nested conditional blocks - engine.program.decoder.pc = 10; - engine.op_else().unwrap(); - assert_eq!(engine.program.decoder.pc, 15); - engine.program.decoder.pc = 8; - engine.op_else().unwrap(); - assert_eq!(engine.program.decoder.pc, 10); - } - } - - #[test] - fn jumps() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Unconditional jump - { - engine.program.decoder.pc = 1000; - engine.value_stack.push(100).unwrap(); - engine.op_jmpr().unwrap(); - assert_eq!(engine.program.decoder.pc, 1099); - } - // Jump if true - { - engine.program.decoder.pc = 1000; - // first test false condition, pc shouldn't change - engine.value_stack.push(100).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_jrot().unwrap(); - assert_eq!(engine.program.decoder.pc, 1000); - // then true condition - engine.value_stack.push(100).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_jrot().unwrap(); - assert_eq!(engine.program.decoder.pc, 1099); - } - // Jump if false - { - engine.program.decoder.pc = 1000; - // first test true condition, pc shouldn't change - engine.value_stack.push(-100).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_jrof().unwrap(); - assert_eq!(engine.program.decoder.pc, 1000); - // then false condition - engine.value_stack.push(-100).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_jrof().unwrap(); - assert_eq!(engine.program.decoder.pc, 899); - } - // Exhaust backward jump loop budget - { - engine.loop_budget.limit = 40; - for i in 0..45 { - engine.value_stack.push(-5).unwrap(); - let result = engine.op_jmpr(); - if i < 39 { - result.unwrap(); - } else { - assert!(matches!( - result, - Err(HintErrorKind::ExceededExecutionBudget) - )); - } - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -//! Managing the control value table. -//! -//! Implements 3 instructions. -//! -//! See - -use super::{super::math::mul, Engine, F26Dot6, OpResult}; - -impl Engine<'_> { - /// Write control value table in pixel units. - /// - /// WCVTP[] (0x44) - /// - /// Pops: value: number in pixels (F26Dot6 fixed point number), - /// location: Control Value Table location (uint32) - /// - /// Pops a location and a value from the stack and puts that value in the - /// specified location in the Control Value Table. This instruction assumes - /// the value is in pixels and not in FUnits. - /// - /// See - /// and - pub(super) fn op_wcvtp(&mut self) -> OpResult { - let value = self.value_stack.pop_f26dot6()?; - let location = self.value_stack.pop_usize()?; - let result = self.cvt.set(location, value); - if self.graphics.is_pedantic { - result - } else { - Ok(()) - } - } - - /// Write control value table in font units. - /// - /// WCVTF[] (0x70) - /// - /// Pops: value: number in pixels (F26Dot6 fixed point number), - /// location: Control Value Table location (uint32) - /// - /// Pops a location and a value from the stack and puts the specified - /// value in the specified address in the Control Value Table. This - /// instruction assumes the value is expressed in FUnits and not pixels. - /// The value is scaled before being written to the table. - /// - /// See - /// and - pub(super) fn op_wcvtf(&mut self) -> OpResult { - let value = self.value_stack.pop()?; - let location = self.value_stack.pop_usize()?; - let result = self.cvt.set( - location, - F26Dot6::from_bits(mul(value, self.graphics.scale)), - ); - if self.graphics.is_pedantic { - result - } else { - Ok(()) - } - } - - /// Read control value table. - /// - /// RCVT[] (0x45) - /// - /// Pops: location: CVT entry number - /// Pushes: value: CVT value (F26Dot6) - /// - /// Pops a location from the stack and pushes the value in the location - /// specified in the Control Value Table onto the stack. - /// - /// See - /// and - pub(super) fn op_rcvt(&mut self) -> OpResult { - let location = self.value_stack.pop()? as usize; - let maybe_value = self.cvt.get(location); - let value = if self.graphics.is_pedantic { - maybe_value? - } else { - maybe_value.unwrap_or_default() - }; - self.value_stack.push(value.to_bits()) - } -} - -#[cfg(test)] -mod tests { - use super::super::{super::math, HintErrorKind, MockEngine}; - - #[test] - fn write_read() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.value_stack.push(i * 2).unwrap(); - engine.op_wcvtp().unwrap(); - } - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.op_rcvt().unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), i * 2); - } - } - - #[test] - fn write_scaled_read() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let scale = 64; - engine.graphics.scale = scale; - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.value_stack.push(i * 2).unwrap(); - // WCVTF takes a value in font units and converts to pixels - // with the current scale - engine.op_wcvtf().unwrap(); - } - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.op_rcvt().unwrap(); - let value = engine.value_stack.pop().unwrap(); - assert_eq!(value, math::mul(i * 2, scale)); - } - } - - #[test] - fn pedantry() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let oob_index = 1000; - // Disable pedantic mode: OOB writes are ignored, OOB reads - // push 0 - engine.graphics.is_pedantic = false; - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_wcvtp().unwrap(); - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_wcvtf().unwrap(); - engine.value_stack.push(oob_index).unwrap(); - engine.op_rcvt().unwrap(); - // Enable pedantic mode: OOB reads/writes error - engine.graphics.is_pedantic = true; - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - assert_eq!( - engine.op_wcvtp(), - Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) - ); - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - assert_eq!( - engine.op_wcvtf(), - Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) - ); - engine.value_stack.push(oob_index).unwrap(); - assert_eq!( - engine.op_rcvt(), - Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) - ); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,288 +0,0 @@ -//! Reading and writing data. -//! -//! Implements 7 instructions. -//! -//! See - -use super::{ - super::{math, zone::ZonePointer}, - Engine, OpResult, -}; - -impl Engine<'_> { - /// Get coordinate project in to the projection vector. - /// - /// GC\[a\] (0x46 - 0x47) - /// - /// a: 0: use current position of point p - /// 1: use the position of point p in the original outline - /// - /// Pops: p: point number - /// Pushes: value: coordinate location (F26Dot6) - /// - /// Measures the coordinate value of point p on the current - /// projection_vector and pushes the value onto the stack. - /// - /// See - /// and - pub(super) fn op_gc(&mut self, opcode: u8) -> OpResult { - let p = self.value_stack.pop_usize()?; - let gs = &mut self.graphics; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp2, p)]) { - self.value_stack.push(0)?; - return Ok(()); - } - let value = if (opcode & 1) != 0 { - gs.dual_project(gs.zp2().original(p)?, Default::default()) - } else { - gs.project(gs.zp2().point(p)?, Default::default()) - }; - self.value_stack.push(value.to_bits())?; - Ok(()) - } - - /// Set coordinate from the stack using projection vector and freedom - /// vector. - /// - /// SCFS[] (0x48) - /// - /// Pops: value: distance from origin to move point (F26Dot6) - /// p: point number - /// - /// Moves point p from its current position along the freedom_vector so - /// that its component along the projection_vector becomes the value popped - /// off the stack. - /// - /// See - /// and - pub(super) fn op_scfs(&mut self) -> OpResult { - let value = self.value_stack.pop_f26dot6()?; - let p = self.value_stack.pop_usize()?; - let gs = &mut self.graphics; - let projection = gs.project(gs.zp2().point(p)?, Default::default()); - gs.move_point(gs.zp2, p, value.wrapping_sub(projection))?; - if gs.zp2.is_twilight() { - let twilight = gs.zone_mut(ZonePointer::Twilight); - *twilight.original_mut(p)? = twilight.point(p)?; - } - Ok(()) - } - - /// Measure distance. - /// - /// MD\[a\] (0x46 - 0x47) - /// - /// a: 0: measure distance in grid-fitted outline - /// 1: measure distance in original outline - /// - /// Pops: p1: point number - /// p2: point number - /// Pushes: distance (F26Dot6) - /// - /// Measures the distance between outline point p1 and outline point p2. - /// The value returned is in pixels (F26Dot6) If distance is negative, it - /// was measured against the projection vector. Reversing the order in - /// which the points are listed will change the sign of the result. - /// - /// See - /// and - pub(super) fn op_md(&mut self, opcode: u8) -> OpResult { - let p1 = self.value_stack.pop_usize()?; - let p2 = self.value_stack.pop_usize()?; - let gs = &self.graphics; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, p2), (gs.zp1, p1)]) { - self.value_stack.push(0)?; - return Ok(()); - } - let distance = if (opcode & 1) != 0 { - // measure in grid fitted outline - gs.project(gs.zp0().point(p2)?, gs.zp1().point(p1)?) - .to_bits() - } else if gs.zp0.is_twilight() || gs.zp1.is_twilight() { - // special case for twilight zone - gs.dual_project(gs.zp0().original(p2)?, gs.zp1().original(p1)?) - .to_bits() - } else { - // measure in original unscaled outline - math::mul( - gs.dual_project_unscaled(gs.zp0().unscaled(p2), gs.zp1().unscaled(p1)), - gs.unscaled_to_pixels(), - ) - }; - self.value_stack.push(distance) - } - - /// Measure pixels per em. - /// - /// MPPEM[] (0x4B) - /// - /// Pushes: ppem: pixels per em (uint32) - /// - /// This instruction pushes the number of pixels per em onto the stack. - /// Pixels per em is a function of the resolution of the rendering device - /// and the current point size and the current transformation matrix. - /// - /// See - /// and - pub(super) fn op_mppem(&mut self) -> OpResult { - self.value_stack.push(self.graphics.ppem) - } - - /// Measure point size. - /// - /// MPS[] (0x4C) - /// - /// Pushes: pointSize: the size in points of the current glyph (F26Dot6) - /// - /// Measure point size can be used to obtain a value which serves as the - /// basis for choosing whether to branch to an alternative path through the - /// instruction stream. It makes it possible to treat point sizes below or - /// above a certain threshold differently. - /// - /// See - /// and - pub(super) fn op_mps(&mut self) -> OpResult { - // Note: FreeType computes this at - // - // which is mul_div(ppem, 64 * 72, resolution) where resolution - // is always 72 for our purposes (Skia), resulting in ppem * 64. - self.value_stack.push(self.graphics.ppem * 64) - } -} - -#[cfg(test)] -mod tests { - use super::super::{super::zone::ZonePointer, math, Engine, MockEngine}; - use raw::types::F26Dot6; - - #[test] - fn measure_ppem_and_point_size() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let ppem = 20; - engine.graphics.ppem = ppem; - engine.op_mppem().unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), ppem); - engine.op_mps().unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), ppem * 64); - } - - #[test] - fn gc() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - // current point projected coord - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - engine.value_stack.push(1).unwrap(); - engine.op_gc(0).unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), 4); - // original point projected coord - let point = engine.graphics.zones[1].original_mut(1).unwrap(); - point.x = F26Dot6::from_bits(-64); - point.y = F26Dot6::from_bits(521); - engine.value_stack.push(1).unwrap(); - engine.op_gc(1).unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), 176); - } - - #[test] - fn scfs() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - // This instruction is a nop in backward compatibility mode - // and before IUP. - engine.graphics.backward_compatibility = false; - engine.graphics.did_iup_x = true; - engine.graphics.did_iup_y = true; - // use the twilight zone to test the optional code path - engine.graphics.zp2 = ZonePointer::Twilight; - let point = engine.graphics.zones[0].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - // assert we're not currently the same - assert_ne!( - engine.graphics.zones[0].point(1).unwrap(), - engine.graphics.zones[0].original(1).unwrap() - ); - // push point number - engine.value_stack.push(1).unwrap(); - // push value to match - engine.value_stack.push(42).unwrap(); - // set coordinate from stack! - engine.op_scfs().unwrap(); - let point = engine.graphics.zones[0].point(1).unwrap(); - assert_eq!(point.x.to_bits(), 166); - assert_eq!(point.y.to_bits(), -239); - // ensure that we set original = point - assert_eq!(point, engine.graphics.zones[0].original(1).unwrap()); - } - - #[test] - fn md_scaled() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - // first path, measure in grid fitted outline - let zone = engine.graphics.zone_mut(ZonePointer::Glyph); - let point1 = zone.point_mut(1).unwrap(); - point1.x = F26Dot6::from_bits(132); - point1.y = F26Dot6::from_bits(-256); - let point2 = zone.point_mut(3).unwrap(); - point2.x = F26Dot6::from_bits(-64); - point2.y = F26Dot6::from_bits(100); - // now measure - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(3).unwrap(); - engine.op_md(1).unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), 16); - } - - #[test] - fn md_unscaled() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - // second path, measure in original unscaled outline. - // unscaled points are set in mock engine but we need a scale - engine.graphics.scale = 375912; - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(3).unwrap(); - engine.op_md(0).unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), 11); - } - - #[test] - fn md_twilight() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - // final path, measure in original outline, in twilight zone - engine.graphics.zp0 = ZonePointer::Twilight; - engine.graphics.zp1 = ZonePointer::Twilight; - // set some points - let zone = engine.graphics.zone_mut(ZonePointer::Twilight); - let point1 = zone.original_mut(1).unwrap(); - point1.x = F26Dot6::from_bits(132); - point1.y = F26Dot6::from_bits(-256); - let point2 = zone.original_mut(3).unwrap(); - point2.x = F26Dot6::from_bits(-64); - point2.y = F26Dot6::from_bits(100); - // now measure - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(3).unwrap(); - engine.op_md(0).unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), 16); - } - - fn set_test_vectors(engine: &mut Engine) { - let v = math::normalize14(100, 50); - engine.graphics.proj_vector = v; - engine.graphics.dual_proj_vector = v; - engine.graphics.freedom_vector = v; - engine.graphics.update_projection_state(); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,522 +0,0 @@ -//! Defining and using functions and instructions. -//! -//! Implements 5 instructions. -//! -//! See - -use read_fonts::tables::glyf::bytecode::Opcode; - -use super::{ - super::{definition::Definition, program::Program}, - Engine, HintErrorKind, OpResult, -}; - -/// [Functions|Instructions] may not exceed 64K in size. -/// See -/// See -const MAX_DEFINITION_SIZE: usize = u16::MAX as usize; - -impl Engine<'_> { - /// Function definition. - /// - /// FDEF[] (0x2C) - /// - /// Pops: f: function identifier number - /// - /// Marks the start of a function definition. The argument f is a number - /// that uniquely identifies this function. A function definition can - /// appear only in the Font Program or the CVT program; attempts to invoke - /// the FDEF instruction within a glyph program will result in an error. - /// Functions may not exceed 64K in size. - /// - /// See - /// and - pub(super) fn op_fdef(&mut self) -> OpResult { - let f = self.value_stack.pop()?; - self.do_def(DefKind::Function, f) - } - - /// End function definition. - /// - /// ENDF[] (0x2D) - /// - /// Marks the end of a function definition or an instruction definition. - /// - /// See - /// and - pub(super) fn op_endf(&mut self) -> OpResult { - self.program.leave() - } - - /// Call function. - /// - /// CALL[] (0x2B) - /// - /// Pops: f: function identifier number - /// - /// Calls the function identified by the number f. - /// - /// See - /// and - pub(super) fn op_call(&mut self) -> OpResult { - let f = self.value_stack.pop()?; - self.do_call(DefKind::Function, 1, f) - } - - /// Loop and call function. - /// - /// LOOPCALL[] (0x2a) - /// - /// Pops: f: function identifier number - /// count: number of times to call the function - /// - /// Calls the function f, count number of times. - /// - /// See - /// and - pub(super) fn op_loopcall(&mut self) -> OpResult { - let f = self.value_stack.pop()?; - let count = self.value_stack.pop()?; - if count > 0 { - self.loop_budget.doing_loop_call(count as usize)?; - self.do_call(DefKind::Function, count as u32, f) - } else { - Ok(()) - } - } - - /// Instruction definition. - /// - /// IDEF[] (0x89) - /// - /// Pops: opcode - /// - /// Begins the definition of an instruction. The instruction definition - /// terminates when at ENDF, which is encountered in the instruction - /// stream. Subsequent executions of the opcode popped will be directed - /// to the contents of this instruction definition (IDEF). IDEFs must be - /// defined in the Font Program or the CVT Program; attempts to invoke the - /// IDEF instruction within a glyph program will result in an error. An - /// IDEF affects only undefined opcodes. If the opcode in question is - /// already defined, the interpreter will ignore the IDEF. This is to be - /// used as a patching mechanism for future instructions. Instructions - /// may not exceed 64K in size. - /// - /// See - /// and - pub(super) fn op_idef(&mut self) -> OpResult { - let opcode = self.value_stack.pop()?; - self.do_def(DefKind::Instruction, opcode) - } - - /// Catch all for unhandled opcodes which will attempt to dispatch to a - /// user defined instruction. - pub(super) fn op_unknown(&mut self, opcode: u8) -> OpResult { - self.do_call(DefKind::Instruction, 1, opcode as i32) - } - - /// Common code for FDEF and IDEF. - fn do_def(&mut self, kind: DefKind, key: i32) -> OpResult { - if self.program.initial == Program::Glyph { - return Err(HintErrorKind::DefinitionInGlyphProgram); - } - let defs = match kind { - DefKind::Function => &mut self.definitions.functions, - DefKind::Instruction => &mut self.definitions.instructions, - }; - let def = defs.allocate(key)?; - let start = self.program.decoder.pc; - while let Some(ins) = self.program.decoder.decode() { - let ins = ins?; - match ins.opcode { - Opcode::FDEF | Opcode::IDEF => return Err(HintErrorKind::NestedDefinition), - Opcode::ENDF => { - let range = start..ins.pc + 1; - if self.graphics.is_pedantic && range.len() > MAX_DEFINITION_SIZE { - *def = Default::default(); - return Err(HintErrorKind::DefinitionTooLarge); - } - *def = Definition::new(self.program.current, range, key); - return Ok(()); - } - _ => {} - } - } - Err(HintErrorKind::UnexpectedEndOfBytecode) - } - - /// Common code for CALL, LOOPCALL and unknown opcode handling. - fn do_call(&mut self, kind: DefKind, count: u32, key: i32) -> OpResult { - if count == 0 { - return Ok(()); - } - let def = match kind { - DefKind::Function => self.definitions.functions.get(key), - DefKind::Instruction => match self.definitions.instructions.get(key) { - // Remap an invalid definition error to unhandled opcode - Err(HintErrorKind::InvalidDefinition(opcode)) => Err( - HintErrorKind::UnhandledOpcode(Opcode::from_byte(opcode as u8)), - ), - result => result, - }, - }; - self.program.enter(*def?, count) - } -} - -enum DefKind { - Function, - Instruction, -} - -#[cfg(test)] -mod tests { - use super::{ - super::{ - super::program::{Program, ProgramState}, - Engine, MockEngine, - }, - HintErrorKind, Opcode, MAX_DEFINITION_SIZE, - }; - - /// Define two functions, one of which calls the other with - /// both CALL and LOOPCALL. - #[test] - fn define_function_call_loopcall() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB001), 1, 0, - // FDEF 0: adds 2 to top stack value - op(FDEF), - op(PUSHB000), 2, - op(ADD), - op(ENDF), - // FDEF 1: calls FDEF 0 once, loop calls 5 times, then - // negates the result - op(FDEF), - op(PUSHB000), 0, - op(CALL), - op(PUSHB001), 5, 0, - op(LOOPCALL), - op(NEG), - op(ENDF), - ]; - // Execute this code to define our functions - engine.set_font_code(&font_code); - engine.run().unwrap(); - // Call FDEF 1 with value of 10 on the stack: - // * calls FDEF 0 which adds 2 - // * loop calls FDEF 0 an additional 5 times which adds a total of 10 - // * then negates the result - // leaving -22 on the stack - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_call().unwrap(); - engine.run().unwrap(); - assert_eq!(engine.value_stack.pop().ok(), Some(-22)); - } - - /// Control value programs can override functions defined in the font - /// program based on instance state. - #[test] - fn override_function() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB001), 0, 0, - // FDEF 0: adds 2 to top stack value - op(FDEF), - op(PUSHB000), 2, - op(ADD), - op(ENDF), - // Redefine FDEF 0: subtract 2 instead - op(FDEF), - op(PUSHB000), 2, - op(SUB), - op(ENDF), - ]; - // Execute this code to define our functions - engine.set_font_code(&font_code); - engine.run().unwrap(); - // Call FDEF 0 with value of 10 on the stack: - // * should subtract 2 rather than add - // leaving 8 on the stack - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_call().unwrap(); - engine.run().unwrap(); - assert_eq!(engine.value_stack.pop().ok(), Some(8)); - } - - /// Executes a call from a CV program into a font program. - /// - /// Tests ProgramState bytecode/decoder management. - #[test] - fn call_different_program() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB000), 0, - // FDEF 0: adds 2 to top stack value - op(FDEF), - op(PUSHB000), 2, - op(ADD), - op(ENDF), - ]; - #[rustfmt::skip] - let cv_code = [ - // Call function defined in font program and negate result - op(PUSHB001), 40, 0, - op(CALL), - op(NEG) - ]; - let glyph_code = &[]; - // Run font program first to define the function - engine.program = ProgramState::new(&font_code, &cv_code, glyph_code, Program::Font); - engine.run().unwrap(); - // Now run CV program which calls into the font program - engine.program = ProgramState::new(&font_code, &cv_code, glyph_code, Program::ControlValue); - engine.run().unwrap(); - // Executing CV program: - // * pushes 40 to the stack - // * calls FDEF 0 in font program which adds 2 - // * returns to CV program - // * negates the value - // leaving -42 on the stack - assert_eq!(engine.value_stack.pop().ok(), Some(-42)); - } - - /// Fail when we exceed loop call budget. - #[test] - fn loopcall_budget() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let limit = engine.loop_budget.limit; - #[rustfmt::skip] - let font_code = [ - op(PUSHB001), 1, 0, - // FDEF 0: does nothing - op(FDEF), - op(ENDF), - // FDEF 1: loop calls FDEF 0 twice, exceeding the budget on the - // second attempt - op(FDEF), - op(PUSHB001), limit as u8, 0, - op(LOOPCALL), - op(PUSHB001), 1, 0, - op(LOOPCALL), // pc = 13 - op(ENDF), - ]; - // Execute this code to define our functions - engine.set_font_code(&font_code); - engine.run().unwrap(); - // Call FDEF 1 which attempts to loop call FDEF 0 (limit + 1) times - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_call().unwrap(); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::ExceededExecutionBudget)); - assert_eq!(err.pc, 13); - } - - /// Defines an instruction using an available opcode and executes it. - #[test] - fn define_instruction_and_use() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - // IDEF 0x93: adds 2 to top stack value - op(PUSHB000), op(INS93), - op(IDEF), - op(PUSHB000), 2, - op(ADD), - op(ENDF), - // FDEF 0: uses defined instruction 0x93 and negates the result - op(PUSHB000), 0, - op(FDEF), - op(INS93), - op(NEG), - op(ENDF), - ]; - // Execute this code to define our functions - engine.set_font_code(&font_code); - engine.run().unwrap(); - // Call FDEF 0 with value of 10 on the stack: - // * executes defined instruction 0x93 - // * then negates the result - // leaving -12 on the stack - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_call().unwrap(); - engine.run().unwrap(); - assert_eq!(engine.value_stack.pop().ok(), Some(-12)); - } - - // Invalid to nest definitions. - #[test] - fn nested_definition() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB001), 1, 0, - op(FDEF), // pc = 3 - op(FDEF), - op(ENDF), - op(ENDF), - ]; - // Execute this code to define our functions - engine.set_font_code(&font_code); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::NestedDefinition)); - assert_eq!(err.pc, 3); - } - - // Invalid to modify definitions from the glyph program. - #[test] - fn definition_in_glyph_program() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB000), 0, - op(FDEF), // pc = 2 - op(ENDF), - ]; - engine.set_font_code(&font_code); - engine.program.initial = Program::Glyph; - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::DefinitionInGlyphProgram)); - assert_eq!(err.pc, 2); - } - - #[test] - fn undefined_function() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.value_stack.push(111).unwrap(); - assert!(matches!( - engine.op_call(), - Err(HintErrorKind::InvalidDefinition(111)) - )); - } - - /// Fun function that just calls itself :) - #[test] - fn infinite_recursion() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - // FDEF 0: call FDEF 0 - op(PUSHB000), 0, - op(FDEF), - op(PUSHB000), 0, - op(CALL), // pc = 5 - op(ENDF), - ]; - engine.set_font_code(&font_code); - engine.run().unwrap(); - // Call stack overflow - engine.value_stack.push(0).unwrap(); - engine.op_call().unwrap(); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::CallStackOverflow)); - assert_eq!(err.pc, 5); - } - - #[test] - fn call_stack_underflow() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(ENDF) - ]; - engine.set_font_code(&font_code); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::CallStackUnderflow)); - assert_eq!(err.pc, 0); - } - - #[test] - fn unhandled_opcode() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(Opcode::INS28), - ]; - engine.set_font_code(&font_code); - let err = engine.run().unwrap_err(); - assert!(matches!( - err.kind, - HintErrorKind::UnhandledOpcode(Opcode::INS28) - )); - assert_eq!(err.pc, 0); - } - - #[test] - fn too_many_definitions() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - #[rustfmt::skip] - let font_code = [ - op(PUSHB101), 0, 1, 2, 3, 4, 5, - op(FDEF), op(ENDF), - op(FDEF), op(ENDF), - op(FDEF), op(ENDF), - op(FDEF), op(ENDF), - op(FDEF), op(ENDF), - op(FDEF), op(ENDF), - ]; - engine.set_font_code(&font_code); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::TooManyDefinitions)); - assert_eq!(err.pc, 17); - } - - #[test] - fn big_definition() { - use Opcode::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let mut font_code = vec![]; - font_code.extend_from_slice(&[op(PUSHB000), 0, op(FDEF)]); - font_code.extend(core::iter::repeat(op(NEG)).take(MAX_DEFINITION_SIZE + 1)); - font_code.push(op(ENDF)); - engine.set_font_code(&font_code); - engine.graphics.is_pedantic = true; - engine.value_stack.push(1).unwrap(); - let err = engine.run().unwrap_err(); - assert!(matches!(err.kind, HintErrorKind::DefinitionTooLarge)); - assert_eq!(err.pc, 2); - } - - fn op(opcode: Opcode) -> u8 { - opcode as u8 - } - - impl<'a> Engine<'a> { - fn set_font_code(&mut self, code: &'a [u8]) { - self.program.bytecode[0] = code; - self.program.decoder.bytecode = code; - self.program.current = Program::Font; - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,195 +0,0 @@ -//! Managing delta exceptions. -//! -//! Implements 6 instructions. -//! -//! See - -use super::{super::graphics::CoordAxis, Engine, F26Dot6, OpResult}; -use read_fonts::tables::glyf::bytecode::Opcode; - -impl Engine<'_> { - /// Delta exception P1, P2 and P3. - /// - /// DELTAP1[] (0x5D) - /// DELTAP2[] (0x71) - /// DELTAP3[] (0x72) - /// - /// Pops: n: number of pairs of exception specifications and points (uint32) - /// p1, arg1, p2, arg2, ..., pnn argn: n pairs of exception specifications - /// and points (pairs of uint32s) - /// - /// DELTAP moves the specified points at the size and by the - /// amount specified in the paired argument. An arbitrary number of points - /// and arguments can be specified. - /// - /// The only difference between the instructions is the bias added to the - /// point adjustment. - /// - /// See - /// and - pub(super) fn op_deltap(&mut self, opcode: Opcode) -> OpResult { - let gs = &mut self.graphics; - let ppem = gs.ppem as u32; - let n = self.value_stack.pop_usize()?; - let bias = match opcode { - Opcode::DELTAP2 => 16, - Opcode::DELTAP3 => 32, - _ => 0, - } + gs.delta_base as u32; - let back_compat = gs.backward_compatibility; - let did_iup = gs.did_iup_x && gs.did_iup_y; - for _ in 0..n { - let point_ix = self.value_stack.pop_usize()?; - let mut b = self.value_stack.pop()?; - // FreeType notes that some popular fonts contain invalid DELTAP - // instructions so out of bounds points are ignored. - // See - if point_ix >= gs.zp0().points.len() { - continue; - } - let mut c = (b as u32 & 0xF0) >> 4; - c += bias; - if ppem == c { - // Blindly copying FreeType here - // - b = (b & 0xF) - 8; - if b >= 0 { - b += 1; - } - b *= 1 << (6 - gs.delta_shift as i32); - let distance = F26Dot6::from_bits(b); - if back_compat { - if !did_iup - && ((gs.is_composite && gs.freedom_vector.y != 0) - || gs.zp0().is_touched(point_ix, CoordAxis::Y)?) - { - gs.move_point(gs.zp0, point_ix, distance)?; - } - } else { - gs.move_point(gs.zp0, point_ix, distance)?; - } - } - } - Ok(()) - } - - /// Delta exception C1, C2 and C3. - /// - /// DELTAC1[] (0x73) - /// DELTAC2[] (0x74) - /// DELTAC3[] (0x75) - /// - /// Pops: n: number of pairs of exception specifications and CVT entry numbers (uint32) - /// c1, arg1, c2, arg2,..., cn, argn: (pairs of uint32s) - /// - /// DELTAC changes the value in each CVT entry specified at the size and - /// by the amount specified in its paired argument. - /// - /// The only difference between the instructions is the bias added to the - /// adjustment. - /// - /// See - /// and - pub(super) fn op_deltac(&mut self, opcode: Opcode) -> OpResult { - let gs = &mut self.graphics; - let ppem = gs.ppem as u32; - let n = self.value_stack.pop_usize()?; - let bias = match opcode { - Opcode::DELTAC2 => 16, - Opcode::DELTAC3 => 32, - _ => 0, - } + gs.delta_base as u32; - for _ in 0..n { - let cvt_ix = self.value_stack.pop_usize()?; - let mut b = self.value_stack.pop()?; - let mut c = (b as u32 & 0xF0) >> 4; - c += bias; - if ppem == c { - // See - b = (b & 0xF) - 8; - if b >= 0 { - b += 1; - } - b *= 1 << (6 - gs.delta_shift as i32); - let cvt_val = self.cvt.get(cvt_ix)?; - self.cvt.set(cvt_ix, cvt_val + F26Dot6::from_bits(b))?; - } - } - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::super::{super::zone::ZonePointer, MockEngine}; - use raw::{ - tables::glyf::bytecode::Opcode, - types::{F26Dot6, Point}, - }; - - #[test] - fn deltap() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - let raw_ppem = 16; - let raw_adjustment = 7; - for (point_ix, (ppem_bias, opcode)) in [ - (0, Opcode::DELTAP1), - (16, Opcode::DELTAP2), - (32, Opcode::DELTAP3), - ] - .iter() - .enumerate() - { - let ppem = raw_ppem + ppem_bias; - engine.graphics.ppem = ppem; - // packed ppem + adjustment entry - let packed_ppem = raw_ppem - engine.graphics.delta_base as i32; - engine - .value_stack - .push((packed_ppem << 4) | raw_adjustment) - .unwrap(); - // point index - engine.value_stack.push(point_ix as _).unwrap(); - // exception count - engine.value_stack.push(1).unwrap(); - engine.op_deltap(*opcode).unwrap(); - let point = engine.graphics.zones[1].point(point_ix).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(-8, 0)); - } - } - - #[test] - fn deltac() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let raw_ppem = 16; - let raw_adjustment = 7; - for (cvt_ix, (ppem_bias, opcode)) in [ - (0, Opcode::DELTAC1), - (16, Opcode::DELTAC2), - (32, Opcode::DELTAC3), - ] - .iter() - .enumerate() - { - let ppem = raw_ppem + ppem_bias; - engine.graphics.ppem = ppem; - // packed ppem + adjustment entry - let packed_ppem = raw_ppem - engine.graphics.delta_base as i32; - engine - .value_stack - .push((packed_ppem << 4) | raw_adjustment) - .unwrap(); - // cvt index - engine.value_stack.push(cvt_ix as _).unwrap(); - // exception count - engine.value_stack.push(1).unwrap(); - engine.op_deltac(*opcode).unwrap(); - let value = engine.cvt.get(cvt_ix).unwrap(); - assert_eq!(value.to_bits(), -8); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,243 +0,0 @@ -//! Instruction decoding and dispatch. - -use read_fonts::tables::glyf::bytecode::Opcode; - -use super::{super::program::Program, Engine, HintError, HintErrorKind, Instruction}; - -/// Maximum number of instructions we will execute in `Engine::run()`. This -/// is used to ensure termination of a hinting program. -/// See -const MAX_RUN_INSTRUCTIONS: usize = 1_000_000; - -impl<'a> Engine<'a> { - /// Resets state for the specified program and executes all instructions. - pub fn run_program(&mut self, program: Program, is_pedantic: bool) -> Result<(), HintError> { - self.reset(program, is_pedantic); - self.run() - } - - /// Set internal state for running the specified program. - pub fn reset(&mut self, program: Program, is_pedantic: bool) { - self.program.reset(program); - // Reset overall graphics state, keeping the retained bits. - self.graphics.reset(); - self.graphics.is_pedantic = is_pedantic; - self.loop_budget.reset(); - // Program specific setup. - match program { - Program::Font => { - self.definitions.functions.reset(); - self.definitions.instructions.reset(); - } - Program::ControlValue => { - self.graphics.backward_compatibility = false; - } - Program::Glyph => { - // Instruct control bit 1 says we reset retained graphics state - // to default values. - if self.graphics.instruct_control & 2 != 0 { - self.graphics.reset_retained(); - } - // Set backward compatibility mode - if self.graphics.target.preserve_linear_metrics() { - self.graphics.backward_compatibility = true; - } else if self.graphics.target.is_smooth() { - self.graphics.backward_compatibility = - (self.graphics.instruct_control & 0x4) == 0; - } else { - self.graphics.backward_compatibility = false; - } - } - } - } - - /// Decodes and dispatches all instructions until completion or error. - pub fn run(&mut self) -> Result<(), HintError> { - let mut count = 0; - while let Some(ins) = self.decode() { - let ins = ins?; - self.dispatch(&ins)?; - count += 1; - if count > MAX_RUN_INSTRUCTIONS { - return Err(HintError { - program: self.program.current, - glyph_id: None, - pc: ins.pc, - opcode: Some(ins.opcode), - kind: HintErrorKind::ExceededExecutionBudget, - }); - } - } - Ok(()) - } - - /// Decodes the next instruction from the current program. - pub fn decode(&mut self) -> Option, HintError>> { - let ins = self.program.decoder.decode()?; - Some(ins.map_err(|_| HintError { - program: self.program.current, - glyph_id: None, - pc: self.program.decoder.pc, - opcode: None, - kind: HintErrorKind::UnexpectedEndOfBytecode, - })) - } - - /// Executes the appropriate code for the given instruction. - pub fn dispatch(&mut self, ins: &Instruction) -> Result<(), HintError> { - let current_program = self.program.current; - self.dispatch_inner(ins).map_err(|kind| HintError { - program: current_program, - glyph_id: None, - pc: ins.pc, - opcode: Some(ins.opcode), - kind, - }) - } - - fn dispatch_inner(&mut self, ins: &Instruction) -> Result<(), HintErrorKind> { - use Opcode::*; - let opcode = ins.opcode; - let raw_opcode = opcode as u8; - match ins.opcode { - SVTCA0 | SVTCA1 | SPVTCA0 | SPVTCA1 | SFVTCA0 | SFVTCA1 => self.op_svtca(raw_opcode)?, - SPVTL0 | SPVTL1 | SFVTL0 | SFVTL1 => self.op_svtl(raw_opcode)?, - SPVFS => self.op_spvfs()?, - SFVFS => self.op_sfvfs()?, - GPV => self.op_gpv()?, - GFV => self.op_gfv()?, - SFVTPV => self.op_sfvtpv()?, - ISECT => self.op_isect()?, - SRP0 => self.op_srp0()?, - SRP1 => self.op_srp1()?, - SRP2 => self.op_srp2()?, - SZP0 => self.op_szp0()?, - SZP1 => self.op_szp1()?, - SZP2 => self.op_szp2()?, - SZPS => self.op_szps()?, - SLOOP => self.op_sloop()?, - RTG => self.op_rtg()?, - RTHG => self.op_rthg()?, - SMD => self.op_smd()?, - ELSE => self.op_else()?, - JMPR => self.op_jmpr()?, - SCVTCI => self.op_scvtci()?, - SSWCI => self.op_sswci()?, - SSW => self.op_ssw()?, - DUP => self.op_dup()?, - POP => self.op_pop()?, - CLEAR => self.op_clear()?, - SWAP => self.op_swap()?, - DEPTH => self.op_depth()?, - CINDEX => self.op_cindex()?, - MINDEX => self.op_mindex()?, - ALIGNPTS => self.op_alignpts()?, - // UNUSED: 0x28 - UTP => self.op_utp()?, - LOOPCALL => self.op_loopcall()?, - CALL => self.op_call()?, - FDEF => self.op_fdef()?, - ENDF => self.op_endf()?, - MDAP0 | MDAP1 => self.op_mdap(raw_opcode)?, - IUP0 | IUP1 => self.op_iup(raw_opcode)?, - SHP0 | SHP1 => self.op_shp(raw_opcode)?, - SHC0 | SHC1 => self.op_shc(raw_opcode)?, - SHZ0 | SHZ1 => self.op_shz(raw_opcode)?, - SHPIX => self.op_shpix()?, - IP => self.op_ip()?, - MSIRP0 | MSIRP1 => self.op_msirp(raw_opcode)?, - ALIGNRP => self.op_alignrp()?, - RTDG => self.op_rtdg()?, - MIAP0 | MIAP1 => self.op_miap(raw_opcode)?, - NPUSHB | NPUSHW => self.op_push(&ins.inline_operands)?, - WS => self.op_ws()?, - RS => self.op_rs()?, - WCVTP => self.op_wcvtp()?, - RCVT => self.op_rcvt()?, - GC0 | GC1 => self.op_gc(raw_opcode)?, - SCFS => self.op_scfs()?, - MD0 | MD1 => self.op_md(raw_opcode)?, - MPPEM => self.op_mppem()?, - MPS => self.op_mps()?, - FLIPON => self.op_flipon()?, - FLIPOFF => self.op_flipoff()?, - // Should be unused in production fonts, but we may want to - // support debugging at some point. Just pops a value from - // the stack. - DEBUG => { - self.value_stack.pop()?; - } - LT => self.op_lt()?, - LTEQ => self.op_lteq()?, - GT => self.op_gt()?, - GTEQ => self.op_gteq()?, - EQ => self.op_eq()?, - NEQ => self.op_neq()?, - ODD => self.op_odd()?, - EVEN => self.op_even()?, - IF => self.op_if()?, - EIF => self.op_eif()?, - AND => self.op_and()?, - OR => self.op_or()?, - NOT => self.op_not()?, - DELTAP1 => self.op_deltap(opcode)?, - SDB => self.op_sdb()?, - SDS => self.op_sds()?, - ADD => self.op_add()?, - SUB => self.op_sub()?, - DIV => self.op_div()?, - MUL => self.op_mul()?, - ABS => self.op_abs()?, - NEG => self.op_neg()?, - FLOOR => self.op_floor()?, - CEILING => self.op_ceiling()?, - ROUND00 | ROUND01 | ROUND10 | ROUND11 => self.op_round()?, - // "No round" means do nothing :) - NROUND00 | NROUND01 | NROUND10 | NROUND11 => {} - WCVTF => self.op_wcvtf()?, - DELTAP2 | DELTAP3 => self.op_deltap(opcode)?, - DELTAC1 | DELTAC2 | DELTAC3 => self.op_deltac(opcode)?, - SROUND => self.op_sround()?, - S45ROUND => self.op_s45round()?, - JROT => self.op_jrot()?, - JROF => self.op_jrof()?, - ROFF => self.op_roff()?, - // UNUSED: 0x7B - RUTG => self.op_rutg()?, - RDTG => self.op_rdtg()?, - SANGW => self.op_sangw()?, - // Unsupported instruction, do nothing - AA => {} - FLIPPT => self.op_flippt()?, - FLIPRGON => self.op_fliprgon()?, - FLIPRGOFF => self.op_fliprgoff()?, - // UNUSED: 0x83 | 0x84 - SCANCTRL => self.op_scanctrl()?, - SDPVTL0 | SDPVTL1 => self.op_sdpvtl(raw_opcode)?, - GETINFO => self.op_getinfo()?, - IDEF => self.op_idef()?, - ROLL => self.op_roll()?, - MAX => self.op_max()?, - MIN => self.op_min()?, - SCANTYPE => self.op_scantype()?, - INSTCTRL => self.op_instctrl()?, - // UNUSED: 0x8F | 0x90 (ADJUST?) - GETVARIATION => self.op_getvariation()?, - GETDATA => self.op_getdata()?, - _ => { - // FreeType handles MIRP, MDRP and pushes here. - // - if opcode >= MIRP00000 { - self.op_mirp(raw_opcode)? - } else if opcode >= MDRP00000 { - self.op_mdrp(raw_opcode)? - } else if opcode >= PUSHB000 { - self.op_push(&ins.inline_operands)?; - } else { - return self.op_unknown(opcode as u8); - } - } - } - Ok(()) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1154 +0,0 @@ -//! Managing the graphics state. -//! -//! Implements 45 instructions. -//! -//! See - -use super::{ - super::{math, program::Program, round::RoundMode}, - Engine, F26Dot6, HintErrorKind, OpResult, Point, -}; - -impl Engine<'_> { - /// Set vectors to coordinate axis. - /// - /// SVTCA\[a\] (0x00 - 0x01) - /// - /// Sets both the projection_vector and freedom_vector to the same one of - /// the coordinate axes. - /// - /// See - /// - /// SPVTCA\[a\] (0x02 - 0x03) - /// - /// Sets the projection_vector to one of the coordinate axes depending on - /// the value of the flag a. - /// - /// See - /// - /// SFVTCA\[a\] (0x04 - 0x05) - /// - /// Sets the freedom_vector to one of the coordinate axes depending on - /// the value of the flag a. - /// - /// See - /// - /// FreeType combines these into a single function using some bit magic on - /// the opcode to determine which axes and vectors to set. - /// - /// See - pub(super) fn op_svtca(&mut self, opcode: u8) -> OpResult { - let opcode = opcode as i32; - // The low bit of the opcode determines the axis to set (1 = x, 0 = y). - let x = (opcode & 1) << 14; - let y = x ^ 0x4000; - // Opcodes 0..4 set the projection vector. - if opcode < 4 { - self.graphics.proj_vector.x = x; - self.graphics.proj_vector.y = y; - self.graphics.dual_proj_vector.x = x; - self.graphics.dual_proj_vector.y = y; - } - // Opcodes with bit 2 unset modify the freedom vector. - if opcode & 2 == 0 { - self.graphics.freedom_vector.x = x; - self.graphics.freedom_vector.y = y; - } - self.graphics.update_projection_state(); - Ok(()) - } - - /// Set vectors to line. - /// - /// SPVTL\[a\] (0x06 - 0x07) - /// - /// Sets the projection_vector to a unit vector parallel or perpendicular - /// to the line segment from point p1 to point p2. - /// - /// See - /// - /// SFVTL\[a\] (0x08 - 0x09) - /// - /// Sets the freedom_vector to a unit vector parallel or perpendicular - /// to the line segment from point p1 to point p2. - /// - /// See - /// - /// Pops: p1, p2 (point number) - /// - /// See - pub(super) fn op_svtl(&mut self, opcode: u8) -> OpResult { - let index1 = self.value_stack.pop_usize()?; - let index2 = self.value_stack.pop_usize()?; - let is_parallel = opcode & 1 == 0; - let p1 = self.graphics.zp1().point(index2)?; - let p2 = self.graphics.zp2().point(index1)?; - let vector = line_vector(p1, p2, is_parallel); - if opcode < 8 { - self.graphics.proj_vector = vector; - self.graphics.dual_proj_vector = vector; - } else { - self.graphics.freedom_vector = vector; - } - self.graphics.update_projection_state(); - Ok(()) - } - - /// Set freedom vector to projection vector. - /// - /// SFVTPV[] (0x0E) - /// - /// Sets the freedom_vector to be the same as the projection_vector. - /// - /// See - /// and - pub(super) fn op_sfvtpv(&mut self) -> OpResult { - self.graphics.freedom_vector = self.graphics.proj_vector; - self.graphics.update_projection_state(); - Ok(()) - } - - /// Set dual projection vector to line. - /// - /// SDPVTL\[a\] (0x86 - 0x87) - /// - /// Pops: p1, p2 (point number) - /// - /// Pops two point numbers from the stack and uses them to specify a line - /// that defines a second, dual_projection_vector. - /// - /// See - /// and - pub(super) fn op_sdpvtl(&mut self, opcode: u8) -> OpResult { - let index1 = self.value_stack.pop_usize()?; - let index2 = self.value_stack.pop_usize()?; - let is_parallel = opcode & 1 == 0; - // First set the dual projection vector from *original* points. - let p1 = self.graphics.zp1().original(index2)?; - let p2 = self.graphics.zp2().original(index1)?; - self.graphics.dual_proj_vector = line_vector(p1, p2, is_parallel); - // Now set the projection vector from the *current* points. - let p1 = self.graphics.zp1().point(index2)?; - let p2 = self.graphics.zp2().point(index1)?; - self.graphics.proj_vector = line_vector(p1, p2, is_parallel); - self.graphics.update_projection_state(); - Ok(()) - } - - /// Set projection vector from stack. - /// - /// SPVFS[] (0x0A) - /// - /// Pops: y, x (2.14 fixed point numbers padded with zeroes) - /// - /// Sets the direction of the projection_vector, using values x and y taken - /// from the stack, so that its projections onto the x and y-axes are x and - /// y, which are specified as signed (two’s complement) fixed-point (2.14) - /// numbers. The square root of (x2 + y2) must be equal to 0x4000 (hex) - /// - /// See - /// and - pub(super) fn op_spvfs(&mut self) -> OpResult { - let y = self.value_stack.pop()? as i16 as i32; - let x = self.value_stack.pop()? as i16 as i32; - let vector = if (x, y) == (0, 0) { - self.graphics.proj_vector - } else { - math::normalize14(x, y) - }; - self.graphics.proj_vector = vector; - self.graphics.dual_proj_vector = vector; - self.graphics.update_projection_state(); - Ok(()) - } - - /// Set freedom vector from stack. - /// - /// SFVFS[] (0x0B) - /// - /// Pops: y, x (2.14 fixed point numbers padded with zeroes) - /// - /// Sets the direction of the freedom_vector, using values x and y taken - /// from the stack, so that its projections onto the x and y-axes are x and - /// y, which are specified as signed (two’s complement) fixed-point (2.14) - /// numbers. The square root of (x2 + y2) must be equal to 0x4000 (hex) - /// - /// See - /// and - pub(super) fn op_sfvfs(&mut self) -> OpResult { - let y = self.value_stack.pop()? as i16 as i32; - let x = self.value_stack.pop()? as i16 as i32; - let vector = if (x, y) == (0, 0) { - self.graphics.freedom_vector - } else { - math::normalize14(x, y) - }; - self.graphics.freedom_vector = vector; - self.graphics.update_projection_state(); - Ok(()) - } - - /// Get projection vector. - /// - /// GPV[] (0x0C) - /// - /// Pushes: x, y (2.14 fixed point numbers padded with zeroes) - /// - /// Pushes the x and y components of the projection_vector onto the stack - /// as two 2.14 numbers. - /// - /// See - /// and - pub(super) fn op_gpv(&mut self) -> OpResult { - let vector = self.graphics.proj_vector; - self.value_stack.push(vector.x)?; - self.value_stack.push(vector.y) - } - - /// Get freedom vector. - /// - /// GFV[] (0x0D) - /// - /// Pushes: x, y (2.14 fixed point numbers padded with zeroes) - /// - /// Pushes the x and y components of the freedom_vector onto the stack as - /// two 2.14 numbers. - /// - /// See - /// and - pub(super) fn op_gfv(&mut self) -> OpResult { - let vector = self.graphics.freedom_vector; - self.value_stack.push(vector.x)?; - self.value_stack.push(vector.y) - } - - /// Set reference point 0. - /// - /// SRP0[] (0x10) - /// - /// Pops: p (point number) - /// - /// Pops a point number from the stack and sets rp0 to that point number. - /// - /// See - /// and - pub(super) fn op_srp0(&mut self) -> OpResult { - let p = self.value_stack.pop_usize()?; - self.graphics.rp0 = p; - Ok(()) - } - - /// Set reference point 1. - /// - /// SRP1[] (0x11) - /// - /// Pops: p (point number) - /// - /// Pops a point number from the stack and sets rp1 to that point number. - /// - /// See - /// and - pub(super) fn op_srp1(&mut self) -> OpResult { - let p = self.value_stack.pop_usize()?; - self.graphics.rp1 = p; - Ok(()) - } - - /// Set reference point 2. - /// - /// SRP2[] (0x12) - /// - /// Pops: p (point number) - /// - /// Pops a point number from the stack and sets rp2 to that point number. - /// - /// See - /// and - pub(super) fn op_srp2(&mut self) -> OpResult { - let p = self.value_stack.pop_usize()?; - self.graphics.rp2 = p; - Ok(()) - } - - /// Set zone pointer 0. - /// - /// SZP0[] (0x13) - /// - /// Pops: n (zone number) - /// - /// Pops a zone number, n, from the stack and sets zp0 to the zone with - /// that number. If n is 0, zp0 points to zone 0. If n is 1, zp0 points - /// to zone 1. Any other value for n is an error. - /// - /// See - /// and - pub(super) fn op_szp0(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.zp0 = n.try_into()?; - Ok(()) - } - - /// Set zone pointer 1. - /// - /// SZP1[] (0x14) - /// - /// Pops: n (zone number) - /// - /// Pops a zone number, n, from the stack and sets zp0 to the zone with - /// that number. If n is 0, zp1 points to zone 0. If n is 1, zp0 points - /// to zone 1. Any other value for n is an error. - /// - /// See - /// and - pub(super) fn op_szp1(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.zp1 = n.try_into()?; - Ok(()) - } - - /// Set zone pointer 2. - /// - /// SZP2[] (0x15) - /// - /// Pops: n (zone number) - /// - /// Pops a zone number, n, from the stack and sets zp0 to the zone with - /// that number. If n is 0, zp2 points to zone 0. If n is 1, zp0 points - /// to zone 1. Any other value for n is an error. - /// - /// See - /// and - pub(super) fn op_szp2(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.zp2 = n.try_into()?; - Ok(()) - } - - /// Set zone pointers. - /// - /// SZPS[] (0x16) - /// - /// Pops: n (zone number) - /// - /// Pops a zone number from the stack and sets all of the zone pointers to - /// point to the zone with that number. If n is 0, all three zone pointers - /// will point to zone 0. If n is 1, all three zone pointers will point to - /// zone 1. Any other value for n is an error. - /// - /// See - /// and - pub(super) fn op_szps(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - let zp = n.try_into()?; - self.graphics.zp0 = zp; - self.graphics.zp1 = zp; - self.graphics.zp2 = zp; - Ok(()) - } - - /// Round to half grid. - /// - /// RTHG[] (0x19) - /// - /// Sets the round_state variable to state 0 (hg). In this state, the - /// coordinates of a point are rounded to the nearest half grid line. - /// - /// See - /// and - pub(super) fn op_rthg(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::HalfGrid; - Ok(()) - } - - /// Round to grid. - /// - /// RTG[] (0x18) - /// - /// Sets the round_state variable to state 1 (g). In this state, distances - /// are rounded to the closest grid line. - /// - /// See - /// and - pub(super) fn op_rtg(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::Grid; - Ok(()) - } - - /// Round to double grid. - /// - /// RTDG[] (0x3D) - /// - /// Sets the round_state variable to state 2 (dg). In this state, distances - /// are rounded to the closest half or integer pixel. - /// - /// See - /// and - pub(super) fn op_rtdg(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::DoubleGrid; - Ok(()) - } - - /// Round down to grid. - /// - /// RDTG[] (0x7D) - /// - /// Sets the round_state variable to state 3 (dtg). In this state, distances - /// are rounded down to the closest integer grid line. - /// - /// See - /// and - pub(super) fn op_rdtg(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::DownToGrid; - Ok(()) - } - - /// Round up to grid. - /// - /// RUTG[] (0x7C) - /// - /// Sets the round_state variable to state 4 (utg). In this state distances - /// are rounded up to the closest integer pixel boundary. - /// - /// See - /// and - pub(super) fn op_rutg(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::UpToGrid; - Ok(()) - } - - /// Round off. - /// - /// ROFF[] (0x7A) - /// - /// Sets the round_state variable to state 5 (off). In this state rounding - /// is turned off. - /// - /// See - /// and - pub(super) fn op_roff(&mut self) -> OpResult { - self.graphics.round_state.mode = RoundMode::Off; - Ok(()) - } - - /// Super round. - /// - /// SROUND[] (0x76) - /// - /// Pops: n (number decomposed to obtain period, phase threshold) - /// - /// SROUND allows you fine control over the effects of the round_state - /// variable by allowing you to set the values of three components of - /// the round_state: period, phase, and threshold. - /// - /// More formally, SROUND maps the domain of 26.6 fixed point numbers into - /// a set of discrete values that are separated by equal distances. - /// - /// See - /// and - pub(super) fn op_sround(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.super_round(0x4000, n); - self.graphics.round_state.mode = RoundMode::Super; - Ok(()) - } - - /// Super round 45 degrees. - /// - /// S45ROUND[] (0x77) - /// - /// Pops: n (number decomposed to obtain period, phase threshold) - /// - /// S45ROUND is analogous to SROUND. The gridPeriod is SQRT(2)/2 pixels - /// rather than 1 pixel. It is useful for measuring at a 45 degree angle - /// with the coordinate axes. - /// - /// See - /// and - pub(super) fn op_s45round(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.super_round(0x2D41, n); - self.graphics.round_state.mode = RoundMode::Super45; - Ok(()) - } - - /// Helper function for decomposing period, phase and threshold for - /// the SROUND[] and SROUND45[] instructions. - /// - /// See - fn super_round(&mut self, grid_period: i32, selector: i32) { - let round_state = &mut self.graphics.round_state; - let period = match selector & 0xC0 { - 0 => grid_period / 2, - 0x40 => grid_period, - 0x80 => grid_period * 2, - 0xC0 => grid_period, - _ => round_state.period, - }; - let phase = match selector & 0x30 { - 0 => 0, - 0x10 => period / 4, - 0x20 => period / 2, - 0x30 => period * 3 / 4, - _ => round_state.phase, - }; - let threshold = if (selector & 0x0F) == 0 { - period - 1 - } else { - ((selector & 0x0F) - 4) * period / 8 - }; - round_state.period = period >> 8; - round_state.phase = phase >> 8; - round_state.threshold = threshold >> 8; - } - - /// Set loop variable. - /// - /// SLOOP[] (0x17) - /// - /// Pops: n (value for loop Graphics State variable (integer)) - /// - /// Pops a value, n, from the stack and sets the loop variable count to - /// that value. The loop variable works with the SHP\[a\], SHPIX[], IP[], - /// FLIPPT[], and ALIGNRP[]. The value n indicates the number of times - /// the instruction is to be repeated. After the instruction executes, - /// the loop variable is reset to 1. - /// - /// See - /// and - pub(super) fn op_sloop(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - if n < 0 { - return Err(HintErrorKind::NegativeLoopCounter); - } - // As in FreeType, heuristically limit the number of loops to 16 bits. - self.graphics.loop_counter = (n as u32).min(0xFFFF); - Ok(()) - } - - /// Set minimum distance. - /// - /// SMD[] (0x1A) - /// - /// Pops: distance: value for minimum_distance (F26Dot6) - /// - /// Pops a value from the stack and sets the minimum_distance variable - /// to that value. The distance is assumed to be expressed in sixty-fourths - /// of a pixel. - /// - /// See - /// and - pub(super) fn op_smd(&mut self) -> OpResult { - let distance = self.value_stack.pop_f26dot6()?; - self.graphics.min_distance = distance; - Ok(()) - } - - /// Instruction execution control. - /// - /// INSTCTRL[] (0x8E) - /// - /// Pops: s: selector flag (int32) - /// value: used to set value of instruction_control (uint16 padded) - /// - /// Sets the instruction control state variable making it possible to turn - /// on or off the execution of instructions and to regulate use of - /// parameters set in the CVT program. INSTCTRL[ ] can only be executed in - /// the CVT program. - /// - /// See - /// and - pub(super) fn op_instctrl(&mut self) -> OpResult { - let selector = self.value_stack.pop()? as u32; - let value = self.value_stack.pop()? as u32; - // Selectors are indices starting with 1; not flags. - // Avoid potential subtract with overflow below. - // See - // and - if !(1..=3).contains(&selector) { - return Ok(()); - } - // Convert index to flag. - let selector_flag = 1 << (selector - 1); - if value != 0 && value != selector_flag { - return Ok(()); - } - // If preserving linear metrics, prevent modification of the backward - // compatibility flag. - if selector == 3 && self.graphics.target.preserve_linear_metrics() { - return Ok(()); - } - match (self.program.initial, selector) { - // Typically, this instruction can only be executed in the prep table. - (Program::ControlValue, _) => { - self.graphics.instruct_control &= !(selector_flag as u8); - self.graphics.instruct_control |= value as u8; - } - // Allow an exception in the glyph program for selector 3 which can - // temporarily disable backward compatibility mode. - (Program::Glyph, 3) => { - self.graphics.backward_compatibility = value != 4; - } - _ => {} - } - Ok(()) - } - - /// Scan conversion control. - /// - /// SCANCTRL[] (0x85) - /// - /// Pops: n: flags indicating when to turn on dropout control mode - /// - /// SCANCTRL is used to set the value of the Graphics State variable - /// scan_control which in turn determines whether the scan converter - /// will activate dropout control for this glyph. - /// - /// See - /// and - pub(super) fn op_scanctrl(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - // Bits 0-7 represent the threshold value for ppem. - let threshold = n & 0xFF; - match threshold { - // A value of FF in bits 0-7 means invoke scan_control for all - // sizes. - 0xFF => self.graphics.scan_control = true, - // A value of 0 in bits 0-7 means never invoke scan_control. - 0 => self.graphics.scan_control = false, - _ => { - let ppem = self.graphics.ppem; - let is_rotated = self.graphics.is_rotated; - let is_stretched = self.graphics.is_stretched; - let scan_control = &mut self.graphics.scan_control; - // Bits 8-13 are used to turn on scan_control in cases where - // the specified conditions are met. Bits 8, 9 and 10 are used - // to turn on the scan_control mode (assuming other - // conditions do not block it). Bits 11, 12, and 13 are used to - // turn off the dropout mode unless other conditions force it - if (n & 0x100) != 0 && ppem <= threshold { - // Bit 8: Set scan_control to TRUE if other conditions - // do not block and ppem is less than or equal to the - // threshold value. - *scan_control = true; - } - if (n & 0x200) != 0 && is_rotated { - // Bit 9: Set scan_control to TRUE if other conditions - // do not block and the glyph is rotated - *scan_control = true; - } - if (n & 0x400) != 0 && is_stretched { - // Bit 10: Set scan_control to TRUE if other conditions - // do not block and the glyph is stretched. - *scan_control = true; - } - if (n & 0x800) != 0 && ppem > threshold { - // Bit 11: Set scan_control to FALSE unless ppem is less - // than or equal to the threshold value. - *scan_control = false; - } - if (n & 0x1000) != 0 && is_rotated { - // Bit 12: Set scan_control to FALSE based on rotation - // state. - *scan_control = false; - } - if (n & 0x2000) != 0 && is_stretched { - // Bit 13: Set scan_control to FALSE based on stretched - // state. - *scan_control = false; - } - } - } - Ok(()) - } - - /// Scan type. - /// - /// SCANTYPE[] (0x8D) - /// - /// Pops: n: 16 bit integer - /// - /// Pops a 16-bit integer whose value is used to determine which rules the - /// scan converter will use. - /// - /// See - /// and - pub(super) fn op_scantype(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.scan_type = n & 0xFFFF; - Ok(()) - } - - /// Set control value table cut in. - /// - /// SCVTCI[] (0x1D) - /// - /// Pops: n: value for cut_in (F26Dot6) - /// - /// Sets the control_value_cut_in in the Graphics State. The value n is - /// expressed in sixty-fourths of a pixel. - /// - /// See - /// and - pub(super) fn op_scvtci(&mut self) -> OpResult { - let n = self.value_stack.pop_f26dot6()?; - self.graphics.control_value_cutin = n; - Ok(()) - } - - /// Set single width cut in. - /// - /// SSWCI[] (0x1E) - /// - /// Pops: n: value for single_width_cut_in (F26Dot6) - /// - /// Sets the single_width_cut_in in the Graphics State. The value n is - /// expressed in sixty-fourths of a pixel. - /// - /// See - /// and - pub(super) fn op_sswci(&mut self) -> OpResult { - let n = self.value_stack.pop_f26dot6()?; - self.graphics.single_width_cutin = n; - Ok(()) - } - - /// Set single width. - /// - /// SSW[] (0x1F) - /// - /// Pops: n: value for single_width_value (FUnits) - /// - /// Sets the single_width_value in the Graphics State. The - /// single_width_value is expressed in FUnits, which the - /// interpreter converts to pixels (F26Dot6). - /// - /// See - /// and - pub(super) fn op_ssw(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.single_width = F26Dot6::from_bits(math::mul(n, self.graphics.scale)); - Ok(()) - } - - /// Set auto flip on. - /// - /// FLIPON[] (0x4D) - /// - /// Sets the auto_flip Boolean in the Graphics State to TRUE causing the - /// MIRP instructions to ignore the sign of Control Value Table entries. - /// The default auto_flip Boolean value is TRUE. - /// - /// See - /// and - pub(super) fn op_flipon(&mut self) -> OpResult { - self.graphics.auto_flip = true; - Ok(()) - } - - /// Set auto flip off. - /// - /// FLIPOFF[] (0x4E) - /// - /// Set the auto_flip Boolean in the Graphics State to FALSE causing the - /// MIRP instructions to use the sign of Control Value Table entries. - /// The default auto_flip Boolean value is TRUE. - /// - /// See - /// and - pub(super) fn op_flipoff(&mut self) -> OpResult { - self.graphics.auto_flip = false; - Ok(()) - } - - /// Set angle weight. - /// - /// SANGW[] (0x7E) - /// - /// Pops: weight: value for angle_weight - /// - /// SANGW is no longer needed because of dropped support to the AA - /// (Adjust Angle) instruction. AA was the only instruction that used - /// angle_weight in the global graphics state. - /// - /// See - /// and - pub(super) fn op_sangw(&mut self) -> OpResult { - // totally unsupported but we still need to pop the stack value - let _weight = self.value_stack.pop()?; - Ok(()) - } - - /// Set delta base in graphics state. - /// - /// SDB[] (0x5E) - /// - /// Pops: n: value for delta_base - /// - /// Pops a number, n, and sets delta_base to the value n. The default for - /// delta_base is 9. - /// - /// See - /// and - pub(super) fn op_sdb(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - self.graphics.delta_base = n as u16; - Ok(()) - } - - /// Set delta shift in graphics state. - /// - /// SDS[] (0x5F) - /// - /// Pops: n: value for delta_shift - /// - /// Sets delta_shift to the value n. The default for delta_shift is 3. - /// - /// See - /// and - pub(super) fn op_sds(&mut self) -> OpResult { - let n = self.value_stack.pop()?; - if n as u32 > 6 { - Err(HintErrorKind::InvalidStackValue(n)) - } else { - self.graphics.delta_shift = n as u16; - Ok(()) - } - } -} - -/// Computes a parallel or perpendicular normalized vector for the line -/// between the two given points. -/// -/// This is common code for the "set vector to line" instructions. -/// -/// See -fn line_vector(p1: Point, p2: Point, is_parallel: bool) -> Point { - let mut a = (p1.x - p2.x).to_bits(); - let mut b = (p1.y - p2.y).to_bits(); - if a == 0 && b == 0 { - // If the points are equal, set to the x axis. - a = 0x4000; - } else if !is_parallel { - // Perform a counter-clockwise rotation by 90 degrees to form a - // perpendicular line. - let c = b; - b = a; - a = -c; - } - math::normalize14(a, b) -} - -#[cfg(test)] -mod tests { - use super::{ - super::{ - super::zone::{Zone, ZonePointer}, - math, F2Dot14, MockEngine, - }, - F26Dot6, HintErrorKind, Point, Program, RoundMode, - }; - - // Some helpful constants for testing vectors - const ONE: i32 = F2Dot14::ONE.to_bits() as i32; - - const X_AXIS: Point = Point::new(ONE, 0); - const Y_AXIS: Point = Point::new(0, ONE); - - #[test] - fn set_vectors_to_coord_axis() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // freedom and projection vector to y axis - engine.op_svtca(0x00).unwrap(); - assert_eq!(engine.graphics.freedom_vector, Y_AXIS); - assert_eq!(engine.graphics.proj_vector, Y_AXIS); - // freedom and projection vector to x axis - engine.op_svtca(0x01).unwrap(); - assert_eq!(engine.graphics.freedom_vector, X_AXIS); - assert_eq!(engine.graphics.proj_vector, X_AXIS); - // projection vector to y axis - engine.op_svtca(0x02).unwrap(); - assert_eq!(engine.graphics.proj_vector, Y_AXIS); - // projection vector to x axis - engine.op_svtca(0x03).unwrap(); - assert_eq!(engine.graphics.proj_vector, X_AXIS); - // freedom vector to y axis - engine.op_svtca(0x04).unwrap(); - assert_eq!(engine.graphics.freedom_vector, Y_AXIS); - // freedom vector to x axis - engine.op_svtca(0x05).unwrap(); - assert_eq!(engine.graphics.freedom_vector, X_AXIS); - } - - #[test] - fn set_get_vectors_from_stack() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // projection vector - engine.value_stack.push(X_AXIS.x).unwrap(); - engine.value_stack.push(X_AXIS.y).unwrap(); - engine.op_spvfs().unwrap(); - assert_eq!(engine.graphics.proj_vector, X_AXIS); - engine.op_gpv().unwrap(); - let y = engine.value_stack.pop().unwrap(); - let x = engine.value_stack.pop().unwrap(); - assert_eq!(Point::new(x, y), X_AXIS); - // freedom vector - engine.value_stack.push(Y_AXIS.x).unwrap(); - engine.value_stack.push(Y_AXIS.y).unwrap(); - engine.op_sfvfs().unwrap(); - assert_eq!(engine.graphics.freedom_vector, Y_AXIS); - engine.op_gfv().unwrap(); - let y = engine.value_stack.pop().unwrap(); - let x = engine.value_stack.pop().unwrap(); - assert_eq!(Point::new(x, y), Y_AXIS); - } - - #[test] - fn set_vectors_to_line() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Set up a zone for testing and set all the zone pointers to it. - let points = &mut [Point::new(0, 0), Point::new(64, 0)].map(|p| p.map(F26Dot6::from_bits)); - let original = - &mut [Point::new(0, 64), Point::new(0, -64)].map(|p| p.map(F26Dot6::from_bits)); - engine.graphics.zones[1] = Zone { - points, - original, - unscaled: &mut [], - flags: &mut [], - contours: &[], - }; - engine.value_stack.push(1).unwrap(); - engine.op_szps().unwrap(); - // First, push point indices (a few times for reuse) - for _ in 0..6 { - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(0).unwrap(); - } - // SPVTL: set projection vector to line: - { - // (parallel) - engine.op_svtl(0x6).unwrap(); - assert_eq!(engine.graphics.proj_vector, X_AXIS); - // (perpendicular) - engine.op_svtl(0x7).unwrap(); - assert_eq!(engine.graphics.proj_vector, Point::new(0, ONE)); - } - // SFVTL: set freedom vector to line: - { - // (parallel) - engine.op_svtl(0x8).unwrap(); - assert_eq!(engine.graphics.freedom_vector, X_AXIS); - // (perpendicular) - engine.op_svtl(0x9).unwrap(); - assert_eq!(engine.graphics.freedom_vector, Point::new(0, ONE)); - } - // SDPVTL: set dual projection vector to line: - { - // (parallel) - engine.op_sdpvtl(0x86).unwrap(); - assert_eq!(engine.graphics.dual_proj_vector, Point::new(0, -ONE)); - // (perpendicular) - engine.op_sdpvtl(0x87).unwrap(); - assert_eq!(engine.graphics.dual_proj_vector, Point::new(ONE, 0)); - } - } - - /// Lots of little tests for instructions that just set fields on - /// the graphics state. - #[test] - fn simple_state_setting() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // srp0 - engine.value_stack.push(111).unwrap(); - engine.op_srp0().unwrap(); - assert_eq!(engine.graphics.rp0, 111); - // srp1 - engine.value_stack.push(222).unwrap(); - engine.op_srp1().unwrap(); - assert_eq!(engine.graphics.rp1, 222); - // srp2 - engine.value_stack.push(333).unwrap(); - engine.op_srp2().unwrap(); - assert_eq!(engine.graphics.rp2, 333); - // zp0 - engine.value_stack.push(1).unwrap(); - engine.op_szp0().unwrap(); - assert_eq!(engine.graphics.zp0, ZonePointer::Glyph); - // zp1 - engine.value_stack.push(0).unwrap(); - engine.op_szp1().unwrap(); - assert_eq!(engine.graphics.zp1, ZonePointer::Twilight); - // zp2 - engine.value_stack.push(1).unwrap(); - engine.op_szp2().unwrap(); - assert_eq!(engine.graphics.zp2, ZonePointer::Glyph); - // zps - engine.value_stack.push(0).unwrap(); - engine.op_szps().unwrap(); - assert_eq!( - [ - engine.graphics.zp0, - engine.graphics.zp1, - engine.graphics.zp2 - ], - [ZonePointer::Twilight; 3] - ); - // zp failure - engine.value_stack.push(2).unwrap(); - assert!(matches!( - engine.op_szps(), - Err(HintErrorKind::InvalidZoneIndex(2)) - )); - // rtg - engine.op_rtg().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::Grid); - // rtdg - engine.op_rtdg().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::DoubleGrid); - // rdtg - engine.op_rdtg().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::DownToGrid); - // rutg - engine.op_rutg().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::UpToGrid); - // roff - engine.op_roff().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::Off); - // sround - engine.value_stack.push(0).unwrap(); - engine.op_sround().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::Super); - // s45round - engine.value_stack.push(0).unwrap(); - engine.op_s45round().unwrap(); - assert_eq!(engine.graphics.round_state.mode, RoundMode::Super45); - // sloop - engine.value_stack.push(10).unwrap(); - engine.op_sloop().unwrap(); - assert_eq!(engine.graphics.loop_counter, 10); - // loop variable cannot be negative - engine.value_stack.push(-10).unwrap(); - assert!(matches!( - engine.op_sloop(), - Err(HintErrorKind::NegativeLoopCounter) - )); - // smd - engine.value_stack.push(64).unwrap(); - engine.op_smd().unwrap(); - assert_eq!(engine.graphics.min_distance, F26Dot6::from_bits(64)); - // scantype - engine.value_stack.push(50).unwrap(); - engine.op_scantype().unwrap(); - assert_eq!(engine.graphics.scan_type, 50); - // scvtci - engine.value_stack.push(128).unwrap(); - engine.op_scvtci().unwrap(); - assert_eq!(engine.graphics.control_value_cutin, F26Dot6::from_bits(128)); - // sswci - engine.value_stack.push(100).unwrap(); - engine.op_sswci().unwrap(); - assert_eq!(engine.graphics.single_width_cutin, F26Dot6::from_bits(100)); - // ssw - engine.graphics.scale = 64; - engine.value_stack.push(100).unwrap(); - engine.op_ssw().unwrap(); - assert_eq!( - engine.graphics.single_width, - F26Dot6::from_bits(math::mul(100, engine.graphics.scale)) - ); - // flipoff - engine.op_flipoff().unwrap(); - assert!(!engine.graphics.auto_flip); - // flipon - engine.op_flipon().unwrap(); - assert!(engine.graphics.auto_flip); - // sdb - engine.value_stack.push(172).unwrap(); - engine.op_sdb().unwrap(); - assert_eq!(engine.graphics.delta_base, 172); - // sds - engine.value_stack.push(4).unwrap(); - engine.op_sds().unwrap(); - assert_eq!(engine.graphics.delta_shift, 4); - // delta_shift has a max value of 6 - engine.value_stack.push(7).unwrap(); - assert!(matches!( - engine.op_sds(), - Err(HintErrorKind::InvalidStackValue(7)) - )); - } - - #[test] - fn instctrl() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.program.initial = Program::ControlValue; - // selectors 1..=3 are valid and values for each selector - // can be 0, which disables the field, or 1 << (selector - 1) to - // enable it - for selector in 1..=3 { - // enable first - let enable_mask = (1 << (selector - 1)) as u8; - engine.value_stack.push(enable_mask as i32).unwrap(); - engine.value_stack.push(selector).unwrap(); - engine.op_instctrl().unwrap(); - assert!(engine.graphics.instruct_control & enable_mask != 0); - // now disable - engine.value_stack.push(0).unwrap(); - engine.value_stack.push(selector).unwrap(); - engine.op_instctrl().unwrap(); - assert!(engine.graphics.instruct_control & enable_mask == 0); - } - // in glyph programs, selector 3 can be used to toggle - // backward_compatibility - engine.program.initial = Program::Glyph; - // enabling this flag opts into "native ClearType mode" - // which disables backward compatibility - engine.value_stack.push((3 - 1) << 1).unwrap(); - engine.value_stack.push(3).unwrap(); - engine.op_instctrl().unwrap(); - assert!(!engine.graphics.backward_compatibility); - // and disabling it enables backward compatibility - engine.value_stack.push(0).unwrap(); - engine.value_stack.push(3).unwrap(); - engine.op_instctrl().unwrap(); - assert!(engine.graphics.backward_compatibility); - } - - // Subtract with overflow caught by fuzzing when selector == 0 - // See - // and - #[test] - fn instctrl_avoid_overflow() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.program.initial = Program::ControlValue; - engine.value_stack.push(0).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_instctrl().unwrap(); - } - - #[test] - fn scanctrl() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Example modes from specification: - // 0x0000 No dropout control is invoked - engine.value_stack.push(0x0000).unwrap(); - engine.op_scanctrl().unwrap(); - assert!(!engine.graphics.scan_control); - // 0x01FF Always do dropout control - engine.value_stack.push(0x01FF).unwrap(); - engine.op_scanctrl().unwrap(); - assert!(engine.graphics.scan_control); - // 0x0A10 Do dropout control if the glyph is rotated and has less than 16 pixels per-em - engine.value_stack.push(0x0A10).unwrap(); - engine.graphics.is_rotated = true; - engine.graphics.ppem = 12; - engine.op_scanctrl().unwrap(); - assert!(engine.graphics.scan_control); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,305 +0,0 @@ -//! Logical functions. -//! -//! Implements 11 instructions. -//! -//! See - -use super::{Engine, F26Dot6, OpResult}; - -impl Engine<'_> { - /// Less than. - /// - /// LT[] (0x50) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// First pops e2, then pops e1 off the stack and compares them: if e1 is - /// less than e2, 1, signifying TRUE, is pushed onto the stack. If e1 is - /// not less than e2, 0, signifying FALSE, is placed onto the stack. - /// - /// See - /// and - pub(super) fn op_lt(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a < b) as i32)) - } - - /// Less than or equal. - /// - /// LTEQ[] (0x51) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e2 and e1 off the stack and compares them. If e1 is less than or - /// equal to e2, 1, signifying TRUE, is pushed onto the stack. If e1 is - /// not less than or equal to e2, 0, signifying FALSE, is placed onto the - /// stack. - /// - /// See - /// and - pub(super) fn op_lteq(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a <= b) as i32)) - } - - /// Greater than. - /// - /// GT[] (0x52) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// First pops e2 then pops e1 off the stack and compares them. If e1 is - /// greater than e2, 1, signifying TRUE, is pushed onto the stack. If e1 - /// is not greater than e2, 0, signifying FALSE, is placed onto the stack. - /// - /// See - /// and - pub(super) fn op_gt(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a > b) as i32)) - } - - /// Greater than or equal. - /// - /// GTEQ[] (0x53) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e1 and e2 off the stack and compares them. If e1 is greater than - /// or equal to e2, 1, signifying TRUE, is pushed onto the stack. If e1 - /// is not greater than or equal to e2, 0, signifying FALSE, is placed - /// onto the stack. - /// - /// See - /// and - pub(super) fn op_gteq(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a >= b) as i32)) - } - - /// Equal. - /// - /// EQ[] (0x54) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e1 and e2 off the stack and compares them. If they are equal, 1, - /// signifying TRUE is pushed onto the stack. If they are not equal, 0, - /// signifying FALSE is placed onto the stack. - /// - /// See - /// and - pub(super) fn op_eq(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a == b) as i32)) - } - - /// Not equal. - /// - /// NEQ[] (0x55) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e1 and e2 from the stack and compares them. If they are not equal, - /// 1, signifying TRUE, is pushed onto the stack. If they are equal, 0, - /// signifying FALSE, is placed on the stack. - /// - /// See - /// and - pub(super) fn op_neq(&mut self) -> OpResult { - self.value_stack.apply_binary(|a, b| Ok((a != b) as i32)) - } - - /// Odd. - /// - /// ODD[] (0x56) - /// - /// Pops: e1 - /// Pushes: Boolean value - /// - /// Tests whether the number at the top of the stack is odd. Pops e1 from - /// the stack and rounds it as specified by the round_state before testing - /// it. After the value is rounded, it is shifted from a fixed point value - /// to an integer value (any fractional values are ignored). If the integer - /// value is odd, one, signifying TRUE, is pushed onto the stack. If it is - /// even, zero, signifying FALSE is placed onto the stack. - /// - /// See - /// and - pub(super) fn op_odd(&mut self) -> OpResult { - let round_state = self.graphics.round_state; - self.value_stack.apply_unary(|e1| { - Ok((round_state.round(F26Dot6::from_bits(e1)).to_bits() & 127 == 64) as i32) - }) - } - - /// Even. - /// - /// EVEN[] (0x57) - /// - /// Pops: e1 - /// Pushes: Boolean value - /// - /// Tests whether the number at the top of the stack is even. Pops e1 off - /// the stack and rounds it as specified by the round_state before testing - /// it. If the rounded number is even, one, signifying TRUE, is pushed onto - /// the stack if it is odd, zero, signifying FALSE, is placed onto the - /// stack. - /// - /// See - /// and - pub(super) fn op_even(&mut self) -> OpResult { - let round_state = self.graphics.round_state; - self.value_stack.apply_unary(|e1| { - Ok((round_state.round(F26Dot6::from_bits(e1)).to_bits() & 127 == 0) as i32) - }) - } - - /// Logical and. - /// - /// AND[] (0x5A) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e1 and e2 off the stack and pushes onto the stack the result of a - /// logical and of the two elements. Zero is returned if either or both of - /// the elements are FALSE (have the value zero). One is returned if both - /// elements are TRUE (have a non zero value). - /// - /// See - /// and - pub(super) fn op_and(&mut self) -> OpResult { - self.value_stack - .apply_binary(|a, b| Ok((a != 0 && b != 0) as i32)) - } - - /// Logical or. - /// - /// OR[] (0x5B) - /// - /// Pops: e1, e2 - /// Pushes: Boolean value - /// - /// Pops e1 and e2 off the stack and pushes onto the stack the result of a - /// logical or operation between the two elements. Zero is returned if both - /// of the elements are FALSE. One is returned if either one or both of the - /// elements are TRUE (has a nonzero value). - /// - /// See - /// and - pub(super) fn op_or(&mut self) -> OpResult { - self.value_stack - .apply_binary(|a, b| Ok((a != 0 || b != 0) as i32)) - } - - /// Logical not. - /// - /// NOT[] (0x5C) - /// - /// Pops: e - /// Pushes: (not e): logical negation of e - /// - /// Pops e off the stack and returns the result of a logical NOT operation - /// performed on e. If originally zero, one is pushed onto the stack if - /// originally nonzero, zero is pushed onto the stack. - /// - /// See - /// and - pub(super) fn op_not(&mut self) -> OpResult { - self.value_stack.apply_unary(|e| Ok((e == 0) as i32)) - } -} - -#[cfg(test)] -mod tests { - use super::super::MockEngine; - - #[test] - fn compare_ops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - for b in -10..=10 { - let input = &[a, b]; - engine.test_exec(input, a < b, |engine| { - engine.op_lt().unwrap(); - }); - engine.test_exec(input, a <= b, |engine| { - engine.op_lteq().unwrap(); - }); - engine.test_exec(input, a > b, |engine| { - engine.op_gt().unwrap(); - }); - engine.test_exec(input, a >= b, |engine| { - engine.op_gteq().unwrap(); - }); - engine.test_exec(input, a == b, |engine| { - engine.op_eq().unwrap(); - }); - engine.test_exec(input, a != b, |engine| { - engine.op_neq().unwrap(); - }); - } - } - } - - #[test] - fn parity_ops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // These operate on 26.6 so values are multiple of 64 - let cases = [ - // (input, is_even) - (0, true), - (64, false), - (128, true), - (192, false), - (256, true), - (57, false), - (-128, true), - ]; - for (input, is_even) in cases { - engine.test_exec(&[input], is_even, |engine| { - engine.op_even().unwrap(); - }); - } - for (input, is_even) in cases { - engine.test_exec(&[input], !is_even, |engine| { - engine.op_odd().unwrap(); - }); - } - } - - #[test] - fn not_op() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.test_exec(&[0], 1, |engine| { - engine.op_not().unwrap(); - }); - engine.test_exec(&[234234], 0, |engine| { - engine.op_not().unwrap(); - }); - } - - #[test] - fn and_or_ops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for a in -10..=10 { - for b in -10..=10 { - let input = &[a, b]; - let a = a != 0; - let b = b != 0; - engine.test_exec(input, a && b, |engine| { - engine.op_and().unwrap(); - }); - engine.test_exec(input, a || b, |engine| { - engine.op_or().unwrap(); - }); - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,322 +0,0 @@ -//! Miscellaneous instructions. -//! -//! Implements 3 instructions. -//! -//! See - -use super::{Engine, OpResult}; - -impl Engine<'_> { - /// Get information. - /// - /// GETINFO[] (0x88) - /// - /// Pops: selector: integer - /// Pushes: result: integer - /// - /// GETINFO is used to obtain data about the font scaler version and the - /// characteristics of the current glyph. The instruction pops a selector - /// used to determine the type of information desired and pushes a result - /// onto the stack. - /// - /// See - /// and - pub(super) fn op_getinfo(&mut self) -> OpResult { - use getinfo::*; - let selector = self.value_stack.pop()?; - let mut result = 0; - // Interpreter version (selector bit: 0, result bits: 0-7) - if (selector & VERSION_SELECTOR_BIT) != 0 { - result = 40; - } - // Glyph rotated (selector bit: 1, result bit: 8) - if (selector & GLYPH_ROTATED_SELECTOR_BIT) != 0 && self.graphics.is_rotated { - result |= GLYPH_ROTATED_RESULT_BIT; - } - // Glyph stretched (selector bit: 2, result bit: 9) - if (selector & GLYPH_STRETCHED_SELECTOR_BIT) != 0 && self.graphics.is_stretched { - result |= GLYPH_STRETCHED_RESULT_BIT; - } - // Font variations (selector bit: 3, result bit: 10) - if (selector & FONT_VARIATIONS_SELECTOR_BIT) != 0 && self.axis_count != 0 { - result |= FONT_VARIATIONS_RESULT_BIT; - } - // The following only apply for smooth hinting. - if self.graphics.target.is_smooth() { - // Subpixel hinting [cleartype enabled] (selector bit: 6, result bit: 13) - // (always enabled) - if (selector & SUBPIXEL_HINTING_SELECTOR_BIT) != 0 { - result |= SUBPIXEL_HINTING_RESULT_BIT; - } - // Vertical LCD subpixels? (selector bit: 8, result bit: 15) - if (selector & VERTICAL_LCD_SELECTOR_BIT) != 0 && self.graphics.target.is_vertical_lcd() - { - result |= VERTICAL_LCD_RESULT_BIT; - } - // Subpixel positioned? (selector bit: 10, result bit: 17) - // (always enabled) - if (selector & SUBPIXEL_POSITIONED_SELECTOR_BIT) != 0 { - result |= SUBPIXEL_POSITIONED_RESULT_BIT; - } - // Symmetrical smoothing (selector bit: 11, result bit: 18) - // Note: FreeType always enables this but we allow direct control - // with our own flag. - // See - if (selector & SYMMETRICAL_SMOOTHING_SELECTOR_BIT) != 0 - && self.graphics.target.symmetric_rendering() - { - result |= SYMMETRICAL_SMOOTHING_RESULT_BIT; - } - // ClearType hinting and grayscale rendering (selector bit: 12, result bit: 19) - if (selector & GRAYSCALE_CLEARTYPE_SELECTOR_BIT) != 0 - && self.graphics.target.is_grayscale_cleartype() - { - result |= GRAYSCALE_CLEARTYPE_RESULT_BIT; - } - } - self.value_stack.push(result) - } - - /// Get variation. - /// - /// GETVARIATION[] (0x91) - /// - /// Pushes: Normalized axes coordinates, one for each axis in the font. - /// - /// GETVARIATION is used to obtain the current normalized variation - /// coordinates for each axis. The coordinate for the first axis, as - /// defined in the 'fvar' table, is pushed first on the stack, followed - /// by each consecutive axis until the coordinate for the last axis is - /// on the stack. - /// - /// See - /// and - pub(super) fn op_getvariation(&mut self) -> OpResult { - // For non-variable fonts, this falls back to IDEF resolution. - let axis_count = self.axis_count as usize; - if axis_count != 0 { - // Make sure we push `axis_count` coords regardless of the value - // provided by the user. - for coord in self - .coords - .iter() - .copied() - .chain(std::iter::repeat(Default::default())) - .take(axis_count) - { - self.value_stack.push(coord.to_bits() as i32)?; - } - Ok(()) - } else { - self.op_unknown(0x91) - } - } - - /// Get data. - /// - /// GETDATA[] (0x92) - /// - /// Pushes: 17 - /// - /// Undocumented and nobody knows what this does. FreeType just - /// returns 17 for variable fonts and falls back to IDEF lookup - /// otherwise. - /// - /// See - pub(super) fn op_getdata(&mut self) -> OpResult { - if self.axis_count != 0 { - self.value_stack.push(17) - } else { - self.op_unknown(0x92) - } - } -} - -/// Constants for the GETINFO instruction. Extracted here -/// to enable access from tests. -mod getinfo { - // Interpreter version (selector bit: 0, result bits: 0-7) - pub const VERSION_SELECTOR_BIT: i32 = 1 << 0; - - // Glyph rotated (selector bit: 1, result bit: 8) - pub const GLYPH_ROTATED_SELECTOR_BIT: i32 = 1 << 1; - pub const GLYPH_ROTATED_RESULT_BIT: i32 = 1 << 8; - - // Glyph stretched (selector bit: 2, result bit: 9) - pub const GLYPH_STRETCHED_SELECTOR_BIT: i32 = 1 << 2; - pub const GLYPH_STRETCHED_RESULT_BIT: i32 = 1 << 9; - - // Font variations (selector bit: 3, result bit: 10) - pub const FONT_VARIATIONS_SELECTOR_BIT: i32 = 1 << 3; - pub const FONT_VARIATIONS_RESULT_BIT: i32 = 1 << 10; - - // Subpixel hinting [cleartype enabled] (selector bit: 6, result bit: 13) - // (always enabled) - pub const SUBPIXEL_HINTING_SELECTOR_BIT: i32 = 1 << 6; - pub const SUBPIXEL_HINTING_RESULT_BIT: i32 = 1 << 13; - - // Vertical LCD subpixels? (selector bit: 8, result bit: 15) - pub const VERTICAL_LCD_SELECTOR_BIT: i32 = 1 << 8; - pub const VERTICAL_LCD_RESULT_BIT: i32 = 1 << 15; - - // Subpixel positioned? (selector bit: 10, result bit: 17) - // (always enabled) - pub const SUBPIXEL_POSITIONED_SELECTOR_BIT: i32 = 1 << 10; - pub const SUBPIXEL_POSITIONED_RESULT_BIT: i32 = 1 << 17; - - // Symmetrical smoothing (selector bit: 11, result bit: 18) - // Note: FreeType always enables this but we deviate when our own - // preserve linear metrics flag is enabled. - pub const SYMMETRICAL_SMOOTHING_SELECTOR_BIT: i32 = 1 << 11; - pub const SYMMETRICAL_SMOOTHING_RESULT_BIT: i32 = 1 << 18; - - // ClearType hinting and grayscale rendering (selector bit: 12, result bit: 19) - pub const GRAYSCALE_CLEARTYPE_SELECTOR_BIT: i32 = 1 << 12; - pub const GRAYSCALE_CLEARTYPE_RESULT_BIT: i32 = 1 << 19; -} - -#[cfg(test)] -mod tests { - use super::super::{ - super::super::super::{SmoothMode, Target}, - Engine, HintErrorKind, MockEngine, - }; - use raw::types::F2Dot14; - use read_fonts::tables::glyf::bytecode::Opcode; - - #[test] - fn getinfo() { - use super::getinfo::*; - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // version - engine.getinfo_test(VERSION_SELECTOR_BIT, 40); - // not rotated - engine.getinfo_test(GLYPH_ROTATED_SELECTOR_BIT, 0); - // rotated - engine.graphics.is_rotated = true; - engine.getinfo_test(GLYPH_ROTATED_SELECTOR_BIT, GLYPH_ROTATED_RESULT_BIT); - // not stretched - engine.getinfo_test(GLYPH_STRETCHED_SELECTOR_BIT, 0); - // stretched - engine.graphics.is_stretched = true; - engine.getinfo_test(GLYPH_STRETCHED_SELECTOR_BIT, GLYPH_STRETCHED_RESULT_BIT); - // stretched and rotated - engine.getinfo_test( - GLYPH_ROTATED_SELECTOR_BIT | GLYPH_STRETCHED_SELECTOR_BIT, - GLYPH_ROTATED_RESULT_BIT | GLYPH_STRETCHED_RESULT_BIT, - ); - // not variable - engine.getinfo_test(FONT_VARIATIONS_SELECTOR_BIT, 0); - // variable - engine.axis_count = 1; - engine.getinfo_test(FONT_VARIATIONS_SELECTOR_BIT, FONT_VARIATIONS_RESULT_BIT); - // in strong hinting mode, the following selectors are always disabled - engine.graphics.target = Target::Mono; - for selector in [ - SUBPIXEL_HINTING_SELECTOR_BIT, - VERTICAL_LCD_SELECTOR_BIT, - SUBPIXEL_POSITIONED_SELECTOR_BIT, - SYMMETRICAL_SMOOTHING_SELECTOR_BIT, - GRAYSCALE_CLEARTYPE_SELECTOR_BIT, - ] { - engine.getinfo_test(selector, 0); - } - // set back to smooth mode - engine.graphics.target = Target::default(); - for (selector, result) in [ - // default smooth mode is grayscale cleartype - ( - GRAYSCALE_CLEARTYPE_SELECTOR_BIT, - GRAYSCALE_CLEARTYPE_RESULT_BIT, - ), - // always enabled in smooth mode - (SUBPIXEL_HINTING_SELECTOR_BIT, SUBPIXEL_HINTING_RESULT_BIT), - ( - SUBPIXEL_POSITIONED_SELECTOR_BIT, - SUBPIXEL_POSITIONED_RESULT_BIT, - ), - ] { - engine.getinfo_test(selector, result); - } - // vertical lcd - engine.graphics.target = Target::Smooth { - mode: SmoothMode::VerticalLcd, - preserve_linear_metrics: true, - symmetric_rendering: false, - }; - engine.getinfo_test(VERTICAL_LCD_SELECTOR_BIT, VERTICAL_LCD_RESULT_BIT); - // symmetical smoothing is disabled - engine.getinfo_test(SYMMETRICAL_SMOOTHING_SELECTOR_BIT, 0); - // grayscale cleartype is disabled when lcd_subpixel is not None - engine.getinfo_test(GRAYSCALE_CLEARTYPE_SELECTOR_BIT, 0); - // reset to default to disable preserve linear metrics - engine.graphics.target = Target::default(); - // now symmetrical smoothing is enabled - engine.getinfo_test( - SYMMETRICAL_SMOOTHING_SELECTOR_BIT, - SYMMETRICAL_SMOOTHING_RESULT_BIT, - ); - } - - #[test] - fn getvariation() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // no variations should trigger unknown opcode - assert!(matches!( - engine.op_getvariation(), - Err(HintErrorKind::UnhandledOpcode(Opcode::GETVARIATION)) - )); - // set the axis count to a non-zero value to enable variations - engine.axis_count = 2; - // and creates some coords - let coords = [ - F2Dot14::from_f32(-1.0), - F2Dot14::from_f32(0.5), - F2Dot14::from_f32(1.0), - ]; - let coords_bits = coords.map(|x| x.to_bits() as i32); - // too few, pad with zeros - engine.coords = &coords[0..1]; - engine.op_getvariation().unwrap(); - assert_eq!(engine.value_stack.len(), 2); - assert_eq!(engine.value_stack.values(), &[coords_bits[0], 0]); - engine.value_stack.clear(); - // too many, truncate - engine.coords = &coords[0..3]; - engine.op_getvariation().unwrap(); - assert_eq!(engine.value_stack.len(), 2); - assert_eq!(engine.value_stack.values(), &coords_bits[0..2]); - engine.value_stack.clear(); - // just right - engine.coords = &coords[0..2]; - engine.op_getvariation().unwrap(); - assert_eq!(engine.value_stack.len(), 2); - assert_eq!(engine.value_stack.values(), &coords_bits[0..2]); - } - - #[test] - fn getdata() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // no variations should trigger unknown opcode - assert!(matches!( - engine.op_getdata(), - Err(HintErrorKind::UnhandledOpcode(Opcode::GETDATA)) - )); - // set the axis count to a non-zero value to enable variations - engine.axis_count = 1; - engine.op_getdata().unwrap(); - // :shrug: - assert_eq!(engine.value_stack.pop().unwrap(), 17); - } - - impl Engine<'_> { - fn getinfo_test(&mut self, selector: i32, expected: i32) { - self.value_stack.push(selector).unwrap(); - self.op_getinfo().unwrap(); - assert_eq!(self.value_stack.pop().unwrap(), expected); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,269 +0,0 @@ -//! TrueType bytecode interpreter. - -mod arith; -mod control_flow; -mod cvt; -mod data; -mod definition; -mod delta; -mod dispatch; -mod graphics; -mod logical; -mod misc; -mod outline; -mod round; -mod stack; -mod storage; - -use read_fonts::{ - tables::glyf::bytecode::Instruction, - types::{F26Dot6, F2Dot14, Point}, -}; - -use super::{ - super::Outlines, - cvt::Cvt, - definition::DefinitionState, - error::{HintError, HintErrorKind}, - graphics::{GraphicsState, RetainedGraphicsState}, - math, - program::ProgramState, - storage::Storage, - value_stack::ValueStack, - zone::Zone, -}; - -pub type OpResult = Result<(), HintErrorKind>; - -/// TrueType bytecode interpreter. -pub struct Engine<'a> { - program: ProgramState<'a>, - graphics: GraphicsState<'a>, - definitions: DefinitionState<'a>, - cvt: Cvt<'a>, - storage: Storage<'a>, - value_stack: ValueStack<'a>, - loop_budget: LoopBudget, - axis_count: u16, - coords: &'a [F2Dot14], -} - -impl<'a> Engine<'a> { - #[allow(clippy::too_many_arguments)] - pub fn new( - outlines: &Outlines, - program: ProgramState<'a>, - graphics: RetainedGraphicsState, - definitions: DefinitionState<'a>, - cvt: impl Into>, - storage: impl Into>, - value_stack: ValueStack<'a>, - twilight: Zone<'a>, - glyph: Zone<'a>, - axis_count: u16, - coords: &'a [F2Dot14], - is_composite: bool, - ) -> Self { - let point_count = if glyph.points.is_empty() { - None - } else { - Some(glyph.points.len()) - }; - let graphics = GraphicsState { - retained: graphics, - zones: [twilight, glyph], - is_composite, - ..Default::default() - }; - Self { - program, - graphics, - definitions, - cvt: cvt.into(), - storage: storage.into(), - value_stack, - loop_budget: LoopBudget::new(outlines, point_count), - axis_count, - coords, - } - } - - pub fn backward_compatibility(&self) -> bool { - self.graphics.backward_compatibility - } - - pub fn retained_graphics_state(&self) -> &RetainedGraphicsState { - &self.graphics.retained - } -} - -/// Tracks budgets for loops to limit execution time. -struct LoopBudget { - /// Maximum number of times we can do backward jumps or - /// loop calls. - limit: usize, - /// Current number of backward jumps executed. - backward_jumps: usize, - /// Current number of loop call iterations executed. - loop_calls: usize, -} - -impl LoopBudget { - fn new(outlines: &Outlines, point_count: Option) -> Self { - let cvt_len = outlines.cvt_len as usize; - // Compute limits for loop calls and backward jumps. - // See - let limit = if let Some(point_count) = point_count { - (point_count * 10).max(50) + (cvt_len / 10).max(50) - } else { - 300 + 22 * cvt_len - }; - // FreeType has two variables for neg_jump_counter_max and - // loopcall_counter_max but sets them to the same value so - // we'll just use a single limit. - Self { - limit, - backward_jumps: 0, - loop_calls: 0, - } - } - - fn reset(&mut self) { - self.backward_jumps = 0; - self.loop_calls = 0; - } - - fn doing_backward_jump(&mut self) -> Result<(), HintErrorKind> { - self.backward_jumps += 1; - if self.backward_jumps > self.limit { - Err(HintErrorKind::ExceededExecutionBudget) - } else { - Ok(()) - } - } - - fn doing_loop_call(&mut self, count: usize) -> Result<(), HintErrorKind> { - self.loop_calls += count; - if self.loop_calls > self.limit { - Err(HintErrorKind::ExceededExecutionBudget) - } else { - Ok(()) - } - } -} - -#[cfg(test)] -use mock::MockEngine; - -#[cfg(test)] -mod mock { - use super::{ - super::{ - cow_slice::CowSlice, - definition::{Definition, DefinitionMap, DefinitionState}, - program::{Program, ProgramState}, - zone::Zone, - Point, PointFlags, - }, - Engine, F26Dot6, GraphicsState, LoopBudget, ValueStack, - }; - - /// Mock engine for testing. - pub(super) struct MockEngine { - cvt_storage: Vec, - value_stack: Vec, - definitions: Vec, - unscaled: Vec>, - points: Vec>, - point_flags: Vec, - contours: Vec, - twilight: Vec>, - twilight_flags: Vec, - } - - impl MockEngine { - pub fn new() -> Self { - Self { - cvt_storage: vec![0; 32], - value_stack: vec![0; 32], - definitions: vec![Default::default(); 8], - unscaled: vec![Default::default(); 32], - points: vec![Default::default(); 64], - point_flags: vec![Default::default(); 32], - contours: vec![31], - twilight: vec![Default::default(); 32], - twilight_flags: vec![Default::default(); 32], - } - } - - pub fn engine(&mut self) -> Engine { - let font_code = &[]; - let cv_code = &[]; - let glyph_code = &[]; - let (cvt, storage) = self.cvt_storage.split_at_mut(16); - let (function_defs, instruction_defs) = self.definitions.split_at_mut(5); - let definition = DefinitionState::new( - DefinitionMap::Mut(function_defs), - DefinitionMap::Mut(instruction_defs), - ); - for (i, point) in self.unscaled.iter_mut().enumerate() { - let i = i as i32; - point.x = 57 + i * 2; - point.y = -point.x * 3; - } - let (points, original) = self.points.split_at_mut(32); - let glyph_zone = Zone::new( - &self.unscaled, - original, - points, - &mut self.point_flags, - &self.contours, - ); - let (points, original) = self.twilight.split_at_mut(16); - let twilight_zone = Zone::new(&[], original, points, &mut self.twilight_flags, &[]); - let mut graphics_state = GraphicsState { - zones: [twilight_zone, glyph_zone], - ..Default::default() - }; - graphics_state.update_projection_state(); - Engine { - graphics: graphics_state, - cvt: CowSlice::new_mut(cvt).into(), - storage: CowSlice::new_mut(storage).into(), - value_stack: ValueStack::new(&mut self.value_stack, false), - program: ProgramState::new(font_code, cv_code, glyph_code, Program::Font), - loop_budget: LoopBudget { - limit: 10, - backward_jumps: 0, - loop_calls: 0, - }, - definitions: definition, - axis_count: 0, - coords: &[], - } - } - } - - impl Default for MockEngine { - fn default() -> Self { - Self::new() - } - } - - impl Engine<'_> { - /// Helper to push values to the stack, invoke a callback and check - /// the expected result. - pub(super) fn test_exec( - &mut self, - push: &[i32], - expected_result: impl Into, - mut f: impl FnMut(&mut Engine), - ) { - for &val in push { - self.value_stack.push(val).unwrap(); - } - f(self); - assert_eq!(self.value_stack.pop().ok(), Some(expected_result.into())); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1418 +0,0 @@ -//! Managing outlines. -//! -//! Implements 87 instructions. -//! -//! See - -use super::{ - super::{ - graphics::CoordAxis, - zone::{PointDisplacement, ZonePointer}, - }, - math, Engine, F26Dot6, HintErrorKind, OpResult, -}; - -impl Engine<'_> { - /// Flip point. - /// - /// FLIPPT[] (0x80) - /// - /// Pops: p: point number (uint32) - /// - /// Uses the loop counter. - /// - /// Flips points that are off the curve so that they are on the curve and - /// points that are on the curve so that they are off the curve. The point - /// is not marked as touched. The result of a FLIPPT instruction is that - /// the contour describing part of a glyph outline is redefined. - /// - /// See - /// and - pub(super) fn op_flippt(&mut self) -> OpResult { - let count = self.graphics.loop_counter as usize; - self.graphics.loop_counter = 1; - // In backward compatibility mode, don't flip points after IUP has - // been done. - if self.graphics.backward_compatibility - && self.graphics.did_iup_x - && self.graphics.did_iup_y - { - for _ in 0..count { - self.value_stack.pop()?; - } - return Ok(()); - } - let zone = self.graphics.zone_mut(ZonePointer::Glyph); - for _ in 0..count { - let p = self.value_stack.pop_usize()?; - zone.flip_on_curve(p)?; - } - Ok(()) - } - - /// Flip range on. - /// - /// FLIPRGON[] (0x81) - /// - /// Pops: highpoint: highest point number in range of points to be flipped (uint32) - /// lowpoint: lowest point number in range of points to be flipped (uint32) - /// - /// Flips a range of points beginning with lowpoint and ending with highpoint so that - /// any off the curve points become on the curve points. The points are not marked as - /// touched. - /// - /// See - /// and - pub(super) fn op_fliprgon(&mut self) -> OpResult { - self.set_on_curve_for_range(true) - } - - /// Flip range off. - /// - /// FLIPRGOFF[] (0x82) - /// - /// Pops: highpoint: highest point number in range of points to be flipped (uint32) - /// lowpoint: lowest point number in range of points to be flipped (uint32) - /// - /// Flips a range of points beginning with lowpoint and ending with - /// highpoint so that any on the curve points become off the curve points. - /// The points are not marked as touched. - /// - /// See - /// and - pub(super) fn op_fliprgoff(&mut self) -> OpResult { - self.set_on_curve_for_range(false) - } - - /// Shift point by the last point. - /// - /// SHP\[a\] (0x32 - 0x33) - /// - /// a: 0: uses rp2 in the zone pointed to by zp1 - /// 1: uses rp1 in the zone pointed to by zp0 - /// - /// Pops: p: point to be shifted - /// - /// Uses the loop counter. - /// - /// Shift point p by the same amount that the reference point has been - /// shifted. Point p is shifted along the freedom_vector so that the - /// distance between the new position of point p and the current position - /// of point p is the same as the distance between the current position - /// of the reference point and the original position of the reference point. - /// - /// See - /// and - pub(super) fn op_shp(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let PointDisplacement { dx, dy, .. } = gs.point_displacement(opcode)?; - let count = gs.loop_counter; - gs.loop_counter = 1; - for _ in 0..count { - let p = self.value_stack.pop_usize()?; - gs.move_zp2_point(p, dx, dy, true)?; - } - Ok(()) - } - - /// Shift contour by the last point. - /// - /// SHC\[a\] (0x34 - 0x35) - /// - /// a: 0: uses rp2 in the zone pointed to by zp1 - /// 1: uses rp1 in the zone pointed to by zp0 - /// - /// Pops: c: contour to be shifted - /// - /// Shifts every point on contour c by the same amount that the reference - /// point has been shifted. Each point is shifted along the freedom_vector - /// so that the distance between the new position of the point and the old - /// position of that point is the same as the distance between the current - /// position of the reference point and the original position of the - /// reference point. The distance is measured along the projection_vector. - /// If the reference point is one of the points defining the contour, the - /// reference point is not moved by this instruction. - /// - /// See - /// and - pub(super) fn op_shc(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let contour_ix = self.value_stack.pop_usize()?; - if !gs.is_pedantic && contour_ix >= gs.zp2().contours.len() { - return Ok(()); - } - let point_disp = gs.point_displacement(opcode)?; - let start = if contour_ix != 0 { - gs.zp2().contour(contour_ix - 1)? as usize + 1 - } else { - 0 - }; - let end = if gs.zp2.is_twilight() { - gs.zp2().points.len() - } else { - gs.zp2().contour(contour_ix)? as usize + 1 - }; - for i in start..end { - if point_disp.zone != gs.zp2 || point_disp.point_ix != i { - gs.move_zp2_point(i, point_disp.dx, point_disp.dy, true)?; - } - } - Ok(()) - } - - /// Shift zone by the last point. - /// - /// SHZ\[a\] (0x36 - 0x37) - /// - /// a: 0: uses rp2 in the zone pointed to by zp1 - /// 1: uses rp1 in the zone pointed to by zp0 - /// - /// Pops: e: zone to be shifted - /// - /// Shift the points in the specified zone (Z1 or Z0) by the same amount - /// that the reference point has been shifted. The points in the zone are - /// shifted along the freedom_vector so that the distance between the new - /// position of the shifted points and their old position is the same as - /// the distance between the current position of the reference point and - /// the original position of the reference point. - /// - /// See - /// and - pub(super) fn op_shz(&mut self, opcode: u8) -> OpResult { - let _e = ZonePointer::try_from(self.value_stack.pop()?)?; - let gs = &mut self.graphics; - let point_disp = gs.point_displacement(opcode)?; - let end = if gs.zp2.is_twilight() { - gs.zp2().points.len() - } else if !gs.zp2().contours.is_empty() { - *gs.zp2() - .contours - .last() - .ok_or(HintErrorKind::InvalidContourIndex(0))? as usize - + 1 - } else { - 0 - }; - for i in 0..end { - if point_disp.zone != gs.zp2 || i != point_disp.point_ix { - gs.move_zp2_point(i, point_disp.dx, point_disp.dy, false)?; - } - } - Ok(()) - } - - /// Shift point by a pixel amount. - /// - /// SHPIX (0x38) - /// - /// Pops: amount: magnitude of the shift (F26Dot6) - /// p1, p2,.. pn: points to be shifted - /// - /// Uses the loop counter. - /// - /// Shifts the points specified by the amount stated. When the loop - /// variable is used, the amount to be shifted is put onto the stack - /// only once. That is, if loop = 3, then the contents of the top of - /// the stack should be point p1, point p2, point p3, amount. The value - /// amount is expressed in sixty-fourths of a pixel. - /// - /// See - /// and - pub(super) fn op_shpix(&mut self) -> OpResult { - let gs = &mut self.graphics; - let in_twilight = gs.zp0.is_twilight() || gs.zp1.is_twilight() || gs.zp2.is_twilight(); - let amount = self.value_stack.pop()?; - let dx = F26Dot6::from_bits(math::mul14(amount, gs.freedom_vector.x)); - let dy = F26Dot6::from_bits(math::mul14(amount, gs.freedom_vector.y)); - let count = gs.loop_counter; - gs.loop_counter = 1; - let did_iup = gs.did_iup_x && gs.did_iup_y; - for _ in 0..count { - let p = self.value_stack.pop_usize()?; - if gs.backward_compatibility { - if in_twilight - || (!did_iup - && ((gs.is_composite && gs.freedom_vector.y != 0) - || gs.zp2().is_touched(p, CoordAxis::Y)?)) - { - gs.move_zp2_point(p, dx, dy, true)?; - } - } else { - gs.move_zp2_point(p, dx, dy, true)?; - } - } - Ok(()) - } - - /// Move stack indirect relative point. - /// - /// MSIRP\[a\] (0x3A - 0x3B) - /// - /// a: 0: do not set rp0 to p - /// 1: set rp0 to p - /// - /// Pops: d: distance (F26Dot6) - /// p: point number - /// - /// Makes the distance between a point p and rp0 equal to the value - /// specified on the stack. The distance on the stack is in fractional - /// pixels (F26Dot6). An MSIRP has the same effect as a MIRP instruction - /// except that it takes its value from the stack rather than the Control - /// Value Table. As a result, the cut_in does not affect the results of a - /// MSIRP. Additionally, MSIRP is unaffected by the round_state. - /// - /// See - /// and - pub(super) fn op_msirp(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let distance = self.value_stack.pop_f26dot6()?; - let point_ix = self.value_stack.pop_usize()?; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp1, point_ix), (gs.zp0, gs.rp0)]) { - return Ok(()); - } - if gs.zp1.is_twilight() { - *gs.zp1_mut().point_mut(point_ix)? = gs.zp0().original(gs.rp0)?; - gs.move_original(gs.zp1, point_ix, distance)?; - *gs.zp1_mut().point_mut(point_ix)? = gs.zp1().original(point_ix)?; - } - let d = gs.project(gs.zp1().point(point_ix)?, gs.zp0().point(gs.rp0)?); - gs.move_point(gs.zp1, point_ix, distance.wrapping_sub(d))?; - gs.rp1 = gs.rp0; - gs.rp2 = point_ix; - if (opcode & 1) != 0 { - gs.rp0 = point_ix; - } - Ok(()) - } - - /// Move direct absolute point. - /// - /// MDAP\[a\] (0x2E - 0x2F) - /// - /// a: 0: do not round the value - /// 1: round the value - /// - /// Pops: p: point number - /// - /// Sets the reference points rp0 and rp1 equal to point p. If a=1, this - /// instruction rounds point p to the grid point specified by the state - /// variable round_state. If a=0, it simply marks the point as touched in - /// the direction(s) specified by the current freedom_vector. This command - /// is often used to set points in the twilight zone. - /// - /// See - /// and - pub(super) fn op_mdap(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let p = self.value_stack.pop_usize()?; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, p)]) { - gs.rp0 = p; - gs.rp1 = p; - return Ok(()); - } - let distance = if (opcode & 1) != 0 { - let cur_dist = gs.project(gs.zp0().point(p)?, Default::default()); - gs.round(cur_dist) - cur_dist - } else { - F26Dot6::ZERO - }; - gs.move_point(gs.zp0, p, distance)?; - gs.rp0 = p; - gs.rp1 = p; - Ok(()) - } - - /// Move indirect absolute point. - /// - /// MIAP\[a\] (0x3E - 0x3F) - /// - /// a: 0: do not round the distance and don't use control value cutin - /// 1: round the distance and use control value cutin - /// - /// Pops: n: CVT entry number - /// p: point number - /// - /// Moves point p to the absolute coordinate position specified by the nth - /// Control Value Table entry. The coordinate is measured along the current - /// projection_vector. If a=1, the position will be rounded as specified by - /// round_state. If a=1, and if the device space difference between the CVT - /// value and the original position is greater than the - /// control_value_cut_in, then the original position will be rounded - /// (instead of the CVT value.) - /// - /// See - /// and - pub(super) fn op_miap(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let cvt_entry = self.value_stack.pop_usize()?; - let point_ix = self.value_stack.pop_usize()?; - let mut distance = self.cvt.get(cvt_entry)?; - if gs.zp0.is_twilight() { - // Special behavior for twilight zone. - // - let fv = gs.freedom_vector; - let z = gs.zp0_mut(); - let original_point = z.original_mut(point_ix)?; - original_point.x = F26Dot6::from_bits(math::mul14(distance.to_bits(), fv.x)); - original_point.y = F26Dot6::from_bits(math::mul14(distance.to_bits(), fv.y)); - *z.point_mut(point_ix)? = *original_point; - } - let original_distance = gs.project(gs.zp0().point(point_ix)?, Default::default()); - if (opcode & 1) != 0 { - let delta = (distance.wrapping_sub(original_distance)).abs(); - if delta > gs.control_value_cutin { - distance = original_distance; - } - distance = gs.round(distance); - } - gs.move_point(gs.zp0, point_ix, distance.wrapping_sub(original_distance))?; - gs.rp0 = point_ix; - gs.rp1 = point_ix; - Ok(()) - } - - /// Move direct relative point. - /// - /// MDRP\[abcde\] (0xC0 - 0xDF) - /// - /// a: 0: do not set rp0 to point p after move - /// 1: do set rp0 to point p after move - /// b: 0: do not keep distance greater than or equal to minimum_distance - /// 1: keep distance greater than or equal to minimum_distance - /// c: 0: do not round distance - /// 1: round the distance - /// de: distance type for engine characteristic compensation - /// - /// Pops: p: point number - /// - /// MDRP moves point p along the freedom_vector so that the distance from - /// its new position to the current position of rp0 is the same as the - /// distance between the two points in the original uninstructed outline, - /// and then adjusts it to be consistent with the Boolean settings. Note - /// that it is only the original positions of rp0 and point p and the - /// current position of rp0 that determine the new position of point p - /// along the freedom_vector. - /// - /// See - /// and - pub(super) fn op_mdrp(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let p = self.value_stack.pop_usize()?; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp1, p), (gs.zp0, gs.rp0)]) { - gs.rp1 = gs.rp0; - gs.rp2 = p; - if (opcode & 16) != 0 { - gs.rp0 = p; - } - return Ok(()); - } - let mut original_distance = if gs.zp0.is_twilight() || gs.zp1.is_twilight() { - gs.dual_project(gs.zp1().original(p)?, gs.zp0().original(gs.rp0)?) - } else { - let v1 = gs.zp1().unscaled(p); - let v2 = gs.zp0().unscaled(gs.rp0); - let dist = gs.dual_project_unscaled(v1, v2); - F26Dot6::from_bits(math::mul(dist, gs.unscaled_to_pixels())) - }; - let cutin = gs.single_width_cutin; - let value = gs.single_width; - if cutin > F26Dot6::ZERO - && original_distance < value + cutin - && original_distance > value - cutin - { - original_distance = if original_distance >= F26Dot6::ZERO { - value - } else { - -value - }; - } - // round flag - let mut distance = if (opcode & 4) != 0 { - gs.round(original_distance) - } else { - original_distance - }; - // minimum distance flag - if (opcode & 8) != 0 { - let min_distance = gs.min_distance; - if original_distance >= F26Dot6::ZERO { - if distance < min_distance { - distance = min_distance; - } - } else if distance > -min_distance { - distance = -min_distance; - } - } - original_distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); - gs.move_point(gs.zp1, p, distance.wrapping_sub(original_distance))?; - gs.rp1 = gs.rp0; - gs.rp2 = p; - if (opcode & 16) != 0 { - gs.rp0 = p; - } - Ok(()) - } - - /// Move indirect relative point. - /// - /// MIRP\[abcde\] (0xE0 - 0xFF) - /// - /// a: 0: do not set rp0 to point p after move - /// 1: do set rp0 to point p after move - /// b: 0: do not keep distance greater than or equal to minimum_distance - /// 1: keep distance greater than or equal to minimum_distance - /// c: 0: do not round distance and do not look at control_value_cutin - /// 1: round the distance and look at control_value_cutin - /// de: distance type for engine characteristic compensation - /// - /// Pops: n: CVT entry number - /// p: point number - /// - /// A MIRP instruction makes it possible to preserve the distance between - /// two points subject to a number of qualifications. Depending upon the - /// setting of Boolean flag b, the distance can be kept greater than or - /// equal to the value established by the minimum_distance state variable. - /// Similarly, the instruction can be set to round the distance according - /// to the round_state graphics state variable. The value of the minimum - /// distance variable is the smallest possible value the distance between - /// two points can be rounded to. Additionally, if the c Boolean is set, - /// the MIRP instruction acts subject to the control_value_cut_in. If the - /// difference between the actual measurement and the value in the CVT is - /// sufficiently small (less than the cut_in_value), the CVT value will be - /// used and not the actual value. If the device space difference between - /// this distance from the CVT and the single_width_value is smaller than - /// the single_width_cut_in, then use the single_width_value rather than - /// the outline or Control Value Table distance. - /// - /// See - /// and - pub(super) fn op_mirp(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let n = (self.value_stack.pop()? + 1) as usize; - let p = self.value_stack.pop_usize()?; - if !gs.is_pedantic - && (!gs.in_bounds([(gs.zp1, p), (gs.zp0, gs.rp0)]) || (n > self.cvt.len())) - { - gs.rp1 = gs.rp0; - if (opcode & 16) != 0 { - gs.rp0 = p; - } - gs.rp2 = p; - return Ok(()); - } - let mut cvt_distance = if n == 0 { - F26Dot6::ZERO - } else { - self.cvt.get(n - 1)? - }; - // single width test - let cutin = gs.single_width_cutin; - let value = gs.single_width; - let mut delta = cvt_distance.wrapping_sub(value).abs(); - if delta < cutin { - cvt_distance = if cvt_distance >= F26Dot6::ZERO { - value - } else { - -value - }; - } - if gs.zp1.is_twilight() { - let fv = gs.freedom_vector; - let point = { - let d = cvt_distance.to_bits(); - let p2 = gs.zp0().original(gs.rp0)?; - let p1 = gs.zp1_mut().original_mut(p)?; - p1.x = p2.x + F26Dot6::from_bits(math::mul(d, fv.x)); - p1.y = p2.y + F26Dot6::from_bits(math::mul(d, fv.y)); - *p1 - }; - *gs.zp1_mut().point_mut(p)? = point; - } - let original_distance = gs.dual_project(gs.zp1().original(p)?, gs.zp0().original(gs.rp0)?); - let current_distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); - // auto flip test - if gs.auto_flip && (original_distance.to_bits() ^ cvt_distance.to_bits()) < 0 { - cvt_distance = -cvt_distance; - } - // control value cutin and round - let mut distance = if (opcode & 4) != 0 { - if gs.zp0 == gs.zp1 { - delta = cvt_distance.wrapping_sub(original_distance).abs(); - if delta > gs.control_value_cutin { - cvt_distance = original_distance; - } - } - gs.round(cvt_distance) - } else { - cvt_distance - }; - // minimum distance test - if (opcode & 8) != 0 { - let min_distance = gs.min_distance; - if original_distance >= F26Dot6::ZERO { - if distance < min_distance { - distance = min_distance - }; - } else if distance > -min_distance { - distance = -min_distance - } - } - gs.move_point(gs.zp1, p, distance.wrapping_sub(current_distance))?; - gs.rp1 = gs.rp0; - if (opcode & 16) != 0 { - gs.rp0 = p; - } - gs.rp2 = p; - Ok(()) - } - - /// Align relative point. - /// - /// ALIGNRP[] (0x3C) - /// - /// Pops: p: point number (uint32) - /// - /// Uses the loop counter. - /// - /// Reduces the distance between rp0 and point p to zero. Since distance - /// is measured along the projection_vector and movement is along the - /// freedom_vector, the effect of the instruction is to align points. - /// - /// See - /// and - pub(super) fn op_alignrp(&mut self) -> OpResult { - let gs = &mut self.graphics; - let count = gs.loop_counter; - gs.loop_counter = 1; - for _ in 0..count { - let p = self.value_stack.pop_usize()?; - let distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); - gs.move_point(gs.zp1, p, -distance)?; - } - Ok(()) - } - - /// Move point to intersection of two lines. - /// - /// ISECT[] (0x0F) - /// - /// Pops: b1: end point of line 2 - /// b0: start point of line 2 - /// a1: end point of line 1 - /// a0: start point of line 1 - /// p: point to move. - /// - /// Puts point p at the intersection of the lines A and B. The points a0 - /// and a1 define line A. Similarly, b0 and b1 define line B. ISECT - /// ignores the freedom_vector in moving point p. - /// - /// See - /// and - pub(super) fn op_isect(&mut self) -> OpResult { - let gs = &mut self.graphics; - let b1 = self.value_stack.pop_usize()?; - let b0 = self.value_stack.pop_usize()?; - let a1 = self.value_stack.pop_usize()?; - let a0 = self.value_stack.pop_usize()?; - let point_ix = self.value_stack.pop_usize()?; - // Lots of funky fixed point math so just map these to i32 to avoid - // a bunch of wrapping/unwrapping. - // To shreds you say! - let [pa0, pa1] = { - let z = gs.zp1(); - [z.point(a0)?, z.point(a1)?].map(|p| p.map(F26Dot6::to_bits)) - }; - let [pb0, pb1] = { - let z = gs.zp0(); - [z.point(b0)?, z.point(b1)?].map(|p| p.map(F26Dot6::to_bits)) - }; - let dbx = pb1.x - pb0.x; - let dby = pb1.y - pb0.y; - let dax = pa1.x - pa0.x; - let day = pa1.y - pa0.y; - let dx = pb0.x - pa0.x; - let dy = pb0.y - pa0.y; - use math::mul_div; - let discriminant = mul_div(dax, -dby, 0x40) + mul_div(day, dbx, 0x40); - let dotproduct = mul_div(dax, dbx, 0x40) + mul_div(day, dby, 0x40); - // Useful context from FreeType: - // - // "The discriminant above is actually a cross product of vectors - // da and db. Together with the dot product, they can be used as - // surrogates for sine and cosine of the angle between the vectors. - // Indeed, - // dotproduct = |da||db|cos(angle) - // discriminant = |da||db|sin(angle) - // We use these equations to reject grazing intersections by - // thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees." - // - // See - if 19 * discriminant.abs() > dotproduct.abs() { - let v = mul_div(dx, -dby, 0x40) + mul_div(dy, dbx, 0x40); - let x = mul_div(v, dax, discriminant); - let y = mul_div(v, day, discriminant); - let point = gs.zp2_mut().point_mut(point_ix)?; - point.x = F26Dot6::from_bits(pa0.x + x); - point.y = F26Dot6::from_bits(pa0.y + y); - } else { - let point = gs.zp2_mut().point_mut(point_ix)?; - point.x = F26Dot6::from_bits((pa0.x + pa1.x + pb0.x + pb1.x) / 4); - point.y = F26Dot6::from_bits((pa0.y + pa1.y + pb0.y + pb1.y) / 4); - } - gs.zp2_mut().touch(point_ix, CoordAxis::Both)?; - Ok(()) - } - - /// Align points. - /// - /// ALIGNPTS[] (0x27) - /// - /// Pops: p1: point number - /// p2: point number - /// - /// Makes the distance between point 1 and point 2 zero by moving both - /// along the freedom_vector to the average of both their projections - /// along the projection_vector. - /// - /// See - /// and - pub(super) fn op_alignpts(&mut self) -> OpResult { - let p2 = self.value_stack.pop_usize()?; - let p1 = self.value_stack.pop_usize()?; - let gs = &mut self.graphics; - let distance = F26Dot6::from_bits( - gs.project(gs.zp0().point(p2)?, gs.zp1().point(p1)?) - .to_bits() - / 2, - ); - gs.move_point(gs.zp1, p1, distance)?; - gs.move_point(gs.zp0, p2, -distance)?; - Ok(()) - } - - /// Interpolate point by last relative stretch. - /// - /// IP[] (0x39) - /// - /// Pops: p: point number - /// - /// Uses the loop counter. - /// - /// Moves point p so that its relationship to rp1 and rp2 is the same as it - /// was in the original uninstructed outline. Measurements are made along - /// the projection_vector, and movement to satisfy the interpolation - /// relationship is constrained to be along the freedom_vector. This - /// instruction is not valid if rp1 and rp2 have the same position on the - /// projection_vector. - /// - /// See - /// and - pub(super) fn op_ip(&mut self) -> OpResult { - let gs = &mut self.graphics; - let count = gs.loop_counter; - gs.loop_counter = 1; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, gs.rp1), (gs.zp1, gs.rp2)]) { - return Ok(()); - } - let in_twilight = gs.zp0.is_twilight() || gs.zp1.is_twilight() || gs.zp2.is_twilight(); - let orus_base = if in_twilight { - gs.zp0().original(gs.rp1)? - } else { - gs.zp0().unscaled(gs.rp1).map(F26Dot6::from_bits) - }; - let cur_base = gs.zp0().point(gs.rp1)?; - let old_range = if in_twilight { - gs.dual_project(gs.zp1().original(gs.rp2)?, orus_base) - } else { - gs.dual_project(gs.zp1().unscaled(gs.rp2).map(F26Dot6::from_bits), orus_base) - }; - let cur_range = gs.project(gs.zp1().point(gs.rp2)?, cur_base); - for _ in 0..count { - let point = self.value_stack.pop_usize()?; - if !gs.is_pedantic && !gs.in_bounds([(gs.zp2, point)]) { - continue; - } - let original_distance = if in_twilight { - gs.dual_project(gs.zp2().original(point)?, orus_base) - } else { - gs.dual_project(gs.zp2().unscaled(point).map(F26Dot6::from_bits), orus_base) - }; - let cur_distance = gs.project(gs.zp2().point(point)?, cur_base); - let new_distance = if original_distance != F26Dot6::ZERO { - if old_range != F26Dot6::ZERO { - F26Dot6::from_bits(math::mul_div( - original_distance.to_bits(), - cur_range.to_bits(), - old_range.to_bits(), - )) - } else { - original_distance - } - } else { - F26Dot6::ZERO - }; - gs.move_point(gs.zp2, point, new_distance.wrapping_sub(cur_distance))?; - } - Ok(()) - } - - /// Interpolate untouched points through the outline. - /// - /// IUP\[a\] (0x30 - 0x31) - /// - /// a: 0: interpolate in the y-direction - /// 1: interpolate in the x-direction - /// - /// Considers a glyph contour by contour, moving any untouched points in - /// each contour that are between a pair of touched points. If the - /// coordinates of an untouched point were originally between those of - /// the touched pair, it is linearly interpolated between the new - /// coordinates, otherwise the untouched point is shifted by the amount - /// the nearest touched point is shifted. - /// - /// See - /// and - pub(super) fn op_iup(&mut self, opcode: u8) -> OpResult { - let gs = &mut self.graphics; - let axis = if (opcode & 1) != 0 { - CoordAxis::X - } else { - CoordAxis::Y - }; - let mut run = true; - // In backward compatibility mode, allow IUP until it has been done on - // both axes. - if gs.backward_compatibility { - if gs.did_iup_x && gs.did_iup_y { - run = false; - } - if axis == CoordAxis::X { - gs.did_iup_x = true; - } else { - gs.did_iup_y = true; - } - } - if run { - gs.zone_mut(ZonePointer::Glyph).iup(axis)?; - } - Ok(()) - } - - /// Untouch point. - /// - /// UTP[] (0x29) - /// - /// Pops: p: point number (uint32) - /// - /// Marks point p as untouched. A point may be touched in the x direction, - /// the y direction, both, or neither. This instruction uses the current - /// freedom_vector to determine whether to untouch the point in the - /// x-direction, the y direction, or both. Points that are marked as - /// untouched will be moved by an IUP (interpolate untouched points) - /// instruction. Using UTP you can ensure that a point will be affected - /// by IUP even if it was previously touched. - /// - /// See - /// and - pub(super) fn op_utp(&mut self) -> OpResult { - let p = self.value_stack.pop_usize()?; - let coord_axis = match ( - self.graphics.freedom_vector.x != 0, - self.graphics.freedom_vector.y != 0, - ) { - (true, true) => Some(CoordAxis::Both), - (true, false) => Some(CoordAxis::X), - (false, true) => Some(CoordAxis::Y), - (false, false) => None, - }; - if let Some(coord_axis) = coord_axis { - self.graphics.zp0_mut().untouch(p, coord_axis)?; - } - Ok(()) - } - - /// Helper for FLIPRGON and FLIPRGOFF. - fn set_on_curve_for_range(&mut self, on: bool) -> OpResult { - let high_point = self.value_stack.pop_usize()?; - let low_point = self.value_stack.pop_usize()?; - // high_point is inclusive but Zone::set_on_curve takes an exclusive - // range - let high_point = high_point - .checked_add(1) - .ok_or(HintErrorKind::InvalidPointIndex(high_point))?; - // In backward compatibility mode, don't flip points after IUP has - // been done. - if self.graphics.backward_compatibility - && self.graphics.did_iup_x - && self.graphics.did_iup_y - { - return Ok(()); - } - self.graphics - .zone_mut(ZonePointer::Glyph) - .set_on_curve(low_point, high_point, on) - } -} - -#[cfg(test)] -mod tests { - use super::{super::MockEngine, math, CoordAxis, Engine, ZonePointer}; - use raw::{ - tables::glyf::{bytecode::Opcode, PointMarker}, - types::{F26Dot6, Point}, - }; - - #[test] - fn flip_point() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Points all start as off-curve in the mock engine. - // Flip every odd point in the first 10 - let count = 5; - // First, set the loop counter: - engine.value_stack.push(count).unwrap(); - engine.op_sloop().unwrap(); - // Now push the point indices - for i in (1..=9).step_by(2) { - engine.value_stack.push(i).unwrap(); - } - assert_eq!(engine.value_stack.len(), count as usize); - // And flip! - engine.op_flippt().unwrap(); - let flags = &engine.graphics.zones[1].flags; - for i in 0..10 { - // Odd points are now on-curve - assert_eq!(flags[i].is_on_curve(), i & 1 != 0); - } - } - - /// Backward compat + IUP state prevents flipping. - #[test] - fn state_prevents_flip_point() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Points all start as off-curve in the mock engine. - // Flip every odd point in the first 10 - let count = 5; - // First, set the loop counter: - engine.value_stack.push(count).unwrap(); - engine.op_sloop().unwrap(); - // Now push the point indices - for i in (1..=9).step_by(2) { - engine.value_stack.push(i).unwrap(); - } - assert_eq!(engine.value_stack.len(), count as usize); - // Prevent flipping - engine.graphics.backward_compatibility = true; - engine.graphics.did_iup_x = true; - engine.graphics.did_iup_y = true; - // But try anyway - engine.op_flippt().unwrap(); - let flags = &engine.graphics.zones[1].flags; - for i in 0..10 { - // All points are still off-curve - assert!(!flags[i].is_on_curve()); - } - } - - #[test] - fn flip_range_on_off() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Points all start as off-curve in the mock engine. - // Flip 10..=20 on - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(20).unwrap(); - engine.op_fliprgon().unwrap(); - for (i, flag) in engine.graphics.zones[1].flags.iter().enumerate() { - assert_eq!(flag.is_on_curve(), (10..=20).contains(&i)); - } - // Now flip 12..=15 off - engine.value_stack.push(12).unwrap(); - engine.value_stack.push(15).unwrap(); - engine.op_fliprgoff().unwrap(); - for (i, flag) in engine.graphics.zones[1].flags.iter().enumerate() { - assert_eq!( - flag.is_on_curve(), - (10..=11).contains(&i) || (16..=20).contains(&i) - ); - } - } - - /// Backward compat + IUP state prevents flipping. - #[test] - fn state_prevents_flip_range_on_off() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Prevent flipping - engine.graphics.backward_compatibility = true; - engine.graphics.did_iup_x = true; - engine.graphics.did_iup_y = true; - // Points all start as off-curve in the mock engine. - // Try to flip 10..=20 on - engine.value_stack.push(10).unwrap(); - engine.value_stack.push(20).unwrap(); - engine.op_fliprgon().unwrap(); - for flag in engine.graphics.zones[1].flags.iter() { - assert!(!flag.is_on_curve()); - } - // Reset all points to on - for flag in engine.graphics.zones[1].flags.iter_mut() { - flag.set_on_curve(); - } - // Now try to flip 12..=15 off - engine.value_stack.push(12).unwrap(); - engine.value_stack.push(15).unwrap(); - engine.op_fliprgoff().unwrap(); - for flag in engine.graphics.zones[1].flags.iter() { - assert!(flag.is_on_curve()); - } - } - - #[test] - fn untouch_point() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - // Touch all points in both axes to start. - let count = engine.graphics.zones[1].points.len(); - for i in 0..count { - engine.graphics.zones[1].touch(i, CoordAxis::Both).unwrap(); - } - let mut untouch = |point_ix: usize, fx, fy, marker| { - assert!(engine.graphics.zp0().flags[point_ix].has_marker(marker)); - // Untouch axis is based on freedom vector: - engine.graphics.freedom_vector.x = fx; - engine.graphics.freedom_vector.y = fy; - engine.value_stack.push(point_ix as i32).unwrap(); - engine.op_utp().unwrap(); - assert!(!engine.graphics.zp0().flags[point_ix].has_marker(marker)); - }; - // Untouch point 0 in x axis - untouch(0, 1, 0, PointMarker::TOUCHED_X); - // Untouch point 1 in y axis - untouch(1, 0, 1, PointMarker::TOUCHED_Y); - // untouch point 2 in both axes - untouch(2, 1, 1, PointMarker::TOUCHED); - } - - #[test] - fn shp() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp2 = ZonePointer::Glyph; - engine.graphics.rp2 = 1; - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - engine.value_stack.push(1).unwrap(); - engine.op_shp(0).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(136, -254)); - } - - #[test] - fn shc() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp2 = ZonePointer::Glyph; - engine.graphics.rp2 = 1; - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - engine.value_stack.push(0).unwrap(); - engine.op_shc(0).unwrap(); - let points = engine.graphics.zones[1] - .points - .iter() - .map(|p| p.map(F26Dot6::to_bits)) - .take(3) - .collect::>(); - assert_eq!( - points, - &[Point::new(4, 2), Point::new(132, -256), Point::new(4, 2),] - ); - } - - #[test] - fn shz() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp2 = ZonePointer::Glyph; - engine.graphics.rp2 = 1; - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - engine.value_stack.push(0).unwrap(); - engine.op_shz(0).unwrap(); - let points = engine.graphics.zones[1] - .points - .iter() - .map(|p| p.map(F26Dot6::to_bits)) - .take(3) - .collect::>(); - assert_eq!( - points, - &[Point::new(4, 2), Point::new(132, -256), Point::new(4, 2),] - ); - } - - #[test] - fn shpix() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp2 = ZonePointer::Glyph; - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - // point index - engine.value_stack.push(1).unwrap(); - // amount to move in pixels along freedom vector - engine.value_stack.push(42).unwrap(); - engine.op_shpix().unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(170, -237)); - } - - #[test] - fn msirp() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp1 = ZonePointer::Glyph; - let point = engine.graphics.zones[1].point_mut(1).unwrap(); - point.x = F26Dot6::from_bits(132); - point.y = F26Dot6::from_bits(-256); - // point index - engine.value_stack.push(1).unwrap(); - // amount to move in pixels along freedom vector - engine.value_stack.push(-42).unwrap(); - engine.op_msirp(0).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(91, -277)); - assert_eq!(engine.graphics.rp0, 0); - // opcode with bit 0 set changes rp0 to point_ix - engine.value_stack.push(4).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_msirp(1).unwrap(); - assert_eq!(engine.graphics.rp0, 4); - } - - #[test] - fn mdap() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - // with rounding - engine.set_point_f26dot6(1, 1, (132, -256)); - engine.value_stack.push(1).unwrap(); - engine.op_mdap(1).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(128, -258)); - // without rounding - engine.set_point_f26dot6(1, 2, (132, -256)); - engine.value_stack.push(2).unwrap(); - engine.op_mdap(0).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(132, -256)); - } - - #[test] - fn miap() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - // set a CVT distance - engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); - // with rounding - engine.set_point_f26dot6(1, 1, (132, -256)); - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_miap(1).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); - // without rounding - engine.set_point_f26dot6(1, 2, (132, -256)); - engine.value_stack.push(2).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_miap(0).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(171, -236)); - } - - /// Tests bit 'a' of MDRP which just sets rp0 to the adjusted point - /// after move. - #[test] - fn mdrp_rp0() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.graphics.rp0 = 0; - // Don't change rp0 - engine.value_stack.push(1).unwrap(); - engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); - assert_eq!(engine.graphics.rp0, 0); - // Change rp0 - engine.value_stack.push(1).unwrap(); - engine.op_mdrp(Opcode::MDRP10000 as _).unwrap(); - assert_eq!(engine.graphics.rp0, 1); - } - - /// Test bit "b" which controls whether distances are adjusted - /// to the minimum_distance field of GraphicsState. - #[test] - fn mdrp_mindist() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - // without min distance check - engine.set_point_f26dot6(1, 1, (132, -256)); - engine.value_stack.push(1).unwrap(); - engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(128, -258)); - // with min distance check - engine.set_point_f26dot6(1, 2, (132, -256)); - engine.value_stack.push(2).unwrap(); - engine.op_mdrp(Opcode::MDRP01000 as _).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); - } - - /// Test bit "c" which controls whether distances are rounded. - #[test] - fn mdrp_round() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.op_rthg().unwrap(); - // without rounding - engine.set_point_f26dot6(1, 1, (132, -231)); - engine.value_stack.push(1).unwrap(); - engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(119, -238)); - // with rounding - engine.set_point_f26dot6(1, 2, (132, -231)); - engine.value_stack.push(2).unwrap(); - engine.op_mdrp(Opcode::MDRP00100 as _).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); - } - - /// Tests bit 'a' of MIRP which just sets rp0 to the adjusted point - /// after move. - #[test] - fn mirp_rp0() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.graphics.rp0 = 0; - // Don't change rp0 - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); - assert_eq!(engine.graphics.rp0, 0); - // Change rp0 - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP10000 as _).unwrap(); - assert_eq!(engine.graphics.rp0, 1); - } - - /// Test bit "b" which controls whether distances are adjusted - /// to the minimum_distance field of GraphicsState. - #[test] - fn mirp_mindist() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - // set a CVT distance - engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); - // without min distance check - engine.set_point_f26dot6(1, 1, (132, -256)); - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(171, -236)); - // with min distance check - engine.set_point_f26dot6(1, 2, (132, -256)); - engine.value_stack.push(2).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP01000 as _).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); - } - - /// Test bit "c" which controls whether distances are rounded. - #[test] - fn mirp_round() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - // set a CVT distance - engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); - engine.op_rthg().unwrap(); - // without rounding - engine.set_point_f26dot6(1, 1, (132, -231)); - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(162, -216)); - // with rounding - engine.set_point_f26dot6(1, 2, (132, -231)); - engine.value_stack.push(2).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_mirp(Opcode::MIRP00100 as _).unwrap(); - let point = engine.graphics.zones[1].point(2).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); - } - - #[test] - fn alignrp() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp1 = ZonePointer::Glyph; - engine.graphics.rp0 = 0; - engine.set_point_f26dot6(1, 0, (132, -231)); - engine.set_point_f26dot6(1, 1, (-72, 109)); - engine.value_stack.push(1).unwrap(); - engine.op_alignrp().unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(-45, 122)); - } - - #[test] - fn isect() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp1 = ZonePointer::Glyph; - engine.graphics.rp0 = 0; - // Two points for line 1 - engine.set_point_f26dot6(1, 0, (0, 0)); - engine.set_point_f26dot6(1, 1, (100, 100)); - // And two more for line 2 - engine.set_point_f26dot6(1, 2, (0, 100)); - engine.set_point_f26dot6(1, 3, (100, 0)); - // Push point numbers: first is the point where the - // intersection should be stored. - for ix in [4, 0, 1, 2, 3] { - engine.value_stack.push(ix).unwrap(); - } - engine.op_isect().unwrap(); - let point = engine.graphics.zones[1].point(4).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(50, 50)); - } - - #[test] - fn alignpts() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp1 = ZonePointer::Glyph; - engine.set_point_f26dot6(1, 0, (132, -231)); - engine.set_point_f26dot6(1, 1, (-72, 109)); - engine.value_stack.push(0).unwrap(); - engine.value_stack.push(1).unwrap(); - engine.op_alignpts().unwrap(); - let p1 = engine.graphics.zones[1].point(0).unwrap(); - let p2 = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(p1.map(F26Dot6::to_bits), Point::new(119, -238)); - assert_eq!(p2.map(F26Dot6::to_bits), Point::new(-59, 116)); - } - - #[test] - fn ip() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - set_test_vectors(&mut engine); - engine.graphics.backward_compatibility = false; - engine.graphics.zp0 = ZonePointer::Glyph; - engine.graphics.zp1 = ZonePointer::Glyph; - engine.graphics.zp2 = ZonePointer::Glyph; - engine.graphics.rp1 = 2; - engine.graphics.rp2 = 3; - engine.set_point_f26dot6(1, 2, (72, -109)); - engine.set_point_f26dot6(1, 1, (132, -231)); - engine.value_stack.push(1).unwrap(); - engine.op_ip().unwrap(); - let point = engine.graphics.zones[1].point(1).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); - } - - #[test] - fn iup_flags() { - // IUP shift and interpolate logic is tested in ../zone.rs so just - // check the flags here. - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - assert!(!engine.graphics.did_iup_x); - assert!(!engine.graphics.did_iup_y); - // IUP[y] - engine.op_iup(0).unwrap(); - assert!(!engine.graphics.did_iup_x); - assert!(engine.graphics.did_iup_y); - // IUP[x] - engine.op_iup(1).unwrap(); - assert!(engine.graphics.did_iup_x); - assert!(engine.graphics.did_iup_y); - } - - // Add with overflow caught by fuzzer: - // https://issues.oss-fuzz.com/issues/377736138 - #[test] - fn flip_region_avoid_overflow() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - engine.value_stack.push(1).unwrap(); - engine.value_stack.push(-1).unwrap(); - // Just don't panic - let _ = engine.set_on_curve_for_range(true); - } - - fn set_test_vectors(engine: &mut Engine) { - let v = math::normalize14(100, 50); - engine.graphics.proj_vector = v; - engine.graphics.dual_proj_vector = v; - engine.graphics.freedom_vector = v; - engine.graphics.update_projection_state(); - } - - impl Engine<'_> { - fn set_point_f26dot6(&mut self, zone_ix: usize, point_ix: usize, xy: (i32, i32)) { - let p = self.graphics.zones[zone_ix].point_mut(point_ix).unwrap(); - p.x = F26Dot6::from_bits(xy.0); - p.y = F26Dot6::from_bits(xy.1); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -//! Compensating for the engine characteristics (rounding). -//! -//! Implements 4 instructions. -//! -//! See - -use super::{Engine, OpResult}; - -impl Engine<'_> { - /// Round value. - /// - /// ROUND\[ab\] (0x68 - 0x6B) - /// - /// Pops: n1 - /// Pushes: n2 - /// - /// Rounds a value according to the state variable round_state while - /// compensating for the engine. n1 is popped off the stack and, - /// depending on the engine characteristics, is increased or decreased - /// by a set amount. The number obtained is then rounded and pushed - /// back onto the stack as n2. - /// - /// See - /// and - pub(super) fn op_round(&mut self) -> OpResult { - let n1 = self.value_stack.pop_f26dot6()?; - let n2 = self.graphics.round(n1); - self.value_stack.push(n2.to_bits()) - } -} - -#[cfg(test)] -mod tests { - use super::super::{super::round::RoundMode, MockEngine}; - - #[test] - fn round() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - use RoundMode::*; - let cases = [ - (Grid, &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)]), - ( - HalfGrid, - &[(0, 32), (32, 32), (-32, -32), (64, 96), (50, 32)], - ), - ( - DoubleGrid, - &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 64)], - ), - (DownToGrid, &[(0, 0), (32, 0), (-32, 0), (64, 64), (50, 0)]), - ( - UpToGrid, - &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], - ), - (Off, &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 50)]), - ]; - for (mode, values) in cases { - match mode { - Grid => engine.op_rtg().unwrap(), - HalfGrid => engine.op_rthg().unwrap(), - DoubleGrid => engine.op_rtdg().unwrap(), - DownToGrid => engine.op_rdtg().unwrap(), - UpToGrid => engine.op_rutg().unwrap(), - Off => engine.op_roff().unwrap(), - _ => unreachable!(), - } - for (input, expected) in values { - engine.value_stack.push(*input).unwrap(); - engine.op_round().unwrap(); - let result = engine.value_stack.pop().unwrap(); - assert_eq!(*expected, result); - } - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,224 +0,0 @@ -//! Managing the stack and pushing data onto the interpreter stack. -//! -//! Implements 26 instructions. -//! -//! See -//! and - -use read_fonts::tables::glyf::bytecode::InlineOperands; - -use super::{Engine, OpResult}; - -impl Engine<'_> { - /// Duplicate top stack element. - /// - /// DUP[] (0x20) - /// - /// Pops: e - /// Pushes: e, e - /// - /// Duplicates the element at the top of the stack. - /// - /// See - /// and - pub(super) fn op_dup(&mut self) -> OpResult { - self.value_stack.dup() - } - - /// Pop top stack element. - /// - /// POP[] (0x21) - /// - /// Pops: e - /// - /// Pops the top element of the stack. - /// - /// See - /// and - pub(super) fn op_pop(&mut self) -> OpResult { - self.value_stack.pop()?; - Ok(()) - } - - /// Clear the entire stack. - /// - /// CLEAR[] (0x22) - /// - /// Pops: all the items on the stack - /// - /// Clears all elements from the stack. - /// - /// See - /// and - pub(super) fn op_clear(&mut self) -> OpResult { - self.value_stack.clear(); - Ok(()) - } - - /// Swap the top two elements on the stack. - /// - /// SWAP[] (0x23) - /// - /// Pops: e2, e1 - /// Pushes: e1, e2 - /// - /// Swaps the top two elements of the stack making the old top element the - /// second from the top and the old second element the top element. - /// - /// See - /// and - pub(super) fn op_swap(&mut self) -> OpResult { - self.value_stack.swap() - } - - /// Returns the depth of the stack. - /// - /// DEPTH[] (0x24) - /// - /// Pushes: n; number of elements - /// - /// Pushes n, the number of elements currently in the stack onto the stack. - /// - /// See - /// and - pub(super) fn op_depth(&mut self) -> OpResult { - let n = self.value_stack.len(); - self.value_stack.push(n as i32) - } - - /// Copy the indexed element to the top of the stack. - /// - /// CINDEX[] (0x25) - /// - /// Pops: k: stack element number - /// Pushes: ek: indexed element - /// - /// Puts a copy of the kth stack element on the top of the stack. - /// - /// See - /// and - pub(super) fn op_cindex(&mut self) -> OpResult { - self.value_stack.copy_index() - } - - /// Move the indexed element to the top of the stack. - /// - /// MINDEX[] (0x26) - /// - /// Pops: k: stack element number - /// Pushes: ek: indexed element - /// - /// Moves the indexed element to the top of the stack. - /// - /// See - /// and - pub(super) fn op_mindex(&mut self) -> OpResult { - self.value_stack.move_index() - } - - /// Roll the top three stack elements. - /// - /// ROLL[] (0x8a) - /// - /// Pops: a, b, c (top three stack elements) - /// Pushes: b, a, c (elements reordered) - /// - /// Performs a circular shift of the top three objects on the stack with - /// the effect being to move the third element to the top of the stack - /// and to move the first two elements down one position. ROLL is - /// equivalent to MINDEX[] 3. - /// - /// See - /// and - pub(super) fn op_roll(&mut self) -> OpResult { - self.value_stack.roll() - } - - /// Push data onto the interpreter stack. - /// - /// NPUSHB[] (0x8a) - /// - /// Takes n unsigned bytes from the instruction stream, where n is an - /// unsigned integer in the range (0..255), and pushes them onto the stack. - /// n itself is not pushed onto the stack. - /// - /// NPUSHW[] (0x41) - /// - /// Takes n 16-bit signed words from the instruction stream, where n is an - /// unsigned integer in the range (0..255), and pushes them onto the stack. - /// n itself is not pushed onto the stack. - /// - /// PUSHB\[abc\] (0xB0 - 0xB7) - /// - /// Takes the specified number of bytes from the instruction stream and - /// pushes them onto the interpreter stack. - /// The variables a, b, and c are binary digits representing numbers from - /// 000 to 111 (0-7 in binary). Because the actual number of bytes (n) is - /// from 1 to 8, 1 is automatically added to the ABC figure to obtain the - /// actual number of bytes pushed. - /// - /// PUSHW\[abc\] (0xB8 - 0xBF) - /// - /// Takes the specified number of words from the instruction stream and - /// pushes them onto the interpreter stack. - /// The variables a, b, and c are binary digits representing numbers from - /// 000 to 111 (0-7 binary). Because the actual number of bytes (n) is from - /// 1 to 8, 1 is automatically added to the abc figure to obtain the actual - /// number of bytes pushed. - /// - /// See - /// and - pub(super) fn op_push(&mut self, operands: &InlineOperands) -> OpResult { - self.value_stack.push_inline_operands(operands) - } -} - -#[cfg(test)] -mod tests { - use super::super::MockEngine; - use read_fonts::tables::glyf::bytecode::MockInlineOperands; - - #[test] - fn stack_ops() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let byte_args = MockInlineOperands::from_bytes(&[2, 4, 6, 8]); - let word_args = MockInlineOperands::from_words(&[-2000, 4000, -6000, 8000]); - let initial_stack = byte_args - .operands() - .values() - .chain(word_args.operands().values()) - .collect::>(); - // Push instructions - engine.op_push(&byte_args.operands()).unwrap(); - engine.op_push(&word_args.operands()).unwrap(); - assert_eq!(engine.value_stack.values(), initial_stack); - // DEPTH[] - engine.op_depth().unwrap(); - assert_eq!( - engine.value_stack.pop().ok(), - Some(initial_stack.len() as i32) - ); - // POP[] - engine.op_pop().unwrap(); - engine.op_pop().unwrap(); - assert_eq!( - engine.value_stack.values(), - &initial_stack[..initial_stack.len() - 2] - ); - // SWAP[] - engine.op_swap().unwrap(); - assert_eq!(&engine.value_stack.values()[4..], &[4000, -2000]); - // ROLL[] - engine.op_roll().unwrap(); - assert_eq!(&engine.value_stack.values()[3..], &[4000, -2000, 8]); - // CINDEX[] - engine.value_stack.push(4).unwrap(); - engine.op_cindex().unwrap(); - assert_eq!(engine.value_stack.peek(), Some(6)); - // MINDEX[] - engine.value_stack.push(3).unwrap(); - engine.op_mindex().unwrap(); - assert_eq!(engine.value_stack.peek(), Some(-2000)); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,110 +0,0 @@ -//! Managing the storage area. -//! -//! Implements 2 instructions. -//! -//! See - -use super::{Engine, OpResult}; - -impl Engine<'_> { - /// Read store. - /// - /// RS[] (0x43) - /// - /// Pops: location: Storage Area location - /// Pushes: value: Storage Area value - /// - /// This instruction reads a 32 bit value from the Storage Area location - /// popped from the stack and pushes the value read onto the stack. It pops - /// an address from the stack and pushes the value found in that Storage - /// Area location to the top of the stack. The number of available storage - /// locations is specified in the maxProfile table in the font file. - /// - /// See - /// and - pub(super) fn op_rs(&mut self) -> OpResult { - let location = self.value_stack.pop_usize()?; - let maybe_value = self.storage.get(location); - let value = if self.graphics.is_pedantic { - maybe_value? - } else { - maybe_value.unwrap_or(0) - }; - self.value_stack.push(value) - } - - /// Write store. - /// - /// WS[] (0x42) - /// - /// Pops: value: Storage Area value, - /// location: Storage Area location - /// - /// This instruction writes a 32 bit value into the storage location - /// indexed by locations. It works by popping a value and then a location - /// from the stack. The value is placed in the Storage Area location - /// specified by that address. The number of storage locations is specified - /// in the maxProfile table in the font file. - /// - /// See - /// and - pub(super) fn op_ws(&mut self) -> OpResult { - let value = self.value_stack.pop()?; - let location = self.value_stack.pop_usize()?; - let result = self.storage.set(location, value); - if self.graphics.is_pedantic { - result - } else { - Ok(()) - } - } -} - -#[cfg(test)] -mod tests { - use super::super::{HintErrorKind, MockEngine}; - - #[test] - fn write_read() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.value_stack.push(i * 2).unwrap(); - engine.op_ws().unwrap(); - } - for i in 0..8 { - engine.value_stack.push(i).unwrap(); - engine.op_rs().unwrap(); - assert_eq!(engine.value_stack.pop().unwrap(), i * 2); - } - } - - #[test] - fn pedantry() { - let mut mock = MockEngine::new(); - let mut engine = mock.engine(); - let oob_index = 1000; - // Disable pedantic mode: OOB writes are ignored, OOB reads - // push 0 - engine.graphics.is_pedantic = false; - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - engine.op_ws().unwrap(); - engine.value_stack.push(oob_index).unwrap(); - engine.op_rs().unwrap(); - // Enable pedantic mode: OOB reads/writes error - engine.graphics.is_pedantic = true; - engine.value_stack.push(oob_index).unwrap(); - engine.value_stack.push(0).unwrap(); - assert_eq!( - engine.op_ws(), - Err(HintErrorKind::InvalidStorageIndex(oob_index as _)) - ); - engine.value_stack.push(oob_index).unwrap(); - assert_eq!( - engine.op_rs(), - Err(HintErrorKind::InvalidStorageIndex(oob_index as _)) - ); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -//! Hinting error definitions. - -use read_fonts::tables::glyf::bytecode::{DecodeError, Opcode}; - -use super::program::Program; -use crate::GlyphId; - -/// Errors that may occur when interpreting TrueType bytecode. -#[derive(Clone, PartialEq, Debug)] -pub enum HintErrorKind { - UnexpectedEndOfBytecode, - UnhandledOpcode(Opcode), - DefinitionInGlyphProgram, - NestedDefinition, - DefinitionTooLarge, - TooManyDefinitions, - InvalidDefinition(usize), - ValueStackOverflow, - ValueStackUnderflow, - CallStackOverflow, - CallStackUnderflow, - InvalidStackValue(i32), - InvalidPointIndex(usize), - InvalidPointRange(usize, usize), - InvalidContourIndex(usize), - InvalidCvtIndex(usize), - InvalidStorageIndex(usize), - DivideByZero, - InvalidZoneIndex(i32), - NegativeLoopCounter, - InvalidJump, - ExceededExecutionBudget, -} - -impl core::fmt::Display for HintErrorKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::UnexpectedEndOfBytecode => write!(f, "unexpected end of bytecode"), - Self::UnhandledOpcode(opcode) => write!(f, "unhandled instruction opcode {opcode}"), - Self::DefinitionInGlyphProgram => { - write!( - f, - "function or instruction definition present in glyph program" - ) - } - Self::NestedDefinition => write!(f, "nested function or instruction definition"), - Self::DefinitionTooLarge => write!( - f, - "function or instruction definition exceeded the maximum size of 64k" - ), - Self::TooManyDefinitions => write!(f, "too many function or instruction definitions"), - Self::InvalidDefinition(key) => { - write!(f, "function or instruction definition {key} not found") - } - Self::ValueStackOverflow => write!(f, "value stack overflow"), - Self::ValueStackUnderflow => write!(f, "value stack underflow"), - Self::CallStackOverflow => write!(f, "call stack overflow"), - Self::CallStackUnderflow => write!(f, "call stack underflow"), - Self::InvalidStackValue(value) => write!( - f, - "stack value {value} was invalid for the current operation" - ), - Self::InvalidPointIndex(index) => write!(f, "point index {index} was out of bounds"), - Self::InvalidPointRange(start, end) => { - write!(f, "point range {start}..{end} was out of bounds") - } - Self::InvalidContourIndex(index) => { - write!(f, "contour index {index} was out of bounds") - } - Self::InvalidCvtIndex(index) => write!(f, "cvt index {index} was out of bounds"), - Self::InvalidStorageIndex(index) => { - write!(f, "storage area index {index} was out of bounds") - } - Self::DivideByZero => write!(f, "attempt to divide by 0"), - Self::InvalidZoneIndex(index) => write!( - f, - "zone index {index} was invalid (only 0 or 1 are permitted)" - ), - Self::NegativeLoopCounter => { - write!(f, "attempt to set the loop counter to a negative value") - } - Self::InvalidJump => write!(f, "the target of a jump instruction was invalid"), - Self::ExceededExecutionBudget => write!(f, "too many instructions executed"), - } - } -} - -impl From for HintErrorKind { - fn from(_: DecodeError) -> Self { - Self::UnexpectedEndOfBytecode - } -} - -/// Hinting error with additional context. -#[derive(Clone, Debug)] -pub struct HintError { - pub program: Program, - pub glyph_id: Option, - pub pc: usize, - pub opcode: Option, - pub kind: HintErrorKind, -} - -impl core::fmt::Display for HintError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.program { - Program::ControlValue => write!(f, "prep")?, - Program::Font => write!(f, "fpgm")?, - Program::Glyph => write!(f, "glyf")?, - } - if let Some(glyph_id) = self.glyph_id { - write!(f, "[{}]", glyph_id.to_u32())?; - } - let (opcode, colon) = match self.opcode { - Some(opcode) => (opcode.name(), ":"), - _ => ("", ""), - }; - write!(f, "@{}:{opcode}{colon} {}", self.pc, self.kind) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,316 +0,0 @@ -//! Graphics state for the TrueType interpreter. - -use super::{ - round::RoundState, - zone::{Zone, ZonePointer}, - F26Dot6, Point, Target, -}; -use core::ops::{Deref, DerefMut}; - -/// Describes the axis to which a measurement or point movement operation -/// applies. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub enum CoordAxis { - #[default] - Both, - X, - Y, -} - -/// Context in which instructions are executed. -/// -/// See -#[derive(Debug)] -pub struct GraphicsState<'a> { - /// Fields of the graphics state that persist between calls to the interpreter. - pub retained: RetainedGraphicsState, - /// A unit vector whose direction establishes an axis along which - /// distances are measured. - /// - /// See - pub proj_vector: Point, - /// Current axis for the projection vector. - pub proj_axis: CoordAxis, - /// A second projection vector set to a line defined by the original - /// outline location of two points. The dual projection vector is used - /// when it is necessary to measure distances from the scaled outline - /// before any instructions were executed. - /// - /// See - pub dual_proj_vector: Point, - /// Current axis for the dual projection vector. - pub dual_proj_axis: CoordAxis, - /// A unit vector that establishes an axis along which points can move. - /// - /// See - pub freedom_vector: Point, - /// Current axis for point movement. - pub freedom_axis: CoordAxis, - /// Dot product of freedom and projection vectors. - pub fdotp: i32, - /// Determines the manner in which values are rounded. - /// - /// See - pub round_state: RoundState, - /// First reference point. - /// - /// See - pub rp0: usize, - /// Second reference point. - /// - /// See - pub rp1: usize, - /// Third reference point. - /// - /// See - pub rp2: usize, - /// Makes it possible to repeat certain instructions a designated number of - /// times. The default value of one assures that unless the value of loop - /// is altered, these instructions will execute one time. - /// - /// See - pub loop_counter: u32, - /// First zone pointer. - /// - /// See - pub zp0: ZonePointer, - /// Second zone pointer. - /// - /// See - pub zp1: ZonePointer, - /// Third zone pointer. - /// - /// See - pub zp2: ZonePointer, - /// Outline data for each zone. - /// - /// This array contains the twilight and glyph zones, in that order. - pub zones: [Zone<'a>; 2], - /// True if the current glyph is a composite. - pub is_composite: bool, - /// If true, enables a set of backward compatibility heuristics that - /// prevent certain modifications to the outline. The purpose is to - /// support "modern" vertical only hinting that attempts to preserve - /// outline shape and metrics in the horizontal direction. This is - /// enabled by default, but fonts (and specific glyphs) can opt out - /// of this behavior using the INSTCTRL instruction. In practice, - /// opting out is usually only done by "ClearType native" fonts. - /// - /// See - /// for more background and some gory details. - /// - /// Defaults to true. - /// - /// See - pub backward_compatibility: bool, - /// If true, enables more strict error checking. - /// - /// Defaults to false. - /// - /// See - pub is_pedantic: bool, - /// Set to true when IUP has been executed in the horizontal direction. - pub did_iup_x: bool, - /// Set to true when IUP has been executed in the vertical direction. - pub did_iup_y: bool, -} - -impl GraphicsState<'_> { - /// Returns the factor for scaling unscaled points to pixels. - /// - /// For composite glyphs, "unscaled" points are already scaled so we - /// return the identity. - pub fn unscaled_to_pixels(&self) -> i32 { - if self.is_composite { - 1 << 16 - } else { - self.scale - } - } - - /// Resets the non-retained portions of the graphics state. - pub fn reset(&mut self) { - let GraphicsState { - retained, - zones, - is_composite, - .. - } = core::mem::take(self); - *self = GraphicsState { - retained, - zones, - is_composite, - ..Default::default() - }; - self.update_projection_state(); - } - - /// Resets the retained portion of the graphics state to default - /// values while saving the user instance settings. - pub fn reset_retained(&mut self) { - let scale = self.scale; - let ppem = self.ppem; - let mode = self.target; - self.retained = RetainedGraphicsState { - scale, - ppem, - target: mode, - ..Default::default() - } - } -} - -impl Default for GraphicsState<'_> { - fn default() -> Self { - // For table of default values, see - // All vectors are set to the x-axis (normalized in 2.14) - let vector = Point::new(0x4000, 0); - Self { - retained: RetainedGraphicsState::default(), - proj_vector: vector, - proj_axis: CoordAxis::Both, - dual_proj_vector: vector, - dual_proj_axis: CoordAxis::Both, - freedom_vector: vector, - freedom_axis: CoordAxis::Both, - fdotp: 0x4000, - round_state: RoundState::default(), - rp0: 0, - rp1: 0, - rp2: 0, - loop_counter: 1, - zp0: ZonePointer::default(), - zp1: ZonePointer::default(), - zp2: ZonePointer::default(), - zones: [Zone::default(), Zone::default()], - is_composite: false, - backward_compatibility: true, - is_pedantic: false, - did_iup_x: false, - did_iup_y: false, - } - } -} - -/// The persistent graphics state. -/// -/// Some of the graphics state is set by the control value program and -/// persists between runs of the interpreter. This struct captures that -/// state. -/// -/// See -#[derive(Copy, Clone, Debug)] -pub struct RetainedGraphicsState { - /// Controls whether the sign of control value table entries will be - /// changed to match the sign of the actual distance measurement with - /// which it is compared. - /// - /// See - pub auto_flip: bool, - /// Limits the regularizing effects of control value table entries to - /// cases where the difference between the table value and the measurement - /// taken from the original outline is sufficiently small. - /// - /// See - pub control_value_cutin: F26Dot6, - /// Establishes the base value used to calculate the range of point sizes - /// to which a given DELTAC[] or DELTAP[] instruction will apply. - /// - /// See - pub delta_base: u16, - /// Determines the range of movement and smallest magnitude of movement - /// (the step) in a DELTAC[] or DELTAP[] instruction. - /// - /// See - pub delta_shift: u16, - /// Makes it possible to turn off instructions under some circumstances. - /// When set to TRUE, no instructions will be executed - /// - /// See - pub instruct_control: u8, - /// Establishes the smallest possible value to which a distance will be - /// rounded. - /// - /// See - pub min_distance: F26Dot6, - /// Determines whether the interpreter will activate dropout control for - /// the current glyph. - /// - /// See - pub scan_control: bool, - /// Type associated with `scan_control`. - pub scan_type: i32, - /// The distance difference below which the interpreter will replace a - /// CVT distance or an actual distance in favor of the single width value. - /// - /// See - pub single_width_cutin: F26Dot6, - /// The value used in place of the control value table distance or the - /// actual distance value when the difference between that distance and - /// the single width value is less than the single width cut-in. - /// - /// See - pub single_width: F26Dot6, - /// The user requested hinting target. - pub target: Target, - /// The scale factor for the current instance. Conversion from font units - /// to 26.6 for current ppem. - pub scale: i32, - /// The nominal pixels per em value for the current instance. - pub ppem: i32, - /// True if a rotation is being applied. - pub is_rotated: bool, - /// True if a non-uniform scale is being applied. - pub is_stretched: bool, -} - -impl RetainedGraphicsState { - pub fn new(scale: i32, ppem: i32, target: Target) -> Self { - Self { - scale, - ppem, - target, - ..Default::default() - } - } -} - -impl Default for RetainedGraphicsState { - fn default() -> Self { - // For table of default values, see - Self { - auto_flip: true, - // 17/16 pixels in 26.6 - // (17 * 64 / 16) = 68 - control_value_cutin: F26Dot6::from_bits(68), - delta_base: 9, - delta_shift: 3, - instruct_control: 0, - // 1 pixel in 26.6 - min_distance: F26Dot6::from_bits(64), - scan_control: false, - scan_type: 0, - single_width_cutin: F26Dot6::ZERO, - single_width: F26Dot6::ZERO, - target: Default::default(), - scale: 0, - ppem: 0, - is_rotated: false, - is_stretched: false, - } - } -} - -impl Deref for GraphicsState<'_> { - type Target = RetainedGraphicsState; - - fn deref(&self) -> &Self::Target { - &self.retained - } -} - -impl DerefMut for GraphicsState<'_> { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.retained - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,275 +0,0 @@ -//! Instance state for TrueType hinting. - -use super::{ - super::Outlines, - cow_slice::CowSlice, - definition::{Definition, DefinitionMap, DefinitionState}, - engine::Engine, - error::HintError, - graphics::RetainedGraphicsState, - program::{Program, ProgramState}, - value_stack::ValueStack, - zone::Zone, - HintOutline, PointFlags, Target, -}; -use alloc::vec::Vec; -use raw::{ - types::{F26Dot6, F2Dot14, Fixed, Point}, - TableProvider, -}; - -#[derive(Clone, Default)] -pub struct HintInstance { - functions: Vec, - instructions: Vec, - cvt: Vec, - storage: Vec, - graphics: RetainedGraphicsState, - twilight_scaled: Vec>, - twilight_original_scaled: Vec>, - twilight_flags: Vec, - axis_count: u16, - max_stack: usize, -} - -impl HintInstance { - pub fn reconfigure( - &mut self, - outlines: &Outlines, - scale: i32, - ppem: i32, - target: Target, - coords: &[F2Dot14], - ) -> Result<(), HintError> { - self.setup(outlines, scale, coords); - let twilight_contours = [self.twilight_scaled.len() as u16]; - let twilight = Zone::new( - &[], - &mut self.twilight_original_scaled, - &mut self.twilight_scaled, - &mut self.twilight_flags, - &twilight_contours, - ); - let glyph = Zone::default(); - let mut stack_buf = vec![0; self.max_stack]; - let value_stack = ValueStack::new(&mut stack_buf, false); - let graphics = RetainedGraphicsState::new(scale, ppem, target); - let mut engine = Engine::new( - outlines, - ProgramState::new(outlines.fpgm, outlines.prep, &[], Program::Font), - graphics, - DefinitionState::new( - DefinitionMap::Mut(&mut self.functions), - DefinitionMap::Mut(&mut self.instructions), - ), - CowSlice::new_mut(&mut self.cvt), - CowSlice::new_mut(&mut self.storage), - value_stack, - twilight, - glyph, - self.axis_count, - coords, - false, - ); - // Run the font program (fpgm) - engine.run_program(Program::Font, false)?; - // Run the control value program (prep) - engine.run_program(Program::ControlValue, false)?; - // Save the retained state from the CV program - self.graphics = *engine.retained_graphics_state(); - Ok(()) - } - - /// Returns true if we should actually apply hinting. - /// - /// Hinting can be completely disabled by the control value program. - pub fn is_enabled(&self) -> bool { - // If bit 0 is set, disables hinting entirely - self.graphics.instruct_control & 1 == 0 - } - - /// Returns true if backward compatibility mode has been activated - /// by the hinter settings or the `prep` table. - pub fn backward_compatibility(&self) -> bool { - // Set backward compatibility mode - if self.graphics.target.preserve_linear_metrics() { - true - } else if self.graphics.target.is_smooth() { - (self.graphics.instruct_control & 0x4) == 0 - } else { - false - } - } - - pub fn hint( - &self, - outlines: &Outlines, - outline: &mut HintOutline, - is_pedantic: bool, - ) -> Result<(), HintError> { - // Twilight zone - let twilight_count = outline.twilight_scaled.len(); - let twilight_contours = [twilight_count as u16]; - outline - .twilight_original_scaled - .copy_from_slice(&self.twilight_original_scaled); - outline - .twilight_scaled - .copy_from_slice(&self.twilight_scaled); - outline.twilight_flags.copy_from_slice(&self.twilight_flags); - let twilight = Zone::new( - &[], - outline.twilight_original_scaled, - outline.twilight_scaled, - outline.twilight_flags, - &twilight_contours, - ); - // Glyph zone - let glyph = Zone::new( - outline.unscaled, - outline.original_scaled, - outline.scaled, - outline.flags, - outline.contours, - ); - let value_stack = ValueStack::new(outline.stack, is_pedantic); - let cvt = CowSlice::new(&self.cvt, outline.cvt).unwrap(); - let storage = CowSlice::new(&self.storage, outline.storage).unwrap(); - let mut engine = Engine::new( - outlines, - ProgramState::new( - outlines.fpgm, - outlines.prep, - outline.bytecode, - Program::Glyph, - ), - self.graphics, - DefinitionState::new( - DefinitionMap::Ref(&self.functions), - DefinitionMap::Ref(&self.instructions), - ), - cvt, - storage, - value_stack, - twilight, - glyph, - self.axis_count, - outline.coords, - outline.is_composite, - ); - engine - .run_program(Program::Glyph, is_pedantic) - .map_err(|mut e| { - e.glyph_id = Some(outline.glyph_id); - e - })?; - // If we're not running in backward compatibility mode, capture - // modified phantom points. - if !engine.backward_compatibility() { - for (i, p) in (outline.scaled[outline.scaled.len() - 4..]) - .iter() - .enumerate() - { - outline.phantom[i] = *p; - } - } - Ok(()) - } - - /// Captures limits, resizes buffers and scales the CVT. - fn setup(&mut self, outlines: &Outlines, scale: i32, coords: &[F2Dot14]) { - let axis_count = outlines - .gvar - .as_ref() - .map(|gvar| gvar.axis_count()) - .unwrap_or_default(); - self.functions.clear(); - self.functions - .resize(outlines.max_function_defs as usize, Definition::default()); - self.instructions.resize( - outlines.max_instruction_defs as usize, - Definition::default(), - ); - self.cvt.clear(); - let cvt = outlines.font.cvt().unwrap_or_default(); - if let Ok(cvar) = outlines.font.cvar() { - // First accumulate all the deltas in 16.16 - self.cvt.resize(cvt.len(), 0); - let _ = cvar.deltas(axis_count, coords, &mut self.cvt); - // Now add the base CVT values - for (value, base_value) in self.cvt.iter_mut().zip(cvt.iter()) { - // Deltas are converted from 16.16 to 26.6 - // See - let delta = Fixed::from_bits(*value).to_f26dot6().to_bits(); - let base_value = base_value.get() as i32 * 64; - *value = base_value + delta; - } - } else { - // CVT values are converted to 26.6 on load - // See - self.cvt - .extend(cvt.iter().map(|value| (value.get() as i32) * 64)); - } - // More weird scaling. This is due to the fact that CVT values are - // already in 26.6 - // See - let scale = Fixed::from_bits(scale >> 6); - for value in &mut self.cvt { - *value = (Fixed::from_bits(*value) * scale).to_bits(); - } - self.storage.clear(); - self.storage.resize(outlines.max_storage as usize, 0); - let max_twilight_points = outlines.max_twilight_points as usize; - self.twilight_scaled.clear(); - self.twilight_scaled - .resize(max_twilight_points, Default::default()); - self.twilight_original_scaled.clear(); - self.twilight_original_scaled - .resize(max_twilight_points, Default::default()); - self.twilight_flags.clear(); - self.twilight_flags - .resize(max_twilight_points, Default::default()); - self.axis_count = axis_count; - self.max_stack = outlines.max_stack_elements as usize; - self.graphics = RetainedGraphicsState::default(); - } -} - -#[cfg(test)] -impl HintInstance { - /// Enable instruct control bit 1 which effectively disables hinting. - /// - /// This mimics what the `prep` table might do for various configurations - /// and font sizes. Used for testing. - pub fn simulate_prep_flag_suppress_hinting(&mut self) { - self.graphics.instruct_control |= 1; - } -} - -#[cfg(test)] -mod tests { - use super::{super::super::Outlines, HintInstance}; - use read_fonts::{types::F2Dot14, FontRef}; - - #[test] - fn scaled_cvar_cvt() { - let font = FontRef::new(font_test_data::CVAR).unwrap(); - let outlines = Outlines::new(&font).unwrap(); - let mut instance = HintInstance::default(); - let coords = [0.5, -0.5].map(F2Dot14::from_f32); - let ppem = 16; - // ppem * 64 / upem - let scale = 67109; - instance - .reconfigure(&outlines, scale, ppem, Default::default(), &coords) - .unwrap(); - let expected = [ - 778, 10, 731, 0, 731, 10, 549, 10, 0, 0, 0, -10, 0, -10, -256, -10, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 137, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 60, 0, 81, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - assert_eq!(&instance.cvt, &expected); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,324 +0,0 @@ -//! Fixed point math helpers that are specific to TrueType hinting. -//! -//! These are implemented in terms of font-types types when possible. It -//! likely makes sense to use more strongly typed fixed point values -//! in the future. - -use read_fonts::types::{Fixed, Point}; - -pub fn floor(x: i32) -> i32 { - x & !63 -} - -pub fn round(x: i32) -> i32 { - floor(x + 32) -} - -pub fn ceil(x: i32) -> i32 { - floor(x + 63) -} - -fn floor_pad(x: i32, n: i32) -> i32 { - x & !(n - 1) -} - -pub fn round_pad(x: i32, n: i32) -> i32 { - floor_pad(x + n / 2, n) -} - -#[inline(always)] -pub fn mul(a: i32, b: i32) -> i32 { - (Fixed::from_bits(a) * Fixed::from_bits(b)).to_bits() -} - -pub fn div(a: i32, b: i32) -> i32 { - (Fixed::from_bits(a) / Fixed::from_bits(b)).to_bits() -} - -/// Fixed point multiply and divide: a * b / c -pub fn mul_div(a: i32, b: i32, c: i32) -> i32 { - Fixed::from_bits(a) - .mul_div(Fixed::from_bits(b), Fixed::from_bits(c)) - .to_bits() -} - -/// Fixed point multiply and divide without rounding: a * b / c -/// -/// Based on -pub fn mul_div_no_round(mut a: i32, mut b: i32, mut c: i32) -> i32 { - let mut s = 1; - if a < 0 { - a = -a; - s = -1; - } - if b < 0 { - b = -b; - s = -s; - } - if c < 0 { - c = -c; - s = -s; - } - let d = if c > 0 { - ((a as i64) * (b as i64)) / c as i64 - } else { - 0x7FFFFFFF - }; - if s < 0 { - -(d as i32) - } else { - d as i32 - } -} - -/// Multiplication for 2.14 fixed point. -/// -/// Based on -pub fn mul14(a: i32, b: i32) -> i32 { - let mut v = a as i64 * b as i64; - v += 0x2000 + (v >> 63); - (v >> 14) as i32 -} - -/// Normalize a vector in 2.14 fixed point. -/// -/// Direct port of -pub fn normalize14(x: i32, y: i32) -> Point { - use core::num::Wrapping; - let (mut sx, mut sy) = (Wrapping(1i32), Wrapping(1i32)); - let mut ux = Wrapping(x as u32); - let mut uy = Wrapping(y as u32); - const ZERO: Wrapping = Wrapping(0); - let mut result = Point::default(); - if x < 0 { - ux = ZERO - ux; - sx = -sx; - } - if y < 0 { - uy = ZERO - uy; - sy = -sy; - } - if ux == ZERO { - result.x = x / 4; - if uy.0 > 0 { - result.y = (sy * Wrapping(0x10000) / Wrapping(4)).0; - } - return result; - } - if uy == ZERO { - result.y = y / 4; - if ux.0 > 0 { - result.x = (sx * Wrapping(0x10000) / Wrapping(4)).0; - } - return result; - } - let mut len = if ux > uy { - ux + (uy >> 1) - } else { - uy + (ux >> 1) - }; - let mut shift = Wrapping(len.0.leading_zeros() as i32); - shift -= Wrapping(15) - + if len >= (Wrapping(0xAAAAAAAAu32) >> shift.0 as usize) { - Wrapping(1) - } else { - Wrapping(0) - }; - if shift.0 > 0 { - let s = shift.0 as usize; - ux <<= s; - uy <<= s; - len = if ux > uy { - ux + (uy >> 1) - } else { - uy + (ux >> 1) - }; - } else { - let s = -shift.0 as usize; - ux >>= s; - uy >>= s; - len >>= s; - } - let mut b = Wrapping(0x10000) - Wrapping(len.0 as i32); - let x = Wrapping(ux.0 as i32); - let y = Wrapping(uy.0 as i32); - let mut z; - let mut u; - let mut v; - loop { - u = Wrapping((x + ((x * b) >> 16)).0 as u32); - v = Wrapping((y + ((y * b) >> 16)).0 as u32); - z = Wrapping(-((u * u + v * v).0 as i32)) / Wrapping(0x200); - z = z * ((Wrapping(0x10000) + b) >> 8) / Wrapping(0x10000); - b += z; - if z <= Wrapping(0) { - break; - } - } - Point::new( - (Wrapping(u.0 as i32) * sx / Wrapping(4)).0, - (Wrapping(v.0 as i32) * sy / Wrapping(4)).0, - ) -} - -#[cfg(test)] -mod tests { - use raw::types::{F2Dot14, Fixed}; - - /// Tolerance value for floating point sanity checks. - /// Tests with large sets of values show this is the best we can - /// expect from the fixed point implementations. - const FLOAT_TOLERANCE: f32 = 1e-4; - - #[test] - fn mul_div_no_round() { - let cases = [ - // computed with FT_MulDiv_NoRound(): - // ((a, b, c), result) where result = a * b / c - ((-326, -11474, 9942), 376), - ((-6781, 13948, 11973), -7899), - ((3517, 15622, 8075), 6804), - ((-6127, 15026, 2276), -40450), - ((11257, 14828, 2542), 65664), - ((-12797, -16280, -9086), -22929), - ((-7994, -3340, 9583), 2786), - ((-16101, -13780, -1427), -155481), - ((10304, -16331, 15480), -10870), - ((-15879, 11912, -4650), 40677), - ((-5015, 6382, -15977), 2003), - ((2080, -11930, -15457), 1605), - ((-11071, 13350, 16138), -9158), - ((16084, -13564, -770), 283329), - ((14304, -10377, -21), 7068219), - ((-14056, -8853, -5488), -22674), - ((-10319, 14797, 8554), -17850), - ((-7820, 6826, 10555), -5057), - ((7257, 15928, 8159), 14167), - ((14929, 11579, -13204), -13091), - ((2808, 12070, -14697), -2306), - ((-13818, 8544, -1649), 71595), - ((3265, 7325, -1373), -17418), - ((14832, 10586, -6440), -24380), - ((4123, 8274, -2022), -16871), - ((4645, -4149, -7242), 2661), - ((-3891, 8366, 5771), -5640), - ((-15447, -3428, -9335), -5672), - ((13670, -14311, -11122), 17589), - ((12590, -6592, 13159), -6306), - ((-8369, -10193, 5051), 16888), - ((-9539, 5167, 2595), -18993), - ]; - for ((a, b, c), expected_result) in cases { - let result = super::mul_div_no_round(a, b, c); - assert_eq!(result, expected_result); - let fa = Fixed::from_bits(a as _).to_f32(); - let fb = Fixed::from_bits(b as _).to_f32(); - let fc = Fixed::from_bits(c as _).to_f32(); - let fresult = fa * fb / fc; - let fexpected_result = Fixed::from_bits(expected_result as _).to_f32(); - assert!((fresult - fexpected_result).abs() < FLOAT_TOLERANCE); - } - } - - #[test] - fn mul14() { - let cases = [ - // computed with TT_MulFix14(): - // ((a, b), result) where result = a * b - ((6236, -10078), -3836), - ((-6803, -5405), 2244), - ((-10006, -12852), 7849), - ((-15434, -4102), 3864), - ((-8681, 9269), -4911), - ((9449, -9130), -5265), - ((12643, 2161), 1668), - ((-6115, 9284), -3465), - ((316, 3390), 65), - ((15077, -12901), -11872), - ((-12182, 11613), -8635), - ((-7213, 8246), -3630), - ((13482, 8096), 6662), - ((5690, 15016), 5215), - ((-5991, 12613), -4612), - ((13112, -8404), -6726), - ((13524, 6786), 5601), - ((7156, 3291), 1437), - ((-2978, 353), -64), - ((-1755, 14626), -1567), - ((14402, 7886), 6932), - ((7124, 15730), 6840), - ((-12679, 14830), -11476), - ((-9374, -12999), 7437), - ((12301, -4685), -3517), - ((5324, 2066), 671), - ((6783, -4946), -2048), - ((12078, -968), -714), - ((-10137, 14116), -8734), - ((-13946, 11585), -9861), - ((-678, -2205), 91), - ((-2629, -3319), 533), - ]; - for ((a, b), expected_result) in cases { - let result = super::mul14(a, b); - assert_eq!(result, expected_result); - let fa = F2Dot14::from_bits(a as _).to_f32(); - let fb = F2Dot14::from_bits(b as _).to_f32(); - let fresult = fa * fb; - let fexpected_result = F2Dot14::from_bits(expected_result as _).to_f32(); - assert!((fresult - fexpected_result).abs() < FLOAT_TOLERANCE); - } - } - - #[test] - fn normalize14() { - let cases = [ - // computed with FT_Vector_NormLen(): - // (input vector, expected normalized vector) - ((-13660, 11807), (-12395, 10713)), - ((-10763, 9293), (-12401, 10707)), - ((-3673, 673), (-16115, 2952)), - ((15886, -2964), (16106, -3005)), - ((15442, -2871), (16108, -2994)), - ((-6308, 5744), (-12114, 11031)), - ((9410, -10415), (10983, -12156)), - ((-10620, -14856), (-9528, -13328)), - ((-9372, 12029), (-10069, 12924)), - ((-1272, -1261), (-11635, -11534)), - ((-7076, -5517), (-12920, -10074)), - ((-10297, 179), (-16381, 284)), - ((9256, -13235), (9389, -13426)), - ((5315, -12449), (6433, -15068)), - ((8064, 15213), (7673, 14476)), - ((-8665, 41), (-16383, 77)), - ((-3455, -4720), (-9677, -13220)), - ((13449, -5152), (15299, -5861)), - ((-15605, 8230), (-14492, 7643)), - ((4716, -13690), (5336, -15490)), - ((12904, -11422), (12268, -10859)), - ((2825, -6396), (6619, -14987)), - ((4654, 15245), (4783, 15670)), - ((-14769, 15133), (-11443, 11725)), - ((-8090, -9057), (-10914, -12219)), - ((-472, 1953), (-3848, 15925)), - ((-12563, 1040), (-16328, 1351)), - ((-7938, 15587), (-7435, 14599)), - ((-9701, 5356), (-14343, 7919)), - ((-642, -14484), (-725, -16367)), - ((12963, -9690), (13123, -9809)), - ((7067, 5361), (13053, 9902)), - ((0x4000, 0), (0x4000, 0)), - ((0, 0x4000), (0, 0x4000)), - ((-0x4000, 0), (-0x4000, 0)), - ((0, -0x4000), (0, -0x4000)), - ]; - for ((x, y), expected) in cases { - let n = super::normalize14(x, y); - assert_eq!((n.x, n.y), expected); - // Ensure the length of the vector is nearly 1.0 - let fx = F2Dot14::from_bits(n.x as _).to_f32(); - let fy = F2Dot14::from_bits(n.y as _).to_f32(); - let flen = (fx * fx + fy * fy).sqrt(); - assert!((flen - 1.0).abs() <= FLOAT_TOLERANCE); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -//! TrueType hinting. - -mod call_stack; -mod cow_slice; -mod cvt; -mod definition; -mod engine; -mod error; -mod graphics; -mod instance; -mod math; -mod program; -mod projection; -mod round; -mod storage; -mod value_stack; -mod zone; - -use super::super::Target; - -use read_fonts::{ - tables::glyf::PointFlags, - types::{F26Dot6, F2Dot14, GlyphId, Point}, -}; - -pub use error::HintError; -pub use instance::HintInstance; - -/// Outline data that is passed to the hinter. -pub struct HintOutline<'a> { - pub glyph_id: GlyphId, - pub unscaled: &'a [Point], - pub scaled: &'a mut [Point], - pub original_scaled: &'a mut [Point], - pub flags: &'a mut [PointFlags], - pub contours: &'a [u16], - pub phantom: &'a mut [Point], - pub bytecode: &'a [u8], - pub stack: &'a mut [i32], - pub cvt: &'a mut [i32], - pub storage: &'a mut [i32], - pub twilight_scaled: &'a mut [Point], - pub twilight_original_scaled: &'a mut [Point], - pub twilight_flags: &'a mut [PointFlags], - pub is_composite: bool, - pub coords: &'a [F2Dot14], -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,163 +0,0 @@ -//! TrueType program management. - -use raw::tables::glyf::bytecode::Decoder; - -use super::{ - call_stack::{CallRecord, CallStack}, - definition::Definition, - error::HintErrorKind, -}; - -/// Describes the source for a piece of bytecode. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -#[repr(u8)] -pub enum Program { - /// Program that initializes the function and instruction tables. Stored - /// in the `fpgm` table. - #[default] - Font = 0, - /// Program that initializes CVT and storage based on font size and other - /// parameters. Stored in the `prep` table. - ControlValue = 1, - /// Glyph specified program. Stored per-glyph in the `glyf` table. - Glyph = 2, -} - -/// State for managing active programs and decoding instructions. -pub struct ProgramState<'a> { - /// Bytecode for each of the three program types, indexed by `Program`. - pub bytecode: [&'a [u8]; 3], - /// The initial program when execution begins. - pub initial: Program, - /// The currently active program. - pub current: Program, - /// Instruction decoder for the currently active program. - pub decoder: Decoder<'a>, - /// Tracks nested function and instruction invocations. - pub call_stack: CallStack, -} - -impl<'a> ProgramState<'a> { - pub fn new( - font_code: &'a [u8], - cv_code: &'a [u8], - glyph_code: &'a [u8], - initial_program: Program, - ) -> Self { - let bytecode = [font_code, cv_code, glyph_code]; - Self { - bytecode, - initial: initial_program, - current: initial_program, - decoder: Decoder::new(bytecode[initial_program as usize], 0), - call_stack: CallStack::default(), - } - } - - /// Resets the state for execution of the given program. - pub fn reset(&mut self, program: Program) { - self.initial = program; - self.current = program; - self.decoder = Decoder::new(self.bytecode[program as usize], 0); - self.call_stack.clear(); - } - - /// Jumps to the code in the given definition and sets it up for - /// execution `count` times. - pub fn enter(&mut self, definition: Definition, count: u32) -> Result<(), HintErrorKind> { - let program = definition.program(); - let pc = definition.code_range().start; - let bytecode = self.bytecode[program as usize]; - self.call_stack.push(CallRecord { - caller_program: self.current, - return_pc: self.decoder.pc, - current_count: count, - definition, - })?; - self.current = program; - self.decoder = Decoder::new(bytecode, pc); - Ok(()) - } - - /// Leaves the code from the definition on the top of the stack. - /// - /// If the top call record has a loop count greater than 1, restarts - /// execution from the beginning of the definition. Otherwise, resumes - /// execution at the previously active definition. - pub fn leave(&mut self) -> Result<(), HintErrorKind> { - let mut record = self.call_stack.pop()?; - if record.current_count > 1 { - // This is a loop call with some iterations remaining. - record.current_count -= 1; - self.decoder.pc = record.definition.code_range().start; - self.call_stack.push(record)?; - } else { - self.current = record.caller_program; - // Reset the decoder to the calling program and program counter. - self.decoder.bytecode = self.bytecode[record.caller_program as usize]; - self.decoder.pc = record.return_pc; - } - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - /// Test accounting of program, bytecode and program counter through - /// enter/leave cycles. - #[test] - fn accounting() { - let font_code = &[0][..]; - let cv_code = &[1][..]; - let glyph_code = &[2][..]; - let mut state = ProgramState::new(font_code, cv_code, glyph_code, Program::Glyph); - // We start at glyph code - assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); - let font_def = Definition::new(Program::Font, 10..20, 0); - let cv_def = Definition::new(Program::ControlValue, 33..111, 1); - // Now move to CV code - state.enter(cv_def, 1).unwrap(); - assert_eq!(state.active_state(), (Program::ControlValue, cv_code, 33)); - // Bump the program counter to test capture of return_pc - state.decoder.pc += 20; - // And to font code - state.enter(font_def, 1).unwrap(); - assert_eq!(state.active_state(), (Program::Font, font_code, 10)); - // Back to CV code - state.leave().unwrap(); - assert_eq!(state.active_state(), (Program::ControlValue, cv_code, 53)); - // And to the original glyph code - state.leave().unwrap(); - assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); - } - - /// Ensure calls with a count of `n` require `n` leaves before returning - /// to previous frame. Also ensure program counter is reset to start of - /// definition at each leave. - #[test] - fn loop_call() { - let font_code = &[0][..]; - let cv_code = &[1][..]; - let glyph_code = &[2][..]; - let mut state = ProgramState::new(font_code, cv_code, glyph_code, Program::Glyph); - let font_def = Definition::new(Program::Font, 10..20, 0); - // "Execute" font definition 3 times - state.enter(font_def, 3).unwrap(); - for _ in 0..3 { - assert_eq!(state.active_state(), (Program::Font, font_code, 10)); - // Modify program counter to ensure we reset on leave - state.decoder.pc += 22; - state.leave().unwrap(); - } - // Should be back to glyph code - assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); - } - - impl<'a> ProgramState<'a> { - fn active_state(&self) -> (Program, &'a [u8], usize) { - (self.current, self.decoder.bytecode, self.decoder.pc) - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ -//! Point projection. - -use super::graphics::{CoordAxis, GraphicsState}; -use raw::types::{F26Dot6, Point}; - -impl GraphicsState<'_> { - /// Updates cached state that is derived from projection vectors. - pub fn update_projection_state(&mut self) { - // 1.0 in 2.14 fixed point. - const ONE: i32 = 0x4000; - // Based on Compute_Funcs() at - // . - // FreeType uses function pointers to select between various "modes" - // but we use the CoordAxis type instead. - if self.freedom_vector.x == ONE { - self.fdotp = self.proj_vector.x; - } else if self.freedom_vector.y == ONE { - self.fdotp = self.proj_vector.y; - } else { - let px = self.proj_vector.x; - let py = self.proj_vector.y; - let fx = self.freedom_vector.x; - let fy = self.freedom_vector.y; - self.fdotp = (px * fx + py * fy) >> 14; - } - self.proj_axis = CoordAxis::Both; - if self.proj_vector.x == ONE { - self.proj_axis = CoordAxis::X; - } else if self.proj_vector.y == ONE { - self.proj_axis = CoordAxis::Y; - } - self.dual_proj_axis = CoordAxis::Both; - if self.dual_proj_vector.x == ONE { - self.dual_proj_axis = CoordAxis::X; - } else if self.dual_proj_vector.y == ONE { - self.dual_proj_axis = CoordAxis::Y; - } - self.freedom_axis = CoordAxis::Both; - if self.fdotp == ONE { - if self.freedom_vector.x == ONE { - self.freedom_axis = CoordAxis::X; - } else if self.freedom_vector.y == ONE { - self.freedom_axis = CoordAxis::Y; - } - } - // At small sizes, fdotp can become too small resulting in overflows - // and spikes. - if self.fdotp.abs() < 0x400 { - self.fdotp = ONE; - } - } - - /// Computes the projection of vector given by (v1 - v2) along the - /// current projection vector. - #[inline(always)] - pub fn project(&self, v1: Point, v2: Point) -> F26Dot6 { - match self.proj_axis { - // - CoordAxis::X => v1.x - v2.x, - // - CoordAxis::Y => v1.y - v2.y, - CoordAxis::Both => { - // - let dx = v1.x - v2.x; - let dy = v1.y - v2.y; - F26Dot6::from_bits(dot14( - dx.to_bits(), - dy.to_bits(), - self.proj_vector.x, - self.proj_vector.y, - )) - } - } - } - - /// Computes the projection of vector given by (v1 - v2) along the - /// current dual projection vector. - #[inline(always)] - pub fn dual_project(&self, v1: Point, v2: Point) -> F26Dot6 { - match self.dual_proj_axis { - // - CoordAxis::X => v1.x - v2.x, - // - CoordAxis::Y => v1.y - v2.y, - CoordAxis::Both => { - // https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L2402 - let dx = v1.x - v2.x; - let dy = v1.y - v2.y; - F26Dot6::from_bits(dot14( - dx.to_bits(), - dy.to_bits(), - self.dual_proj_vector.x, - self.dual_proj_vector.y, - )) - } - } - } - - /// Computes the projection of vector given by (v1 - v2) along the - /// current dual projection vector for unscaled points. - #[inline(always)] - pub fn dual_project_unscaled(&self, v1: Point, v2: Point) -> i32 { - match self.dual_proj_axis { - // - CoordAxis::X => v1.x - v2.x, - // - CoordAxis::Y => v1.y - v2.y, - CoordAxis::Both => { - // https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L2402 - let dx = v1.x - v2.x; - let dy = v1.y - v2.y; - dot14(dx, dy, self.dual_proj_vector.x, self.dual_proj_vector.y) - } - } - } -} - -/// Dot product for vectors in 2.14 fixed point. -fn dot14(ax: i32, ay: i32, bx: i32, by: i32) -> i32 { - let mut v1 = ax as i64 * bx as i64; - let v2 = ay as i64 * by as i64; - v1 += v2; - v1 += 0x2000 + (v1 >> 63); - (v1 >> 14) as i32 -} - -#[cfg(test)] -mod tests { - use super::{super::math, CoordAxis, F26Dot6, GraphicsState, Point}; - - #[test] - fn project_one_axis() { - let mut state = GraphicsState { - proj_vector: math::normalize14(1, 0), - ..Default::default() - }; - state.update_projection_state(); - assert_eq!(state.proj_axis, CoordAxis::X); - assert_eq!(state.proj_vector, Point::new(0x4000, 0)); - let cases = &[ - (Point::new(0, 0), Point::new(0, 0), 0), - (Point::new(100, 100), Point::new(0, 0), 100), - (Point::new(42, 100), Point::new(100, 0), -58), - (Point::new(0, 0), Point::new(100, 100), -100), - ]; - test_project_cases(&state, cases); - } - - #[test] - fn project_both_axes() { - let mut state = GraphicsState { - proj_vector: math::normalize14(0x4000, 0x4000), - ..Default::default() - }; - state.update_projection_state(); - assert_eq!(state.proj_axis, CoordAxis::Both); - let cases = &[ - (Point::new(0, 0), Point::new(0, 0), 0), - (Point::new(100, 100), Point::new(0, 0), 141), - (Point::new(42, 100), Point::new(100, 0), 30), - (Point::new(0, 0), Point::new(100, 100), -141), - ]; - test_project_cases(&state, cases); - } - - fn test_project_cases(state: &GraphicsState, cases: &[(Point, Point, i32)]) { - for (v1, v2, expected) in cases.iter().copied() { - let v1 = v1.map(F26Dot6::from_bits); - let v2 = v2.map(F26Dot6::from_bits); - let result = state.project(v1, v2).to_bits(); - assert_eq!( - result, expected, - "project({v1:?}, {v2:?}) = {result} (expected {expected})" - ); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,240 +0,0 @@ -//! Rounding state. - -use super::{super::F26Dot6, graphics::GraphicsState}; - -/// Rounding strategies supported by the interpreter. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub enum RoundMode { - /// Distances are rounded to the closest grid line. - /// - /// Set by `RTG` instruction. - #[default] - Grid, - /// Distances are rounded to the nearest half grid line. - /// - /// Set by `RTHG` instruction. - HalfGrid, - /// Distances are rounded to the closest half or integer pixel. - /// - /// Set by `RTDG` instruction. - DoubleGrid, - /// Distances are rounded down to the closest integer grid line. - /// - /// Set by `RDTG` instruction. - DownToGrid, - /// Distances are rounded up to the closest integer pixel boundary. - /// - /// Set by `RUTG` instruction. - UpToGrid, - /// Rounding is turned off. - /// - /// Set by `ROFF` instruction. - Off, - /// Allows fine control over the effects of the round state variable by - /// allowing you to set the values of three components of the round_state: - /// period, phase, and threshold. - /// - /// More formally, maps the domain of 26.6 fixed point numbers into a set - /// of discrete values that are separated by equal distances. - /// - /// Set by `SROUND` instruction. - Super, - /// Analogous to `Super`. The grid period is sqrt(2)/2 pixels rather than 1 - /// pixel. It is useful for measuring at a 45 degree angle with the - /// coordinate axes. - /// - /// Set by `S45ROUND` instruction. - Super45, -} - -/// Graphics state that controls rounding. -/// -/// See -#[derive(Copy, Clone, Debug)] -pub struct RoundState { - pub mode: RoundMode, - pub threshold: i32, - pub phase: i32, - pub period: i32, -} - -impl Default for RoundState { - fn default() -> Self { - Self { - mode: RoundMode::Grid, - threshold: 0, - phase: 0, - period: 64, - } - } -} - -impl RoundState { - pub fn round(&self, distance: F26Dot6) -> F26Dot6 { - use super::math; - use RoundMode::*; - let distance = distance.to_bits(); - let result = match self.mode { - // - HalfGrid => { - if distance >= 0 { - (math::floor(distance) + 32).max(0) - } else { - (-(math::floor(-distance) + 32)).min(0) - } - } - // - Grid => { - if distance >= 0 { - math::round(distance).max(0) - } else { - (-math::round(-distance)).min(0) - } - } - // - DoubleGrid => { - if distance >= 0 { - math::round_pad(distance, 32).max(0) - } else { - (-math::round_pad(-distance, 32)).min(0) - } - } - // - DownToGrid => { - if distance >= 0 { - math::floor(distance).max(0) - } else { - (-math::floor(-distance)).min(0) - } - } - // - UpToGrid => { - if distance >= 0 { - math::ceil(distance).max(0) - } else { - (-math::ceil(-distance)).min(0) - } - } - // - Super => { - if distance >= 0 { - let val = - ((distance + (self.threshold - self.phase)) & -self.period) + self.phase; - if val < 0 { - self.phase - } else { - val - } - } else { - let val = - -(((self.threshold - self.phase) - distance) & -self.period) - self.phase; - if val > 0 { - -self.phase - } else { - val - } - } - } - // - Super45 => { - if distance >= 0 { - let val = (((distance + (self.threshold - self.phase)) / self.period) - * self.period) - + self.phase; - if val < 0 { - self.phase - } else { - val - } - } else { - let val = -((((self.threshold - self.phase) - distance) / self.period) - * self.period) - - self.phase; - if val > 0 { - -self.phase - } else { - val - } - } - } - // - Off => distance, - }; - F26Dot6::from_bits(result) - } -} - -impl GraphicsState<'_> { - pub fn round(&self, distance: F26Dot6) -> F26Dot6 { - self.round_state.round(distance) - } -} - -#[cfg(test)] -mod tests { - use super::{F26Dot6, RoundMode, RoundState}; - - #[test] - fn round_to_grid() { - round_cases( - RoundMode::Grid, - &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], - ); - } - - #[test] - fn round_to_half_grid() { - round_cases( - RoundMode::HalfGrid, - &[(0, 32), (32, 32), (-32, -32), (64, 96), (50, 32)], - ); - } - - #[test] - fn round_to_double_grid() { - round_cases( - RoundMode::DoubleGrid, - &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 64)], - ); - } - - #[test] - fn round_down_to_grid() { - round_cases( - RoundMode::DownToGrid, - &[(0, 0), (32, 0), (-32, 0), (64, 64), (50, 0)], - ); - } - - #[test] - fn round_up_to_grid() { - round_cases( - RoundMode::UpToGrid, - &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], - ); - } - - #[test] - fn round_off() { - round_cases( - RoundMode::Off, - &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 50)], - ); - } - - fn round_cases(mode: RoundMode, cases: &[(i32, i32)]) { - for (value, expected) in cases.iter().copied() { - let value = F26Dot6::from_bits(value); - let expected = F26Dot6::from_bits(expected); - let state = RoundState { - mode, - ..Default::default() - }; - let result = state.round(value); - assert_eq!( - result, expected, - "mismatch in rounding: {mode:?}({value}) = {result} (expected {expected})" - ); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,29 +0,0 @@ -//! Storage area. - -use super::{cow_slice::CowSlice, error::HintErrorKind}; - -/// Backing store for the storage area. -/// -/// This is just a wrapper for [`CowSlice`] that converts out of bounds -/// accesses to appropriate errors. -pub struct Storage<'a>(CowSlice<'a>); - -impl Storage<'_> { - pub fn get(&self, index: usize) -> Result { - self.0 - .get(index) - .ok_or(HintErrorKind::InvalidStorageIndex(index)) - } - - pub fn set(&mut self, index: usize, value: i32) -> Result<(), HintErrorKind> { - self.0 - .set(index, value) - .ok_or(HintErrorKind::InvalidStorageIndex(index)) - } -} - -impl<'a> From> for Storage<'a> { - fn from(value: CowSlice<'a>) -> Self { - Self(value) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,359 +0,0 @@ -//! Value stack for TrueType interpreter. -//! -use raw::types::F26Dot6; -use read_fonts::tables::glyf::bytecode::InlineOperands; - -use super::error::HintErrorKind; - -use HintErrorKind::{ValueStackOverflow, ValueStackUnderflow}; - -/// Value stack for the TrueType interpreter. -/// -/// This uses a slice as the backing store rather than a `Vec` to enable -/// support for allocation from user buffers. -/// -/// See -pub struct ValueStack<'a> { - values: &'a mut [i32], - len: usize, - is_pedantic: bool, -} - -impl<'a> ValueStack<'a> { - pub fn new(values: &'a mut [i32], is_pedantic: bool) -> Self { - Self { - values, - len: 0, - is_pedantic, - } - } - - /// Returns the depth of the stack - /// - pub fn len(&self) -> usize { - self.len - } - - #[cfg(test)] - fn is_empty(&self) -> bool { - self.len == 0 - } - - // This is used in tests and also useful for tracing. - #[allow(dead_code)] - pub fn values(&self) -> &[i32] { - &self.values[..self.len] - } - - pub fn push(&mut self, value: i32) -> Result<(), HintErrorKind> { - let ptr = self - .values - .get_mut(self.len) - .ok_or(HintErrorKind::ValueStackOverflow)?; - *ptr = value; - self.len += 1; - Ok(()) - } - - /// Pushes values that have been decoded from the instruction stream - /// onto the stack. - /// - /// Implements the PUSHB[], PUSHW[], NPUSHB[] and NPUSHW[] instructions. - /// - /// See - pub fn push_inline_operands(&mut self, operands: &InlineOperands) -> Result<(), HintErrorKind> { - let push_count = operands.len(); - let stack_base = self.len; - for (stack_value, value) in self - .values - .get_mut(stack_base..stack_base + push_count) - .ok_or(ValueStackOverflow)? - .iter_mut() - .zip(operands.values()) - { - *stack_value = value; - } - self.len += push_count; - Ok(()) - } - - pub fn peek(&mut self) -> Option { - if self.len > 0 { - self.values.get(self.len - 1).copied() - } else { - None - } - } - - /// Pops a value from the stack. - /// - /// Implements the POP[] instruction. - /// - /// See - pub fn pop(&mut self) -> Result { - if let Some(value) = self.peek() { - self.len -= 1; - Ok(value) - } else if self.is_pedantic { - Err(ValueStackUnderflow) - } else { - Ok(0) - } - } - - /// Convenience method for instructions that expect values in 26.6 format. - pub fn pop_f26dot6(&mut self) -> Result { - Ok(F26Dot6::from_bits(self.pop()?)) - } - - /// Convenience method for instructions that pop values that are used as an - /// index. - pub fn pop_usize(&mut self) -> Result { - Ok(self.pop()? as usize) - } - - /// Applies a unary operation. - /// - /// Pops `a` from the stack and pushes `op(a)`. - pub fn apply_unary( - &mut self, - mut op: impl FnMut(i32) -> Result, - ) -> Result<(), HintErrorKind> { - let a = self.pop()?; - self.push(op(a)?) - } - - /// Applies a binary operation. - /// - /// Pops `b` and `a` from the stack and pushes `op(a, b)`. - pub fn apply_binary( - &mut self, - mut op: impl FnMut(i32, i32) -> Result, - ) -> Result<(), HintErrorKind> { - let b = self.pop()?; - let a = self.pop()?; - self.push(op(a, b)?) - } - - /// Clear the entire stack. - /// - /// Implements the CLEAR[] instruction. - /// - /// See - pub fn clear(&mut self) { - self.len = 0; - } - - /// Duplicate top stack element. - /// - /// Implements the DUP[] instruction. - /// - /// See - pub fn dup(&mut self) -> Result<(), HintErrorKind> { - if let Some(value) = self.peek() { - self.push(value) - } else if self.is_pedantic { - Err(ValueStackUnderflow) - } else { - self.push(0) - } - } - - /// Swap the top two elements on the stack. - /// - /// Implements the SWAP[] instruction. - /// - /// See - pub fn swap(&mut self) -> Result<(), HintErrorKind> { - let a = self.pop()?; - let b = self.pop()?; - self.push(a)?; - self.push(b) - } - - /// Copy the indexed element to the top of the stack. - /// - /// Implements the CINDEX[] instruction. - /// - /// See - pub fn copy_index(&mut self) -> Result<(), HintErrorKind> { - let top_ix = self.len.checked_sub(1).ok_or(ValueStackUnderflow)?; - let index = *self.values.get(top_ix).ok_or(ValueStackUnderflow)? as usize; - let element_ix = top_ix.checked_sub(index).ok_or(ValueStackUnderflow)?; - self.values[top_ix] = self.values[element_ix]; - Ok(()) - } - - /// Moves the indexed element to the top of the stack. - /// - /// Implements the MINDEX[] instruction. - /// - /// See - pub fn move_index(&mut self) -> Result<(), HintErrorKind> { - let top_ix = self.len.checked_sub(1).ok_or(ValueStackUnderflow)?; - let index = *self.values.get(top_ix).ok_or(ValueStackUnderflow)? as usize; - let element_ix = top_ix.checked_sub(index).ok_or(ValueStackUnderflow)?; - let new_top_ix = top_ix.checked_sub(1).ok_or(ValueStackUnderflow)?; - let value = self.values[element_ix]; - self.values - .copy_within(element_ix + 1..self.len, element_ix); - self.values[new_top_ix] = value; - self.len -= 1; - Ok(()) - } - - /// Roll the top three stack elements. - /// - /// Implements the ROLL[] instruction. - /// - /// See - pub fn roll(&mut self) -> Result<(), HintErrorKind> { - let a = self.pop()?; - let b = self.pop()?; - let c = self.pop()?; - self.push(b)?; - self.push(a)?; - self.push(c)?; - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::{HintErrorKind, ValueStack}; - use read_fonts::tables::glyf::bytecode::MockInlineOperands; - - // The following are macros because functions can't return a new ValueStack - // with a borrowed parameter. - macro_rules! make_stack { - ($values:expr) => { - ValueStack { - values: $values, - len: $values.len(), - is_pedantic: true, - } - }; - } - macro_rules! make_empty_stack { - ($values:expr) => { - ValueStack { - values: $values, - len: 0, - is_pedantic: true, - } - }; - } - - #[test] - fn push() { - let mut stack = make_empty_stack!(&mut [0; 4]); - for i in 0..4 { - stack.push(i).unwrap(); - assert_eq!(stack.peek(), Some(i)); - } - assert!(matches!( - stack.push(0), - Err(HintErrorKind::ValueStackOverflow) - )); - } - - #[test] - fn push_args() { - let mut stack = make_empty_stack!(&mut [0; 32]); - let values = [-5, 2, 2845, 92, -26, 42, i16::MIN, i16::MAX]; - let mock_args = MockInlineOperands::from_words(&values); - stack.push_inline_operands(&mock_args.operands()).unwrap(); - let mut popped = vec![]; - while !stack.is_empty() { - popped.push(stack.pop().unwrap()); - } - assert!(values - .iter() - .rev() - .map(|x| *x as i32) - .eq(popped.iter().copied())); - } - - #[test] - fn pop() { - let mut stack = make_stack!(&mut [0, 1, 2, 3]); - for i in (0..4).rev() { - assert_eq!(stack.pop().ok(), Some(i)); - } - assert!(matches!( - stack.pop(), - Err(HintErrorKind::ValueStackUnderflow) - )); - } - - #[test] - fn dup() { - let mut stack = make_stack!(&mut [1, 2, 3, 0]); - // pop extra element so we have room for dup - stack.pop().unwrap(); - stack.dup().unwrap(); - assert_eq!(stack.values(), &[1, 2, 3, 3]); - } - - #[test] - fn swap() { - let mut stack = make_stack!(&mut [1, 2, 3]); - stack.swap().unwrap(); - assert_eq!(stack.values(), &[1, 3, 2]); - } - - #[test] - fn copy_index() { - let mut stack = make_stack!(&mut [4, 10, 2, 1, 3]); - stack.copy_index().unwrap(); - assert_eq!(stack.values(), &[4, 10, 2, 1, 10]); - } - - #[test] - fn move_index() { - let mut stack = make_stack!(&mut [4, 10, 2, 1, 3]); - stack.move_index().unwrap(); - assert_eq!(stack.values(), &[4, 2, 1, 10]); - } - - #[test] - fn roll() { - let mut stack = make_stack!(&mut [1, 2, 3]); - stack.roll().unwrap(); - assert_eq!(stack.values(), &[2, 3, 1]); - } - - #[test] - fn unnop() { - let mut stack = make_stack!(&mut [42]); - stack.apply_unary(|a| Ok(-a)).unwrap(); - assert_eq!(stack.peek(), Some(-42)); - stack.apply_unary(|a| Ok(!a)).unwrap(); - assert_eq!(stack.peek(), Some(!-42)); - } - - #[test] - fn binop() { - let mut stack = make_empty_stack!(&mut [0; 32]); - for value in 1..=5 { - stack.push(value).unwrap(); - } - stack.apply_binary(|a, b| Ok(a + b)).unwrap(); - assert_eq!(stack.peek(), Some(9)); - stack.apply_binary(|a, b| Ok(a * b)).unwrap(); - assert_eq!(stack.peek(), Some(27)); - stack.apply_binary(|a, b| Ok(a - b)).unwrap(); - assert_eq!(stack.peek(), Some(-25)); - stack.apply_binary(|a, b| Ok(a / b)).unwrap(); - assert_eq!(stack.peek(), Some(0)); - } - - // Subtract with overflow when stack size is 1 and element index is 0 - // https://oss-fuzz.com/testcase-detail/5765856825507840 - #[test] - fn move_index_avoid_overflow() { - let mut stack = make_stack!(&mut [0]); - // Don't panic - let _ = stack.move_index(); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,835 +0,0 @@ -//! Glyph zones. - -use read_fonts::{ - tables::glyf::{PointFlags, PointMarker}, - types::{F26Dot6, Point}, -}; - -use super::{ - error::HintErrorKind, - graphics::{CoordAxis, GraphicsState}, - math, -}; - -use HintErrorKind::{InvalidPointIndex, InvalidPointRange}; - -/// Reference to either the twilight or glyph zone. -/// -/// See -#[derive(Copy, Clone, PartialEq, Default, Debug)] -#[repr(u8)] -pub enum ZonePointer { - Twilight = 0, - #[default] - Glyph = 1, -} - -impl ZonePointer { - pub fn is_twilight(self) -> bool { - self == Self::Twilight - } -} - -impl TryFrom for ZonePointer { - type Error = HintErrorKind; - - fn try_from(value: i32) -> Result { - match value { - 0 => Ok(Self::Twilight), - 1 => Ok(Self::Glyph), - _ => Err(HintErrorKind::InvalidZoneIndex(value)), - } - } -} - -/// Glyph zone for TrueType hinting. -/// -/// See -#[derive(Default, Debug)] -pub struct Zone<'a> { - /// Outline points prior to applying scale. - pub unscaled: &'a [Point], - /// Copy of the outline points after applying scale. - pub original: &'a mut [Point], - /// Scaled outline points. - pub points: &'a mut [Point], - pub flags: &'a mut [PointFlags], - pub contours: &'a [u16], -} - -impl<'a> Zone<'a> { - /// Creates a new hinting zone. - pub fn new( - unscaled: &'a [Point], - original: &'a mut [Point], - points: &'a mut [Point], - flags: &'a mut [PointFlags], - contours: &'a [u16], - ) -> Self { - Self { - unscaled, - original, - points, - flags, - contours, - } - } - - pub fn point(&self, index: usize) -> Result, HintErrorKind> { - self.points - .get(index) - .copied() - .ok_or(InvalidPointIndex(index)) - } - - pub fn point_mut(&mut self, index: usize) -> Result<&mut Point, HintErrorKind> { - self.points.get_mut(index).ok_or(InvalidPointIndex(index)) - } - - pub fn original(&self, index: usize) -> Result, HintErrorKind> { - self.original - .get(index) - .copied() - .ok_or(InvalidPointIndex(index)) - } - - pub fn original_mut(&mut self, index: usize) -> Result<&mut Point, HintErrorKind> { - self.original.get_mut(index).ok_or(InvalidPointIndex(index)) - } - - pub fn unscaled(&self, index: usize) -> Point { - // Unscaled points in the twilight zone are always (0, 0). This allows - // us to avoid the allocation for that zone and back it with an empty - // slice. - self.unscaled.get(index).copied().unwrap_or_default() - } - - pub fn contour(&self, index: usize) -> Result { - self.contours - .get(index) - .copied() - .ok_or(HintErrorKind::InvalidContourIndex(index)) - } - - pub fn touch(&mut self, index: usize, axis: CoordAxis) -> Result<(), HintErrorKind> { - let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; - flag.set_marker(axis.touched_marker()); - Ok(()) - } - - pub fn untouch(&mut self, index: usize, axis: CoordAxis) -> Result<(), HintErrorKind> { - let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; - flag.clear_marker(axis.touched_marker()); - Ok(()) - } - - pub fn is_touched(&self, index: usize, axis: CoordAxis) -> Result { - let flag = self.flags.get(index).ok_or(InvalidPointIndex(index))?; - Ok(flag.has_marker(axis.touched_marker())) - } - - pub fn flip_on_curve(&mut self, index: usize) -> Result<(), HintErrorKind> { - let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; - flag.flip_on_curve(); - Ok(()) - } - - pub fn set_on_curve( - &mut self, - start: usize, - end: usize, - on: bool, - ) -> Result<(), HintErrorKind> { - let flags = self - .flags - .get_mut(start..end) - .ok_or(InvalidPointRange(start, end))?; - if on { - for flag in flags { - flag.set_on_curve(); - } - } else { - for flag in flags { - flag.clear_on_curve(); - } - } - Ok(()) - } - - /// Interpolate untouched points. - /// - /// Based on - pub fn iup(&mut self, axis: CoordAxis) -> Result<(), HintErrorKind> { - let mut point = 0; - for i in 0..self.contours.len() { - let mut end_point = self.contour(i)? as usize; - let first_point = point; - if end_point >= self.points.len() { - end_point = self.points.len() - 1; - } - while point <= end_point && !self.is_touched(point, axis)? { - point += 1; - } - if point <= end_point { - let first_touched = point; - let mut cur_touched = point; - point += 1; - while point <= end_point { - if self.is_touched(point, axis)? { - self.iup_interpolate(axis, cur_touched + 1, point - 1, cur_touched, point)?; - cur_touched = point; - } - point += 1; - } - if cur_touched == first_touched { - self.iup_shift(axis, first_point, end_point, cur_touched)?; - } else { - self.iup_interpolate( - axis, - cur_touched + 1, - end_point, - cur_touched, - first_touched, - )?; - if first_touched > 0 { - self.iup_interpolate( - axis, - first_point, - first_touched - 1, - cur_touched, - first_touched, - )?; - } - } - } - } - Ok(()) - } - - /// Shift the range of points p1..=p2 based on the delta given by the - /// reference point p. - /// - /// Based on - fn iup_shift( - &mut self, - axis: CoordAxis, - p1: usize, - p2: usize, - p: usize, - ) -> Result<(), HintErrorKind> { - if p1 > p2 || p1 > p || p > p2 { - return Ok(()); - } - macro_rules! shift_coord { - ($coord:ident) => { - let delta = self.point(p)?.$coord - self.original(p)?.$coord; - if delta != F26Dot6::ZERO { - let (first, second) = self - .points - .get_mut(p1..=p2) - .ok_or(InvalidPointRange(p1, p2 + 1))? - .split_at_mut(p - p1); - for point in first - .iter_mut() - .chain(second.get_mut(1..).ok_or(InvalidPointIndex(p - p1))?) - { - point.$coord += delta; - } - } - }; - } - if axis == CoordAxis::X { - shift_coord!(x); - } else { - shift_coord!(y); - } - Ok(()) - } - - /// Interpolate the range of points p1..=p2 based on the deltas - /// given by the two reference points. - /// - /// Based on - fn iup_interpolate( - &mut self, - axis: CoordAxis, - p1: usize, - p2: usize, - mut ref1: usize, - mut ref2: usize, - ) -> Result<(), HintErrorKind> { - if p1 > p2 { - return Ok(()); - } - let max_points = self.points.len(); - if ref1 >= max_points || ref2 >= max_points { - return Ok(()); - } - macro_rules! interpolate_coord { - ($coord:ident) => { - let mut orus1 = self.unscaled(ref1).$coord; - let mut orus2 = self.unscaled(ref2).$coord; - if orus1 > orus2 { - use core::mem::swap; - swap(&mut orus1, &mut orus2); - swap(&mut ref1, &mut ref2); - } - let org1 = self.original(ref1)?.$coord; - let org2 = self.original(ref2)?.$coord; - let cur1 = self.point(ref1)?.$coord; - let cur2 = self.point(ref2)?.$coord; - let delta1 = cur1 - org1; - let delta2 = cur2 - org2; - let iter = self - .original - .get(p1..=p2) - .ok_or(InvalidPointRange(p1, p2 + 1))? - .iter() - .zip( - self.unscaled - .get(p1..=p2) - .ok_or(InvalidPointRange(p1, p2 + 1))?, - ) - .zip( - self.points - .get_mut(p1..=p2) - .ok_or(InvalidPointRange(p1, p2 + 1))?, - ); - if cur1 == cur2 || orus1 == orus2 { - for ((orig, _unscaled), point) in iter { - let a = orig.$coord; - point.$coord = if a <= org1 { - a + delta1 - } else if a >= org2 { - a + delta2 - } else { - cur1 - }; - } - } else { - let scale = math::div((cur2 - cur1).to_bits(), orus2 - orus1); - for ((orig, unscaled), point) in iter { - let a = orig.$coord; - point.$coord = if a <= org1 { - a + delta1 - } else if a >= org2 { - a + delta2 - } else { - cur1 + F26Dot6::from_bits(math::mul(unscaled.$coord - orus1, scale)) - }; - } - } - }; - } - if axis == CoordAxis::X { - interpolate_coord!(x); - } else { - interpolate_coord!(y); - } - Ok(()) - } -} - -impl<'a> GraphicsState<'a> { - /// Takes an array of (zone pointer, point index) pairs and returns true if - /// all accesses would be valid. - pub fn in_bounds(&self, pairs: [(ZonePointer, usize); N]) -> bool { - for (zp, index) in pairs { - if index > self.zone(zp).points.len() { - return false; - } - } - true - } - - #[inline(always)] - pub fn zone(&self, pointer: ZonePointer) -> &Zone<'a> { - &self.zones[pointer as usize] - } - - #[inline(always)] - pub fn zone_mut(&mut self, pointer: ZonePointer) -> &mut Zone<'a> { - &mut self.zones[pointer as usize] - } - - #[inline(always)] - pub fn zp0(&self) -> &Zone<'a> { - self.zone(self.zp0) - } - - #[inline(always)] - pub fn zp0_mut(&mut self) -> &mut Zone<'a> { - self.zone_mut(self.zp0) - } - - #[inline(always)] - pub fn zp1(&self) -> &Zone { - self.zone(self.zp1) - } - - #[inline(always)] - pub fn zp1_mut(&mut self) -> &mut Zone<'a> { - self.zone_mut(self.zp1) - } - - #[inline(always)] - pub fn zp2(&self) -> &Zone { - self.zone(self.zp2) - } - - #[inline(always)] - pub fn zp2_mut(&mut self) -> &mut Zone<'a> { - self.zone_mut(self.zp2) - } -} - -impl GraphicsState<'_> { - /// Moves the requested original point by the given distance. - // See - pub(crate) fn move_original( - &mut self, - zone: ZonePointer, - point_ix: usize, - distance: F26Dot6, - ) -> Result<(), HintErrorKind> { - let fv = self.freedom_vector; - let fdotp = self.fdotp; - let axis = self.freedom_axis; - let point = self.zone_mut(zone).original_mut(point_ix)?; - match axis { - CoordAxis::X => point.x += distance, - CoordAxis::Y => point.y += distance, - CoordAxis::Both => { - let distance = distance.to_bits(); - if fv.x != 0 { - point.x += F26Dot6::from_bits(math::mul_div(distance, fv.x, fdotp)); - } - if fv.y != 0 { - point.y += F26Dot6::from_bits(math::mul_div(distance, fv.y, fdotp)); - } - } - } - Ok(()) - } - - /// Moves the requested scaled point by the given distance. - /// See - pub(crate) fn move_point( - &mut self, - zone: ZonePointer, - point_ix: usize, - distance: F26Dot6, - ) -> Result<(), HintErrorKind> { - // Note: we never adjust x in backward compatibility mode and we never - // adjust y in backward compatibility mode after IUP has been done in - // both directions. - // - // The primary motivation is to avoid horizontal adjustments in cases - // where subpixel rendering provides better fidelity. - // - // For more detail, see - let back_compat = self.backward_compatibility; - let back_compat_and_did_iup = back_compat && self.did_iup_x && self.did_iup_y; - let zone = &mut self.zones[zone as usize]; - let point = zone.point_mut(point_ix)?; - match self.freedom_axis { - CoordAxis::X => { - if !back_compat { - point.x += distance; - } - zone.touch(point_ix, CoordAxis::X)?; - } - CoordAxis::Y => { - if !back_compat_and_did_iup { - point.y += distance; - } - zone.touch(point_ix, CoordAxis::Y)?; - } - CoordAxis::Both => { - // - let fv = self.freedom_vector; - let distance = distance.to_bits(); - if fv.x != 0 { - if !back_compat { - point.x += F26Dot6::from_bits(math::mul_div(distance, fv.x, self.fdotp)); - } - zone.touch(point_ix, CoordAxis::X)?; - } - if fv.y != 0 { - if !back_compat_and_did_iup { - zone.point_mut(point_ix)?.y += - F26Dot6::from_bits(math::mul_div(distance, fv.y, self.fdotp)); - } - zone.touch(point_ix, CoordAxis::Y)?; - } - } - } - Ok(()) - } - - /// Moves the requested scaled point in the zone referenced by zp2 by the - /// given delta. - /// - /// This is a helper function for SHP, SHC, SHZ, and SHPIX instructions. - /// - /// See - pub(crate) fn move_zp2_point( - &mut self, - point_ix: usize, - dx: F26Dot6, - dy: F26Dot6, - do_touch: bool, - ) -> Result<(), HintErrorKind> { - // See notes above in move_point() about how this is used. - let back_compat = self.backward_compatibility; - let back_compat_and_did_iup = back_compat && self.did_iup_x && self.did_iup_y; - let fv = self.freedom_vector; - let zone = self.zp2_mut(); - if fv.x != 0 { - if !back_compat { - zone.point_mut(point_ix)?.x += dx; - } - if do_touch { - zone.touch(point_ix, CoordAxis::X)?; - } - } - if fv.y != 0 { - if !back_compat_and_did_iup { - zone.point_mut(point_ix)?.y += dy; - } - if do_touch { - zone.touch(point_ix, CoordAxis::Y)?; - } - } - Ok(()) - } - - /// Computes the adjustment made to a point along the current freedom vector. - /// See - pub(crate) fn point_displacement( - &mut self, - opcode: u8, - ) -> Result { - let (zone, point_ix) = if (opcode & 1) != 0 { - (self.zp0, self.rp1) - } else { - (self.zp1, self.rp2) - }; - let zone_data = self.zone(zone); - let point = zone_data.point(point_ix)?; - let original_point = zone_data.original(point_ix)?; - let distance = self.project(point, original_point); - let fv = self.freedom_vector; - let dx = F26Dot6::from_bits(math::mul_div(distance.to_bits(), fv.x, self.fdotp)); - let dy = F26Dot6::from_bits(math::mul_div(distance.to_bits(), fv.y, self.fdotp)); - Ok(PointDisplacement { - zone, - point_ix, - dx, - dy, - }) - } -} - -#[derive(PartialEq, Debug)] -pub(crate) struct PointDisplacement { - pub zone: ZonePointer, - pub point_ix: usize, - pub dx: F26Dot6, - pub dy: F26Dot6, -} - -impl CoordAxis { - fn touched_marker(self) -> PointMarker { - match self { - CoordAxis::Both => PointMarker::TOUCHED, - CoordAxis::X => PointMarker::TOUCHED_X, - CoordAxis::Y => PointMarker::TOUCHED_Y, - } - } -} - -#[cfg(test)] -mod tests { - use super::{math, CoordAxis, GraphicsState, PointDisplacement, Zone, ZonePointer}; - use raw::{ - tables::glyf::{PointFlags, PointMarker}, - types::{F26Dot6, Point}, - }; - - #[test] - fn flip_on_curve_point() { - let on_curve = PointFlags::on_curve(); - let off_curve = PointFlags::off_curve_quad(); - let mut zone = Zone { - unscaled: &mut [], - original: &mut [], - points: &mut [], - contours: &[], - flags: &mut [on_curve, off_curve, off_curve, on_curve], - }; - for i in 0..4 { - zone.flip_on_curve(i).unwrap(); - } - assert_eq!(zone.flags, &[off_curve, on_curve, on_curve, off_curve]); - } - - #[test] - fn set_on_curve_regions() { - let on_curve = PointFlags::on_curve(); - let off_curve = PointFlags::off_curve_quad(); - let mut zone = Zone { - unscaled: &mut [], - original: &mut [], - points: &mut [], - contours: &[], - flags: &mut [on_curve, off_curve, off_curve, on_curve], - }; - zone.set_on_curve(0, 2, true).unwrap(); - zone.set_on_curve(2, 4, false).unwrap(); - assert_eq!(zone.flags, &[on_curve, on_curve, off_curve, off_curve]); - } - - #[test] - fn iup_shift() { - let [untouched, touched] = point_markers(); - // A single touched point shifts the whole contour - let mut original = f26dot6_points([(0, 0), (10, 10), (20, 20)]); - let mut points = f26dot6_points([(-5, -20), (10, 10), (20, 20)]); - let mut zone = Zone { - unscaled: &mut [], - original: &mut original, - points: &mut points, - contours: &[3], - flags: &mut [touched, untouched, untouched], - }; - zone.iup(CoordAxis::X).unwrap(); - assert_eq!(zone.points, &f26dot6_points([(-5, -20), (5, 10), (15, 20)]),); - zone.iup(CoordAxis::Y).unwrap(); - assert_eq!(zone.points, &f26dot6_points([(-5, -20), (5, -10), (15, 0)]),); - } - - #[test] - fn iup_interpolate() { - let [untouched, touched] = point_markers(); - // Two touched points interpolates the intermediate point(s) - let mut original = f26dot6_points([(0, 0), (10, 10), (20, 20)]); - let mut points = f26dot6_points([(-5, -20), (10, 10), (27, 56)]); - let mut zone = Zone { - unscaled: &mut [ - Point::new(0, 0), - Point::new(500, 500), - Point::new(1000, 1000), - ], - original: &mut original, - points: &mut points, - contours: &[3], - flags: &mut [touched, untouched, touched], - }; - zone.iup(CoordAxis::X).unwrap(); - assert_eq!( - zone.points, - &f26dot6_points([(-5, -20), (11, 10), (27, 56)]), - ); - zone.iup(CoordAxis::Y).unwrap(); - assert_eq!( - zone.points, - &f26dot6_points([(-5, -20), (11, 18), (27, 56)]), - ); - } - - #[test] - fn move_point_x() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 0); - let point_ix = 0; - let orig_x = gs.zones[1].point(point_ix).unwrap().x; - let dx = F26Dot6::from_bits(10); - // backward compatibility is on by default and we don't move x coord - gs.move_point(ZonePointer::Glyph, 0, dx).unwrap(); - assert_eq!(orig_x, gs.zones[1].point(point_ix).unwrap().x); - // disable so we actually move - gs.backward_compatibility = false; - gs.move_point(ZonePointer::Glyph, 0, dx).unwrap(); - let new_x = gs.zones[1].point(point_ix).unwrap().x; - assert_ne!(orig_x, new_x); - assert_eq!(new_x, orig_x + dx) - } - - #[test] - fn move_point_y() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(0, 100); - let point_ix = 0; - let orig_y = gs.zones[1].point(point_ix).unwrap().y; - let dy = F26Dot6::from_bits(10); - // movement in y is prevented post-iup when backward - // compatibility is enabled - gs.did_iup_x = true; - gs.did_iup_y = true; - gs.move_point(ZonePointer::Glyph, 0, dy).unwrap(); - assert_eq!(orig_y, gs.zones[1].point(point_ix).unwrap().y); - // allow movement - gs.did_iup_x = false; - gs.did_iup_y = false; - gs.move_point(ZonePointer::Glyph, 0, dy).unwrap(); - let new_y = gs.zones[1].point(point_ix).unwrap().y; - assert_ne!(orig_y, new_y); - assert_eq!(new_y, orig_y + dy) - } - - #[test] - fn move_point_x_and_y() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 50); - let point_ix = 0; - let orig_point = gs.zones[1].point(point_ix).unwrap(); - let dist = F26Dot6::from_bits(10); - // prevent movement in x and y - gs.did_iup_x = true; - gs.did_iup_y = true; - gs.move_point(ZonePointer::Glyph, 0, dist).unwrap(); - assert_eq!(orig_point, gs.zones[1].point(point_ix).unwrap()); - // allow movement - gs.backward_compatibility = false; - gs.did_iup_x = false; - gs.did_iup_y = false; - gs.move_point(ZonePointer::Glyph, 0, dist).unwrap(); - let point = gs.zones[1].point(point_ix).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(4, -16)); - } - - #[test] - fn move_original_x() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 0); - let point_ix = 0; - let orig_x = gs.zones[1].original(point_ix).unwrap().x; - let dx = F26Dot6::from_bits(10); - gs.move_original(ZonePointer::Glyph, 0, dx).unwrap(); - let new_x = gs.zones[1].original(point_ix).unwrap().x; - assert_eq!(new_x, orig_x + dx) - } - - #[test] - fn move_original_y() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(0, 100); - let point_ix = 0; - let orig_y = gs.zones[1].original(point_ix).unwrap().y; - let dy = F26Dot6::from_bits(10); - gs.move_original(ZonePointer::Glyph, 0, dy).unwrap(); - let new_y = gs.zones[1].original(point_ix).unwrap().y; - assert_eq!(new_y, orig_y + dy) - } - - #[test] - fn move_original_x_and_y() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 50); - let point_ix = 0; - let dist = F26Dot6::from_bits(10); - gs.move_original(ZonePointer::Glyph, 0, dist).unwrap(); - let point = gs.zones[1].original(point_ix).unwrap(); - assert_eq!(point.map(F26Dot6::to_bits), Point::new(9, 4)); - } - - #[test] - fn move_zp2_point() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 50); - gs.zp2 = ZonePointer::Glyph; - let point_ix = 0; - let orig_point = gs.zones[1].point(point_ix).unwrap(); - let dx = F26Dot6::from_bits(10); - let dy = F26Dot6::from_bits(-10); - // prevent movement in x and y - gs.did_iup_x = true; - gs.did_iup_y = true; - gs.move_zp2_point(point_ix, dx, dy, false).unwrap(); - assert_eq!(orig_point, gs.zones[1].point(point_ix).unwrap()); - // allow movement - gs.backward_compatibility = false; - gs.did_iup_x = false; - gs.did_iup_y = false; - gs.move_zp2_point(point_ix, dx, dy, false).unwrap(); - let point = gs.zones[1].point(point_ix).unwrap(); - assert_eq!(point, orig_point + Point::new(dx, dy)); - } - - #[test] - fn point_displacement() { - let mut mock = MockGraphicsState::new(); - let mut gs = mock.graphics_state(100, 50); - gs.zp0 = ZonePointer::Glyph; - gs.rp1 = 0; - assert_eq!( - gs.point_displacement(1).unwrap(), - PointDisplacement { - zone: ZonePointer::Glyph, - point_ix: 0, - dx: F26Dot6::from_f64(-0.1875), - dy: F26Dot6::from_f64(-0.09375), - } - ); - gs.rp2 = 2; - assert_eq!( - gs.point_displacement(0).unwrap(), - PointDisplacement { - zone: ZonePointer::Glyph, - point_ix: 2, - dx: F26Dot6::from_f64(0.390625), - dy: F26Dot6::from_f64(0.203125), - } - ); - } - - struct MockGraphicsState { - points: [Point; 3], - original: [Point; 3], - contours: [u16; 1], - flags: [PointFlags; 3], - } - - impl MockGraphicsState { - fn new() -> Self { - Self { - points: f26dot6_points([(-5, -20), (10, 10), (20, 20)]), - original: f26dot6_points([(0, 0), (10, 10), (20, -42)]), - flags: [PointFlags::default(); 3], - contours: [3], - } - } - - fn graphics_state(&mut self, fv_x: i32, fv_y: i32) -> GraphicsState { - let glyph = Zone { - unscaled: &mut [], - original: &mut self.original, - points: &mut self.points, - contours: &self.contours, - flags: &mut self.flags, - }; - let v = math::normalize14(fv_x, fv_y); - let mut gs = GraphicsState { - zones: [Zone::default(), glyph], - freedom_vector: v, - proj_vector: v, - zp0: ZonePointer::Glyph, - ..Default::default() - }; - gs.update_projection_state(); - gs - } - } - - fn point_markers() -> [PointFlags; 2] { - let untouched = PointFlags::default(); - let mut touched = untouched; - touched.set_marker(PointMarker::TOUCHED); - [untouched, touched] - } - - fn f26dot6_points(points: [(i32, i32); N]) -> [Point; N] { - points.map(|point| Point::new(F26Dot6::from_bits(point.0), F26Dot6::from_bits(point.1))) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,271 +0,0 @@ -//! Memory allocation for TrueType scaling. - -use std::mem::{align_of, size_of}; - -use read_fonts::{ - tables::glyf::PointFlags, - types::{F26Dot6, Fixed, Point}, -}; - -use super::{super::Hinting, Outline}; - -/// Buffers used during HarfBuzz-style glyph scaling. -pub(crate) struct HarfBuzzOutlineMemory<'a> { - pub points: &'a mut [Point], - pub contours: &'a mut [u16], - pub flags: &'a mut [PointFlags], - pub deltas: &'a mut [Point], - pub iup_buffer: &'a mut [Point], - pub composite_deltas: &'a mut [Point], -} - -impl<'a> HarfBuzzOutlineMemory<'a> { - pub(super) fn new(outline: &Outline, buf: &'a mut [u8]) -> Option { - let (points, buf) = alloc_slice(buf, outline.points)?; - let (contours, buf) = alloc_slice(buf, outline.contours)?; - let (flags, buf) = alloc_slice(buf, outline.points)?; - // Don't allocate any delta buffers if we don't have variations - let (deltas, iup_buffer, composite_deltas, _buf) = if outline.has_variations { - let (deltas, buf) = alloc_slice(buf, outline.max_simple_points)?; - let (iup_buffer, buf) = alloc_slice(buf, outline.max_simple_points)?; - let (composite_deltas, buf) = alloc_slice(buf, outline.max_component_delta_stack)?; - (deltas, iup_buffer, composite_deltas, buf) - } else { - ( - Default::default(), - Default::default(), - Default::default(), - buf, - ) - }; - Some(Self { - points, - contours, - flags, - deltas, - iup_buffer, - composite_deltas, - }) - } -} - -/// Buffers used during glyph scaling. -pub(crate) struct FreeTypeOutlineMemory<'a> { - pub unscaled: &'a mut [Point], - pub scaled: &'a mut [Point], - pub original_scaled: &'a mut [Point], - pub contours: &'a mut [u16], - pub flags: &'a mut [PointFlags], - pub deltas: &'a mut [Point], - pub iup_buffer: &'a mut [Point], - pub composite_deltas: &'a mut [Point], - pub stack: &'a mut [i32], - pub cvt: &'a mut [i32], - pub storage: &'a mut [i32], - pub twilight_scaled: &'a mut [Point], - pub twilight_original_scaled: &'a mut [Point], - pub twilight_flags: &'a mut [PointFlags], -} - -impl<'a> FreeTypeOutlineMemory<'a> { - pub(super) fn new(outline: &Outline, buf: &'a mut [u8], hinting: Hinting) -> Option { - let hinted = outline.has_hinting && hinting == Hinting::Embedded; - let (scaled, buf) = alloc_slice(buf, outline.points)?; - let (unscaled, buf) = alloc_slice(buf, outline.max_other_points)?; - // We only need original scaled points when hinting - let (original_scaled, buf) = if hinted { - alloc_slice(buf, outline.max_other_points)? - } else { - (Default::default(), buf) - }; - // Don't allocate any delta buffers if we don't have variations - let (deltas, iup_buffer, composite_deltas, buf) = if outline.has_variations { - let (deltas, buf) = alloc_slice(buf, outline.max_simple_points)?; - let (iup_buffer, buf) = alloc_slice(buf, outline.max_simple_points)?; - let (composite_deltas, buf) = alloc_slice(buf, outline.max_component_delta_stack)?; - (deltas, iup_buffer, composite_deltas, buf) - } else { - ( - Default::default(), - Default::default(), - Default::default(), - buf, - ) - }; - // Hinting value stack - let (stack, buf) = if hinted { - alloc_slice(buf, outline.max_stack)? - } else { - (Default::default(), buf) - }; - // Copy-on-write buffers for CVT and storage area - let (cvt, storage, buf) = if hinted { - let (cvt, buf) = alloc_slice(buf, outline.cvt_count)?; - let (storage, buf) = alloc_slice(buf, outline.storage_count)?; - (cvt, storage, buf) - } else { - (Default::default(), Default::default(), buf) - }; - // Twilight zone point buffers - let (twilight_scaled, twilight_original_scaled, buf) = if hinted { - let (scaled, buf) = alloc_slice(buf, outline.max_twilight_points)?; - let (original_scaled, buf) = alloc_slice(buf, outline.max_twilight_points)?; - (scaled, original_scaled, buf) - } else { - (Default::default(), Default::default(), buf) - }; - let (contours, buf) = alloc_slice(buf, outline.contours)?; - let (flags, buf) = alloc_slice(buf, outline.points)?; - // Twilight zone point flags - let twilight_flags = if hinted { - alloc_slice(buf, outline.max_twilight_points)?.0 - } else { - Default::default() - }; - Some(Self { - unscaled, - scaled, - original_scaled, - contours, - flags, - deltas, - iup_buffer, - composite_deltas, - stack, - cvt, - storage, - twilight_scaled, - twilight_original_scaled, - twilight_flags, - }) - } -} - -/// Allocates a mutable slice of `T` of the given length from the specified -/// buffer. -/// -/// Returns the allocated slice and the remainder of the buffer. -fn alloc_slice(buf: &mut [u8], len: usize) -> Option<(&mut [T], &mut [u8])> -where - T: bytemuck::AnyBitPattern + bytemuck::NoUninit, -{ - if len == 0 { - return Some((Default::default(), buf)); - } - // 1) Ensure we slice the buffer at a position that is properly aligned - // for T. - let base_ptr = buf.as_ptr() as usize; - let aligned_ptr = align_up(base_ptr, align_of::()); - let aligned_offset = aligned_ptr - base_ptr; - let buf = buf.get_mut(aligned_offset..)?; - // 2) Ensure we have enough space in the buffer to allocate our slice. - let len_in_bytes = len * size_of::(); - if len_in_bytes > buf.len() { - return None; - } - let (slice_buf, rest) = buf.split_at_mut(len_in_bytes); - // Bytemuck handles all safety guarantees here. - let slice = bytemuck::try_cast_slice_mut(slice_buf).ok()?; - Some((slice, rest)) -} - -fn align_up(len: usize, alignment: usize) -> usize { - len + (len.wrapping_neg() & (alignment - 1)) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn unaligned_buffer() { - let mut buf = [0u8; 40]; - let alignment = align_of::(); - let addr = buf.as_ptr() as usize; - let mut unaligned_addr = addr; - // Force an unaligned offset - if unaligned_addr % alignment == 0 { - unaligned_addr += 1; - } - let unaligned_offset = unaligned_addr - addr; - let unaligned = &mut buf[unaligned_offset..]; - assert!(unaligned.as_ptr() as usize % alignment != 0); - let (slice, _) = alloc_slice::(unaligned, 8).unwrap(); - assert_eq!(slice.as_ptr() as usize % alignment, 0); - } - - #[test] - fn fail_unaligned_buffer() { - let mut buf = [0u8; 40]; - let alignment = align_of::(); - let addr = buf.as_ptr() as usize; - let mut unaligned_addr = addr; - // Force an unaligned offset - if unaligned_addr % alignment == 0 { - unaligned_addr += 1; - } - let unaligned_offset = unaligned_addr - addr; - let unaligned = &mut buf[unaligned_offset..]; - assert_eq!(alloc_slice::(unaligned, 16), None); - } - - #[test] - fn outline_memory() { - let outline_info = Outline { - glyph: None, - glyph_id: Default::default(), - points: 10, - contours: 4, - max_simple_points: 4, - max_other_points: 4, - max_component_delta_stack: 4, - max_stack: 0, - cvt_count: 0, - storage_count: 0, - max_twilight_points: 0, - has_hinting: false, - has_variations: true, - has_overlaps: false, - }; - let required_size = outline_info.required_buffer_size(Hinting::None); - let mut buf = vec![0u8; required_size]; - let memory = FreeTypeOutlineMemory::new(&outline_info, &mut buf, Hinting::None).unwrap(); - assert_eq!(memory.scaled.len(), outline_info.points); - assert_eq!(memory.unscaled.len(), outline_info.max_other_points); - // We don't allocate this buffer when hinting is disabled - assert_eq!(memory.original_scaled.len(), 0); - assert_eq!(memory.flags.len(), outline_info.points); - assert_eq!(memory.contours.len(), outline_info.contours); - assert_eq!(memory.deltas.len(), outline_info.max_simple_points); - assert_eq!(memory.iup_buffer.len(), outline_info.max_simple_points); - assert_eq!( - memory.composite_deltas.len(), - outline_info.max_component_delta_stack - ); - } - - #[test] - fn fail_outline_memory() { - let outline_info = Outline { - glyph: None, - glyph_id: Default::default(), - points: 10, - contours: 4, - max_simple_points: 4, - max_other_points: 4, - max_component_delta_stack: 4, - max_stack: 0, - cvt_count: 0, - storage_count: 0, - max_twilight_points: 0, - has_hinting: false, - has_variations: true, - has_overlaps: false, - }; - // Required size adds 4 bytes slop to account for internal alignment - // requirements. So subtract 5 to force a failure. - let not_enough = outline_info.required_buffer_size(Hinting::None) - 5; - let mut buf = vec![0u8; not_enough]; - assert!(FreeTypeOutlineMemory::new(&outline_info, &mut buf, Hinting::None).is_none()); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1427 +0,0 @@ -//! Scaling support for TrueType outlines. - -mod deltas; -mod hint; -mod memory; -mod outline; - -#[cfg(feature = "libm")] -#[allow(unused_imports)] -use core_maths::CoreFloat; - -use deltas::AvailableVarMetrics; -pub use hint::{HintError, HintInstance, HintOutline}; -pub use outline::{Outline, ScaledOutline}; -use raw::FontRef; - -use super::{DrawError, GlyphHMetrics, Hinting}; -use crate::GLYF_COMPOSITE_RECURSION_LIMIT; -use memory::{FreeTypeOutlineMemory, HarfBuzzOutlineMemory}; - -use read_fonts::{ - tables::{ - glyf::{ - Anchor, CompositeGlyph, CompositeGlyphFlags, Glyf, Glyph, PointMarker, SimpleGlyph, - }, - gvar::Gvar, - hdmx::Hdmx, - loca::Loca, - }, - types::{F26Dot6, F2Dot14, Fixed, GlyphId, Point, Tag}, - TableProvider, -}; - -/// Number of phantom points generated at the end of an outline. -pub const PHANTOM_POINT_COUNT: usize = 4; - -/// Scaler state for TrueType outlines. -#[derive(Clone)] -pub struct Outlines<'a> { - pub(crate) font: FontRef<'a>, - pub(crate) glyph_metrics: GlyphHMetrics<'a>, - loca: Loca<'a>, - glyf: Glyf<'a>, - gvar: Option>, - hdmx: Option>, - fpgm: &'a [u8], - prep: &'a [u8], - cvt_len: u32, - max_function_defs: u16, - max_instruction_defs: u16, - max_twilight_points: u16, - max_stack_elements: u16, - max_storage: u16, - glyph_count: u16, - units_per_em: u16, - os2_vmetrics: [i16; 2], - var_metrics: AvailableVarMetrics, - prefer_interpreter: bool, -} - -impl<'a> Outlines<'a> { - pub fn new(font: &FontRef<'a>) -> Option { - let loca = font.loca(None).ok()?; - let glyf = font.glyf().ok()?; - let glyph_metrics = GlyphHMetrics::new(font)?; - let var_metrics = match glyph_metrics.hvar.as_ref() { - Some(hvar) => { - if hvar.lsb_mapping().is_some() { - AvailableVarMetrics::All - } else { - AvailableVarMetrics::Advances - } - } - None => AvailableVarMetrics::None, - }; - let ( - glyph_count, - max_function_defs, - max_instruction_defs, - max_twilight_points, - max_stack_elements, - max_storage, - max_instructions, - ) = font - .maxp() - .map(|maxp| { - ( - maxp.num_glyphs(), - maxp.max_function_defs().unwrap_or_default(), - maxp.max_instruction_defs().unwrap_or_default(), - // Add 4 for phantom points - // See - maxp.max_twilight_points() - .unwrap_or_default() - .saturating_add(4), - // Add 32 to match FreeType's heuristic for buggy fonts - // See - maxp.max_stack_elements() - .unwrap_or_default() - .saturating_add(32), - maxp.max_storage().unwrap_or_default(), - maxp.max_size_of_instructions().unwrap_or_default(), - ) - }) - .unwrap_or_default(); - let os2_vmetrics = font - .os2() - .map(|os2| [os2.s_typo_ascender(), os2.s_typo_descender()]) - .unwrap_or_default(); - let fpgm = font - .data_for_tag(Tag::new(b"fpgm")) - .unwrap_or_default() - .as_bytes(); - let prep = font - .data_for_tag(Tag::new(b"prep")) - .unwrap_or_default() - .as_bytes(); - // Copy FreeType's logic on whether to use the interpreter: - // - let prefer_interpreter = !(max_instructions == 0 && fpgm.is_empty() && prep.is_empty()); - let cvt_len = font.cvt().map(|cvt| cvt.len() as u32).unwrap_or_default(); - Some(Self { - font: font.clone(), - glyph_metrics, - loca, - glyf, - gvar: font.gvar().ok(), - hdmx: font.hdmx().ok(), - fpgm, - prep, - cvt_len, - max_function_defs, - max_instruction_defs, - max_twilight_points, - max_stack_elements, - max_storage, - glyph_count, - units_per_em: font.head().ok()?.units_per_em(), - os2_vmetrics, - var_metrics, - prefer_interpreter, - }) - } - - pub fn units_per_em(&self) -> u16 { - self.units_per_em - } - - pub fn glyph_count(&self) -> usize { - self.glyph_count as usize - } - - pub fn prefer_interpreter(&self) -> bool { - self.prefer_interpreter - } - - pub fn outline(&self, glyph_id: GlyphId) -> Result, DrawError> { - let mut outline = Outline { - glyph_id, - has_variations: self.gvar.is_some(), - ..Default::default() - }; - let glyph = self.loca.get_glyf(glyph_id, &self.glyf)?; - if let Some(glyph) = glyph.as_ref() { - self.outline_rec(glyph, &mut outline, 0, 0)?; - } - outline.points += PHANTOM_POINT_COUNT; - outline.max_stack = self.max_stack_elements as usize; - outline.cvt_count = self.cvt_len as usize; - outline.storage_count = self.max_storage as usize; - outline.max_twilight_points = self.max_twilight_points as usize; - outline.glyph = glyph; - Ok(outline) - } - - pub fn compute_scale(&self, ppem: Option) -> (bool, F26Dot6) { - if let Some(ppem) = ppem { - if self.units_per_em > 0 { - return ( - true, - F26Dot6::from_bits((ppem * 64.) as i32) - / F26Dot6::from_bits(self.units_per_em as i32), - ); - } - } - (false, F26Dot6::from_bits(0x10000)) - } -} - -impl Outlines<'_> { - fn outline_rec( - &self, - glyph: &Glyph, - outline: &mut Outline, - component_depth: usize, - recurse_depth: usize, - ) -> Result<(), DrawError> { - if recurse_depth > GLYF_COMPOSITE_RECURSION_LIMIT { - return Err(DrawError::RecursionLimitExceeded(outline.glyph_id)); - } - match glyph { - Glyph::Simple(simple) => { - let num_points = simple.num_points(); - let num_points_with_phantom = num_points + PHANTOM_POINT_COUNT; - outline.max_simple_points = outline.max_simple_points.max(num_points_with_phantom); - outline.points += num_points; - outline.contours += simple.end_pts_of_contours().len(); - outline.has_hinting = outline.has_hinting || simple.instruction_length() != 0; - outline.max_other_points = outline.max_other_points.max(num_points_with_phantom); - outline.has_overlaps |= simple.has_overlapping_contours(); - } - Glyph::Composite(composite) => { - let (mut count, instructions) = composite.count_and_instructions(); - count += PHANTOM_POINT_COUNT; - let point_base = outline.points; - for (component, flags) in composite.component_glyphs_and_flags() { - outline.has_overlaps |= flags.contains(CompositeGlyphFlags::OVERLAP_COMPOUND); - let component_glyph = self.loca.get_glyf(component.into(), &self.glyf)?; - let Some(component_glyph) = component_glyph else { - continue; - }; - self.outline_rec( - &component_glyph, - outline, - component_depth + count, - recurse_depth + 1, - )?; - } - let has_hinting = !instructions.unwrap_or_default().is_empty(); - if has_hinting { - // We only need the "other points" buffers if the - // composite glyph has instructions. - let num_points_in_composite = outline.points - point_base + PHANTOM_POINT_COUNT; - outline.max_other_points = - outline.max_other_points.max(num_points_in_composite); - } - outline.max_component_delta_stack = outline - .max_component_delta_stack - .max(component_depth + count); - outline.has_hinting = outline.has_hinting || has_hinting; - } - } - Ok(()) - } - - fn hdmx_width(&self, ppem: f32, glyph_id: GlyphId) -> Option { - let hdmx = self.hdmx.as_ref()?; - let ppem_u8 = ppem as u8; - // Make sure our ppem is integral and fits into u8 - if ppem_u8 as f32 == ppem { - // - hdmx.record_for_size(ppem_u8)? - .widths - .get(glyph_id.to_u32() as usize) - .copied() - } else { - None - } - } -} - -trait Scaler { - fn coords(&self) -> &[F2Dot14]; - fn outlines(&self) -> &Outlines; - fn setup_phantom_points( - &mut self, - bounds: [i16; 4], - lsb: i32, - advance: i32, - tsb: i32, - vadvance: i32, - ); - fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError>; - fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError>; - fn load_composite( - &mut self, - glyph: &CompositeGlyph, - glyph_id: GlyphId, - recurse_depth: usize, - ) -> Result<(), DrawError>; - - fn load( - &mut self, - glyph: &Option, - glyph_id: GlyphId, - recurse_depth: usize, - ) -> Result<(), DrawError> { - if recurse_depth > GLYF_COMPOSITE_RECURSION_LIMIT { - return Err(DrawError::RecursionLimitExceeded(glyph_id)); - } - let bounds = match &glyph { - Some(glyph) => [glyph.x_min(), glyph.x_max(), glyph.y_min(), glyph.y_max()], - _ => [0; 4], - }; - let outlines = self.outlines(); - let coords: &[F2Dot14] = self.coords(); - let lsb = outlines.glyph_metrics.lsb(glyph_id, coords); - let advance = outlines.glyph_metrics.advance_width(glyph_id, coords); - let [ascent, descent] = outlines.os2_vmetrics.map(|x| x as i32); - let tsb = ascent - bounds[3] as i32; - let vadvance = ascent - descent; - self.setup_phantom_points(bounds, lsb, advance, tsb, vadvance); - match glyph { - Some(Glyph::Simple(simple)) => self.load_simple(simple, glyph_id), - Some(Glyph::Composite(composite)) => { - self.load_composite(composite, glyph_id, recurse_depth) - } - None => self.load_empty(glyph_id), - } - } -} - -/// f32 all the things. Hold your rounding. No hinting. -pub(crate) struct HarfBuzzScaler<'a> { - outlines: &'a Outlines<'a>, - memory: HarfBuzzOutlineMemory<'a>, - coords: &'a [F2Dot14], - point_count: usize, - contour_count: usize, - component_delta_count: usize, - ppem: f32, - scale: F26Dot6, - is_scaled: bool, - /// Phantom points. These are 4 extra points appended to the end of an - /// outline that allow the bytecode interpreter to produce hinted - /// metrics. - /// - /// See - phantom: [Point; PHANTOM_POINT_COUNT], -} - -impl<'a> HarfBuzzScaler<'a> { - pub(crate) fn unhinted( - outlines: &'a Outlines<'a>, - outline: &'a Outline, - buf: &'a mut [u8], - ppem: Option, - coords: &'a [F2Dot14], - ) -> Result { - let (is_scaled, scale) = outlines.compute_scale(ppem); - let memory = - HarfBuzzOutlineMemory::new(outline, buf).ok_or(DrawError::InsufficientMemory)?; - Ok(Self { - outlines, - memory, - coords, - point_count: 0, - contour_count: 0, - component_delta_count: 0, - ppem: ppem.unwrap_or_default(), - scale, - is_scaled, - phantom: Default::default(), - }) - } - - pub(crate) fn scale( - mut self, - glyph: &Option, - glyph_id: GlyphId, - ) -> Result, DrawError> { - self.load(glyph, glyph_id, 0)?; - Ok(ScaledOutline::new( - &mut self.memory.points[..self.point_count], - self.phantom, - &mut self.memory.flags[..self.point_count], - &mut self.memory.contours[..self.contour_count], - self.outlines.hdmx_width(self.ppem, glyph_id), - )) - } -} - -/// F26Dot6 coords, Fixed deltas, and a penchant for rounding -pub(crate) struct FreeTypeScaler<'a> { - outlines: &'a Outlines<'a>, - memory: FreeTypeOutlineMemory<'a>, - coords: &'a [F2Dot14], - point_count: usize, - contour_count: usize, - component_delta_count: usize, - ppem: f32, - scale: F26Dot6, - is_scaled: bool, - is_hinted: bool, - pedantic_hinting: bool, - /// Phantom points. These are 4 extra points appended to the end of an - /// outline that allow the bytecode interpreter to produce hinted - /// metrics. - /// - /// See - phantom: [Point; PHANTOM_POINT_COUNT], - hinter: Option<&'a HintInstance>, -} - -impl<'a> FreeTypeScaler<'a> { - pub(crate) fn unhinted( - outlines: &'a Outlines<'a>, - outline: &'a Outline, - buf: &'a mut [u8], - ppem: Option, - coords: &'a [F2Dot14], - ) -> Result { - let (is_scaled, scale) = outlines.compute_scale(ppem); - let memory = FreeTypeOutlineMemory::new(outline, buf, Hinting::None) - .ok_or(DrawError::InsufficientMemory)?; - Ok(Self { - outlines, - memory, - coords, - point_count: 0, - contour_count: 0, - component_delta_count: 0, - ppem: ppem.unwrap_or_default(), - scale, - is_scaled, - is_hinted: false, - pedantic_hinting: false, - phantom: Default::default(), - hinter: None, - }) - } - - pub(crate) fn hinted( - outlines: &'a Outlines<'a>, - outline: &'a Outline, - buf: &'a mut [u8], - ppem: Option, - coords: &'a [F2Dot14], - hinter: &'a HintInstance, - pedantic_hinting: bool, - ) -> Result { - let (is_scaled, scale) = outlines.compute_scale(ppem); - let memory = FreeTypeOutlineMemory::new(outline, buf, Hinting::Embedded) - .ok_or(DrawError::InsufficientMemory)?; - Ok(Self { - outlines, - memory, - coords, - point_count: 0, - contour_count: 0, - component_delta_count: 0, - ppem: ppem.unwrap_or_default(), - scale, - is_scaled, - // We don't hint unscaled outlines - is_hinted: is_scaled, - pedantic_hinting, - phantom: Default::default(), - hinter: Some(hinter), - }) - } - - pub(crate) fn scale( - mut self, - glyph: &Option, - glyph_id: GlyphId, - ) -> Result, DrawError> { - self.load(glyph, glyph_id, 0)?; - // Use hdmx if hinting is requested and backward compatibility mode - // is not enabled. - // - let hdmx_width = if self.is_hinted - && self - .hinter - .as_ref() - .map(|hinter| !hinter.backward_compatibility()) - .unwrap_or(true) - { - self.outlines.hdmx_width(self.ppem, glyph_id) - } else { - None - }; - Ok(ScaledOutline::new( - &mut self.memory.scaled[..self.point_count], - self.phantom, - &mut self.memory.flags[..self.point_count], - &mut self.memory.contours[..self.contour_count], - hdmx_width, - )) - } -} - -impl Scaler for FreeTypeScaler<'_> { - fn setup_phantom_points( - &mut self, - bounds: [i16; 4], - lsb: i32, - advance: i32, - tsb: i32, - vadvance: i32, - ) { - // The four "phantom" points as computed by FreeType. - // See - // horizontal: - self.phantom[0].x = F26Dot6::from_bits(bounds[0] as i32 - lsb); - self.phantom[0].y = F26Dot6::ZERO; - self.phantom[1].x = self.phantom[0].x + F26Dot6::from_bits(advance); - self.phantom[1].y = F26Dot6::ZERO; - // vertical: - self.phantom[2].x = F26Dot6::ZERO; - self.phantom[2].y = F26Dot6::from_bits(bounds[3] as i32 + tsb); - self.phantom[3].x = F26Dot6::ZERO; - self.phantom[3].y = self.phantom[2].y - F26Dot6::from_bits(vadvance); - } - - fn coords(&self) -> &[F2Dot14] { - self.coords - } - - fn outlines(&self) -> &Outlines { - self.outlines - } - - fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError> { - // Roughly corresponds to the FreeType code at - // - let scale = self.scale; - let mut unscaled = self.phantom.map(|point| point.map(|x| x.to_bits())); - if self.outlines.glyph_metrics.hvar.is_none() - && self.outlines.gvar.is_some() - && !self.coords.is_empty() - { - if let Ok(deltas) = self.outlines.gvar.as_ref().unwrap().phantom_point_deltas( - &self.outlines.glyf, - &self.outlines.loca, - self.coords, - glyph_id, - ) { - unscaled[0] += deltas[0].map(Fixed::to_i32); - unscaled[1] += deltas[1].map(Fixed::to_i32); - } - } - if self.is_scaled { - for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { - *phantom = unscaled.map(F26Dot6::from_bits) * scale; - } - } else { - for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { - *phantom = unscaled.map(F26Dot6::from_i32); - } - } - Ok(()) - } - - fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError> { - use DrawError::InsufficientMemory; - // Compute the ranges for our point/flag buffers and slice them. - let points_start = self.point_count; - let point_count = glyph.num_points(); - let phantom_start = point_count; - let points_end = points_start + point_count + PHANTOM_POINT_COUNT; - let point_range = points_start..points_end; - let other_points_end = point_count + PHANTOM_POINT_COUNT; - // Scaled points and flags are accumulated as we load the outline. - let scaled = self - .memory - .scaled - .get_mut(point_range.clone()) - .ok_or(InsufficientMemory)?; - let flags = self - .memory - .flags - .get_mut(point_range) - .ok_or(InsufficientMemory)?; - // Unscaled points are temporary and are allocated as needed. We only - // ever need one copy in memory for any simple or composite glyph so - // allocate from the base of the buffer. - let unscaled = self - .memory - .unscaled - .get_mut(..other_points_end) - .ok_or(InsufficientMemory)?; - // Read our unscaled points and flags (up to point_count which does not - // include phantom points). - glyph.read_points_fast(&mut unscaled[..point_count], &mut flags[..point_count])?; - // Compute the range for our contour end point buffer and slice it. - let contours_start = self.contour_count; - let contour_end_pts = glyph.end_pts_of_contours(); - let contour_count = contour_end_pts.len(); - let contours_end = contours_start + contour_count; - let contours = self - .memory - .contours - .get_mut(contours_start..contours_end) - .ok_or(InsufficientMemory)?; - // Read the contour end points. - for (end_pt, contour) in contour_end_pts.iter().zip(contours.iter_mut()) { - *contour = end_pt.get(); - } - // Adjust the running point/contour total counts - self.point_count += point_count; - self.contour_count += contour_count; - // Append phantom points to the outline. - for (i, phantom) in self.phantom.iter().enumerate() { - unscaled[phantom_start + i] = phantom.map(|x| x.to_bits()); - flags[phantom_start + i] = Default::default(); - } - let mut have_deltas = false; - if self.outlines.gvar.is_some() && !self.coords.is_empty() { - let gvar = self.outlines.gvar.as_ref().unwrap(); - let glyph = deltas::SimpleGlyph { - points: &mut unscaled[..], - flags: &mut flags[..], - contours, - }; - let deltas = self - .memory - .deltas - .get_mut(..point_count + PHANTOM_POINT_COUNT) - .ok_or(InsufficientMemory)?; - let iup_buffer = self - .memory - .iup_buffer - .get_mut(..point_count + PHANTOM_POINT_COUNT) - .ok_or(InsufficientMemory)?; - if deltas::simple_glyph( - gvar, - glyph_id, - self.coords, - self.outlines.var_metrics, - glyph, - iup_buffer, - deltas, - ) - .is_ok() - { - have_deltas = true; - } - } - let ins = glyph.instructions(); - let is_hinted = self.is_hinted; - if self.is_scaled { - let scale = self.scale; - if have_deltas { - for ((point, unscaled), delta) in scaled - .iter_mut() - .zip(unscaled.iter_mut()) - .zip(self.memory.deltas.iter()) - { - let delta = delta.map(Fixed::to_f26dot6); - let scaled = (unscaled.map(F26Dot6::from_i32) + delta) * scale; - // The computed scale factor has an i32 -> 26.26 conversion built in. This undoes the - // extra shift. - *point = scaled.map(|v| F26Dot6::from_bits(v.to_i32())); - } - if is_hinted { - // For hinting, we need to adjust the unscaled points as well. - // Round off deltas for unscaled outlines. - for (unscaled, delta) in unscaled.iter_mut().zip(self.memory.deltas.iter()) { - *unscaled += delta.map(Fixed::to_i32); - } - } - } else { - for (point, unscaled) in scaled.iter_mut().zip(unscaled.iter_mut()) { - *point = unscaled.map(|v| F26Dot6::from_bits(v) * scale); - } - } - } else { - if have_deltas { - // Round off deltas for unscaled outlines. - for (unscaled, delta) in unscaled.iter_mut().zip(self.memory.deltas.iter()) { - *unscaled += delta.map(Fixed::to_i32); - } - } - // Unlike FreeType, we also store unscaled outlines in 26.6. - for (point, unscaled) in scaled.iter_mut().zip(unscaled.iter()) { - *point = unscaled.map(F26Dot6::from_i32); - } - } - // Commit our potentially modified phantom points. - if self.outlines.glyph_metrics.hvar.is_some() && self.is_hinted { - self.phantom[0] *= self.scale; - self.phantom[1] *= self.scale; - } else { - for (i, point) in scaled[phantom_start..] - .iter() - .enumerate() - .take(PHANTOM_POINT_COUNT) - { - self.phantom[i] = *point; - } - } - if let (Some(hinter), true) = (self.hinter.as_ref(), is_hinted) { - if !ins.is_empty() { - // Create a copy of our scaled points in original_scaled. - let original_scaled = self - .memory - .original_scaled - .get_mut(..other_points_end) - .ok_or(InsufficientMemory)?; - original_scaled.copy_from_slice(scaled); - // When hinting, round the phantom points. - for point in &mut scaled[phantom_start..] { - point.x = point.x.round(); - point.y = point.y.round(); - } - let mut input = HintOutline { - glyph_id, - unscaled, - scaled, - original_scaled, - flags, - contours, - bytecode: ins, - phantom: &mut self.phantom, - stack: self.memory.stack, - cvt: self.memory.cvt, - storage: self.memory.storage, - twilight_scaled: self.memory.twilight_scaled, - twilight_original_scaled: self.memory.twilight_original_scaled, - twilight_flags: self.memory.twilight_flags, - is_composite: false, - coords: self.coords, - }; - let hint_res = hinter.hint(self.outlines, &mut input, self.pedantic_hinting); - if let (Err(e), true) = (hint_res, self.pedantic_hinting) { - return Err(e)?; - } - } else if !hinter.backward_compatibility() { - // Even when missing instructions, FreeType uses rounded - // phantom points when hinting is requested and backward - // compatibility mode is disabled. - // See - // Notably, FreeType never calls TT_Hint_Glyph for composite - // glyphs when instructions are missing so this only applies - // to simple glyphs. - for (scaled, phantom) in scaled[phantom_start..].iter().zip(&mut self.phantom) { - *phantom = scaled.map(|x| x.round()); - } - } - } - if points_start != 0 { - // If we're not the first component, shift our contour end points. - for contour_end in contours.iter_mut() { - *contour_end += points_start as u16; - } - } - Ok(()) - } - - fn load_composite( - &mut self, - glyph: &CompositeGlyph, - glyph_id: GlyphId, - recurse_depth: usize, - ) -> Result<(), DrawError> { - use DrawError::InsufficientMemory; - let scale = self.scale; - // The base indices of the points and contours for the current glyph. - let point_base = self.point_count; - let contour_base = self.contour_count; - // Compute the per component deltas. Since composites can be nested, we - // use a stack and keep track of the base. - let mut have_deltas = false; - let delta_base = self.component_delta_count; - if self.outlines.gvar.is_some() && !self.coords.is_empty() { - let gvar = self.outlines.gvar.as_ref().unwrap(); - let count = glyph.components().count() + PHANTOM_POINT_COUNT; - let deltas = self - .memory - .composite_deltas - .get_mut(delta_base..delta_base + count) - .ok_or(InsufficientMemory)?; - if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { - // Apply selective deltas to phantom points. - self.outlines.var_metrics.phantom_deltas( - &mut self.phantom, - deltas, - |phantom, delta| { - phantom.x += F26Dot6::from_bits(delta.x.to_i32()); - }, - ); - have_deltas = true; - } - self.component_delta_count += count; - } - if self.is_scaled { - for point in self.phantom.iter_mut() { - *point *= scale; - } - } else { - for point in self.phantom.iter_mut() { - *point = point.map(|x| F26Dot6::from_i32(x.to_bits())); - } - } - for (i, component) in glyph.components().enumerate() { - // Loading a component glyph will override phantom points so save a copy. We'll - // restore them unless the USE_MY_METRICS flag is set. - let phantom = self.phantom; - // Load the component glyph and keep track of the points range. - let start_point = self.point_count; - let component_glyph = self - .outlines - .loca - .get_glyf(component.glyph.into(), &self.outlines.glyf)?; - self.load(&component_glyph, component.glyph.into(), recurse_depth + 1)?; - let end_point = self.point_count; - if !component - .flags - .contains(CompositeGlyphFlags::USE_MY_METRICS) - { - // If the USE_MY_METRICS flag is missing, we restore the phantom points we - // saved at the start of the loop. - self.phantom = phantom; - } - // Prepares the transform components for our conversion math below. - fn scale_component(x: F2Dot14) -> F26Dot6 { - F26Dot6::from_bits(x.to_bits() as i32 * 4) - } - let xform = &component.transform; - let xx = scale_component(xform.xx); - let yx = scale_component(xform.yx); - let xy = scale_component(xform.xy); - let yy = scale_component(xform.yy); - let have_xform = component.flags.intersects( - CompositeGlyphFlags::WE_HAVE_A_SCALE - | CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE - | CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO, - ); - if have_xform { - let scaled = &mut self.memory.scaled[start_point..end_point]; - if self.is_scaled { - for point in scaled { - let x = point.x * xx + point.y * xy; - let y = point.x * yx + point.y * yy; - point.x = x; - point.y = y; - } - } else { - for point in scaled { - // This juggling is necessary because, unlike FreeType, we also - // return unscaled outlines in 26.6 format for a consistent interface. - let unscaled = point.map(|c| F26Dot6::from_bits(c.to_i32())); - let x = unscaled.x * xx + unscaled.y * xy; - let y = unscaled.x * yx + unscaled.y * yy; - *point = Point::new(x, y).map(|c| F26Dot6::from_i32(c.to_bits())); - } - } - } - let anchor_offset = match component.anchor { - Anchor::Offset { x, y } => { - let (mut x, mut y) = (x as i32, y as i32); - if have_xform - && component.flags - & (CompositeGlyphFlags::SCALED_COMPONENT_OFFSET - | CompositeGlyphFlags::UNSCALED_COMPONENT_OFFSET) - == CompositeGlyphFlags::SCALED_COMPONENT_OFFSET - { - // According to FreeType, this algorithm is a "guess" - // and works better than the one documented by Apple. - // https://github.com/freetype/freetype/blob/b1c90733ee6a04882b133101d61b12e352eeb290/src/truetype/ttgload.c#L1259 - fn hypot(a: F26Dot6, b: F26Dot6) -> Fixed { - let a = a.to_bits().abs(); - let b = b.to_bits().abs(); - Fixed::from_bits(if a > b { - a + ((3 * b) >> 3) - } else { - b + ((3 * a) >> 3) - }) - } - // FreeType uses a fixed point multiplication here. - x = (Fixed::from_bits(x) * hypot(xx, xy)).to_bits(); - y = (Fixed::from_bits(y) * hypot(yy, yx)).to_bits(); - } - if have_deltas { - let delta = self - .memory - .composite_deltas - .get(delta_base + i) - .copied() - .unwrap_or_default(); - // For composite glyphs, we copy FreeType and round off - // the fractional parts of deltas. - x += delta.x.to_i32(); - y += delta.y.to_i32(); - } - if self.is_scaled { - let mut offset = Point::new(x, y).map(F26Dot6::from_bits) * scale; - if self.is_hinted - && component - .flags - .contains(CompositeGlyphFlags::ROUND_XY_TO_GRID) - { - // Only round the y-coordinate, per FreeType. - offset.y = offset.y.round(); - } - offset - } else { - Point::new(x, y).map(F26Dot6::from_i32) - } - } - Anchor::Point { base, component } => { - let (base_offset, component_offset) = (base as usize, component as usize); - let base_point = self - .memory - .scaled - .get(point_base + base_offset) - .ok_or(DrawError::InvalidAnchorPoint(glyph_id, base))?; - let component_point = self - .memory - .scaled - .get(start_point + component_offset) - .ok_or(DrawError::InvalidAnchorPoint(glyph_id, component))?; - *base_point - *component_point - } - }; - if anchor_offset.x != F26Dot6::ZERO || anchor_offset.y != F26Dot6::ZERO { - for point in &mut self.memory.scaled[start_point..end_point] { - *point += anchor_offset; - } - } - } - if have_deltas { - self.component_delta_count = delta_base; - } - if let (Some(hinter), true) = (self.hinter.as_ref(), self.is_hinted) { - let ins = glyph.instructions().unwrap_or_default(); - if !ins.is_empty() { - // For composite glyphs, the unscaled and original points are - // simply copies of the current point set. - let start_point = point_base; - let end_point = self.point_count + PHANTOM_POINT_COUNT; - let point_range = start_point..end_point; - let phantom_start = point_range.len() - PHANTOM_POINT_COUNT; - let scaled = &mut self.memory.scaled[point_range.clone()]; - let flags = self - .memory - .flags - .get_mut(point_range.clone()) - .ok_or(InsufficientMemory)?; - // Append the current phantom points to the outline. - for (i, phantom) in self.phantom.iter().enumerate() { - scaled[phantom_start + i] = *phantom; - flags[phantom_start + i] = Default::default(); - } - let other_points_end = point_range.len(); - let unscaled = self - .memory - .unscaled - .get_mut(..other_points_end) - .ok_or(InsufficientMemory)?; - for (scaled, unscaled) in scaled.iter().zip(unscaled.iter_mut()) { - *unscaled = scaled.map(|x| x.to_bits()); - } - let original_scaled = self - .memory - .original_scaled - .get_mut(..other_points_end) - .ok_or(InsufficientMemory)?; - original_scaled.copy_from_slice(scaled); - let contours = self - .memory - .contours - .get_mut(contour_base..self.contour_count) - .ok_or(InsufficientMemory)?; - // Round the phantom points. - for p in &mut scaled[phantom_start..] { - p.x = p.x.round(); - p.y = p.y.round(); - } - // Clear the "touched" flags that are used during IUP processing. - for flag in flags.iter_mut() { - flag.clear_marker(PointMarker::TOUCHED); - } - // Make sure our contour end points accurately reflect the - // outline slices. - if point_base != 0 { - let delta = point_base as u16; - for contour in contours.iter_mut() { - *contour -= delta; - } - } - let mut input = HintOutline { - glyph_id, - unscaled, - scaled, - original_scaled, - flags, - contours, - bytecode: ins, - phantom: &mut self.phantom, - stack: self.memory.stack, - cvt: self.memory.cvt, - storage: self.memory.storage, - twilight_scaled: self.memory.twilight_scaled, - twilight_original_scaled: self.memory.twilight_original_scaled, - twilight_flags: self.memory.twilight_flags, - is_composite: true, - coords: self.coords, - }; - let hint_res = hinter.hint(self.outlines, &mut input, self.pedantic_hinting); - if let (Err(e), true) = (hint_res, self.pedantic_hinting) { - return Err(e)?; - } - // Undo the contour shifts if we applied them above. - if point_base != 0 { - let delta = point_base as u16; - for contour in contours.iter_mut() { - *contour += delta; - } - } - } - } - Ok(()) - } -} - -impl Scaler for HarfBuzzScaler<'_> { - fn setup_phantom_points( - &mut self, - bounds: [i16; 4], - lsb: i32, - advance: i32, - tsb: i32, - vadvance: i32, - ) { - // Same pattern as FreeType, just f32 - // horizontal: - self.phantom[0].x = bounds[0] as f32 - lsb as f32; - self.phantom[0].y = 0.0; - self.phantom[1].x = self.phantom[0].x + advance as f32; - self.phantom[1].y = 0.0; - // vertical: - self.phantom[2].x = 0.0; - self.phantom[2].y = bounds[3] as f32 + tsb as f32; - self.phantom[3].x = 0.0; - self.phantom[3].y = self.phantom[2].y - vadvance as f32; - } - - fn coords(&self) -> &[F2Dot14] { - self.coords - } - - fn outlines(&self) -> &Outlines { - self.outlines - } - - fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError> { - // HB doesn't have an equivalent so this version just copies the - // FreeType version above but changed to use floating point - let scale = self.scale.to_f32(); - let mut unscaled = self.phantom; - if self.outlines.glyph_metrics.hvar.is_none() - && self.outlines.gvar.is_some() - && !self.coords.is_empty() - { - if let Ok(deltas) = self.outlines.gvar.as_ref().unwrap().phantom_point_deltas( - &self.outlines.glyf, - &self.outlines.loca, - self.coords, - glyph_id, - ) { - unscaled[0] += deltas[0].map(Fixed::to_f32); - unscaled[1] += deltas[1].map(Fixed::to_f32); - } - } - if self.is_scaled { - for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { - *phantom = *unscaled * scale; - } - } else { - for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { - *phantom = *unscaled; - } - } - Ok(()) - } - - fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError> { - use DrawError::InsufficientMemory; - // Compute the ranges for our point/flag buffers and slice them. - let points_start = self.point_count; - let point_count = glyph.num_points(); - let phantom_start = point_count; - let points_end = points_start + point_count + PHANTOM_POINT_COUNT; - let point_range = points_start..points_end; - // Points and flags are accumulated as we load the outline. - let points = self - .memory - .points - .get_mut(point_range.clone()) - .ok_or(InsufficientMemory)?; - let flags = self - .memory - .flags - .get_mut(point_range) - .ok_or(InsufficientMemory)?; - glyph.read_points_fast(&mut points[..point_count], &mut flags[..point_count])?; - // Compute the range for our contour end point buffer and slice it. - let contours_start = self.contour_count; - let contour_end_pts = glyph.end_pts_of_contours(); - let contour_count = contour_end_pts.len(); - let contours_end = contours_start + contour_count; - let contours = self - .memory - .contours - .get_mut(contours_start..contours_end) - .ok_or(InsufficientMemory)?; - // Read the contour end points. - for (end_pt, contour) in contour_end_pts.iter().zip(contours.iter_mut()) { - *contour = end_pt.get(); - } - // Adjust the running point/contour total counts - self.point_count += point_count; - self.contour_count += contour_count; - // Append phantom points to the outline. - for (i, phantom) in self.phantom.iter().enumerate() { - points[phantom_start + i] = *phantom; - flags[phantom_start + i] = Default::default(); - } - // Acquire deltas - if self.outlines.gvar.is_some() && !self.coords.is_empty() { - let gvar = self.outlines.gvar.as_ref().unwrap(); - let glyph = deltas::SimpleGlyph { - points: &mut points[..], - flags: &mut flags[..], - contours, - }; - let deltas = self - .memory - .deltas - .get_mut(..point_count + PHANTOM_POINT_COUNT) - .ok_or(InsufficientMemory)?; - let iup_buffer = self - .memory - .iup_buffer - .get_mut(..point_count + PHANTOM_POINT_COUNT) - .ok_or(InsufficientMemory)?; - if deltas::simple_glyph( - gvar, - glyph_id, - self.coords, - self.outlines.var_metrics, - glyph, - iup_buffer, - deltas, - ) - .is_ok() - { - for (point, delta) in points.iter_mut().zip(deltas) { - *point += *delta; - } - } - } - // Apply scaling - if self.is_scaled { - let scale = self.scale.to_f32(); - for point in points.iter_mut() { - *point = point.map(|c| c * scale); - } - } - - if points_start != 0 { - // If we're not the first component, shift our contour end points. - for contour_end in contours.iter_mut() { - *contour_end += points_start as u16; - } - } - Ok(()) - } - - fn load_composite( - &mut self, - glyph: &CompositeGlyph, - glyph_id: GlyphId, - recurse_depth: usize, - ) -> Result<(), DrawError> { - use DrawError::InsufficientMemory; - let scale = self.scale.to_f32(); - // The base indices of the points for the current glyph. - let point_base = self.point_count; - // Compute the per component deltas. Since composites can be nested, we - // use a stack and keep track of the base. - let mut have_deltas = false; - let delta_base = self.component_delta_count; - if self.outlines.gvar.is_some() && !self.coords.is_empty() { - let gvar = self.outlines.gvar.as_ref().unwrap(); - let count = glyph.components().count() + PHANTOM_POINT_COUNT; - let deltas = self - .memory - .composite_deltas - .get_mut(delta_base..delta_base + count) - .ok_or(InsufficientMemory)?; - if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { - // Apply selective deltas to phantom points. - self.outlines.var_metrics.phantom_deltas( - &mut self.phantom, - deltas, - |phantom, delta| { - phantom.x += delta.x; - }, - ); - have_deltas = true; - } - self.component_delta_count += count; - } - if self.is_scaled { - for point in self.phantom.iter_mut() { - *point *= scale; - } - } - for (i, component) in glyph.components().enumerate() { - // Loading a component glyph will override phantom points so save a copy. We'll - // restore them unless the USE_MY_METRICS flag is set. - let phantom = self.phantom; - // Load the component glyph and keep track of the points range. - let start_point = self.point_count; - let component_glyph = self - .outlines - .loca - .get_glyf(component.glyph.into(), &self.outlines.glyf)?; - self.load(&component_glyph, component.glyph.into(), recurse_depth + 1)?; - let end_point = self.point_count; - if !component - .flags - .contains(CompositeGlyphFlags::USE_MY_METRICS) - { - // If the USE_MY_METRICS flag is missing, we restore the phantom points we - // saved at the start of the loop. - self.phantom = phantom; - } - let have_xform = component.flags.intersects( - CompositeGlyphFlags::WE_HAVE_A_SCALE - | CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE - | CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO, - ); - let mut transform = if have_xform { - let xform = &component.transform; - [ - xform.xx, - xform.yx, - xform.xy, - xform.yy, - F2Dot14::ZERO, - F2Dot14::ZERO, - ] - .map(|x| x.to_f32()) - } else { - [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] // identity - }; - - let anchor_offset = match component.anchor { - Anchor::Offset { x, y } => { - let (mut x, mut y) = (x as f32, y as f32); - if have_xform - && component.flags - & (CompositeGlyphFlags::SCALED_COMPONENT_OFFSET - | CompositeGlyphFlags::UNSCALED_COMPONENT_OFFSET) - == CompositeGlyphFlags::SCALED_COMPONENT_OFFSET - { - // Scale x by the magnitude of the x-basis, y by the y-basis - // FreeType implements hypot, we can just use the provided implementation - x *= hypot(transform[0], transform[2]); - y *= hypot(transform[1], transform[3]); - } - Point::new(x, y) - + self - .memory - .composite_deltas - .get(delta_base + i) - .copied() - .unwrap_or_default() - } - Anchor::Point { base, component } => { - let (base_offset, component_offset) = (base as usize, component as usize); - let base_point = self - .memory - .points - .get(point_base + base_offset) - .ok_or(DrawError::InvalidAnchorPoint(glyph_id, base))?; - let component_point = self - .memory - .points - .get(start_point + component_offset) - .ok_or(DrawError::InvalidAnchorPoint(glyph_id, component))?; - *base_point - *component_point - } - }; - transform[4] = anchor_offset.x; - transform[5] = anchor_offset.y; - - let points = &mut self.memory.points[start_point..end_point]; - for point in points.iter_mut() { - *point = map_point(transform, *point); - } - } - if have_deltas { - self.component_delta_count = delta_base; - } - Ok(()) - } -} - -/// Magnitude of the vector (x, y) -fn hypot(x: f32, y: f32) -> f32 { - x.hypot(y) -} - -fn map_point(transform: [f32; 6], p: Point) -> Point { - Point { - x: transform[0] * p.x + transform[2] * p.y + transform[4], - y: transform[1] * p.x + transform[3] * p.y + transform[5], - } -} - -impl AvailableVarMetrics { - /// Calls `f` for each combination of phantom point and its associated - /// delta based on the available metrics present in `self`. - fn phantom_deltas( - self, - phantom: &mut [Point

    ; 4], - deltas: &[Point], - f: impl Fn(&mut Point

    , &Point), - ) { - match self { - Self::None => { - f(&mut phantom[0], &deltas[deltas.len() - 4]); - f(&mut phantom[1], &deltas[deltas.len() - 3]); - } - Self::Advances => { - f(&mut phantom[0], &deltas[deltas.len() - 4]); - } - Self::All => {} - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::MetadataProvider; - use read_fonts::{FontRef, TableProvider}; - - #[test] - fn overlap_flags() { - let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); - let scaler = Outlines::new(&font).unwrap(); - let glyph_count = font.maxp().unwrap().num_glyphs(); - // GID 2 is a composite glyph with the overlap bit on a component - // GID 3 is a simple glyph with the overlap bit on the first flag - let expected_gids_with_overlap = vec![2, 3]; - assert_eq!( - expected_gids_with_overlap, - (0..glyph_count) - .filter(|gid| scaler.outline(GlyphId::from(*gid)).unwrap().has_overlaps) - .collect::>() - ); - } - - #[test] - fn interpreter_preference() { - // no instructions in this font... - let font = FontRef::new(font_test_data::COLRV0V1).unwrap(); - let outlines = Outlines::new(&font).unwrap(); - // thus no preference for the interpreter - assert!(!outlines.prefer_interpreter()); - // but this one has instructions... - let font = FontRef::new(font_test_data::TTHINT_SUBSET).unwrap(); - let outlines = Outlines::new(&font).unwrap(); - // so let's use it - assert!(outlines.prefer_interpreter()); - } - - #[test] - fn empty_glyph_advance() { - let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); - let mut outlines = Outlines::new(&font).unwrap(); - let coords = [F2Dot14::from_f32(0.5)]; - let ppem = Some(24.0); - let gid = font.charmap().map(' ').unwrap(); - let outline = outlines.outline(gid).unwrap(); - // Make sure this is an empty outline since that's what we're testing - assert!(outline.glyph.is_none()); - let mut buf = [0u8; 128]; - let scaler = - FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); - let scaled = scaler.scale(&outline.glyph, gid).unwrap(); - let advance_hvar = scaled.adjusted_advance_width(); - // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar - outlines.glyph_metrics.hvar = None; - outlines.var_metrics = AvailableVarMetrics::None; - let scaler = - FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); - let scaled = scaler.scale(&outline.glyph, gid).unwrap(); - let advance_gvar = scaled.adjusted_advance_width(); - // Make sure we have an advance and that the two are the same - assert!(advance_hvar != F26Dot6::ZERO); - assert_eq!(advance_hvar, advance_gvar); - } - - #[test] - fn empty_glyphs_have_phantom_points_too() { - let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); - let outlines = Outlines::new(&font).unwrap(); - let gid = font.charmap().map(' ').unwrap(); - let outline = outlines.outline(gid).unwrap(); - assert!(outline.glyph.is_none()); - assert_eq!(outline.points, PHANTOM_POINT_COUNT); - } - - // Pull metric deltas from gvar when hvar is not present - // - #[test] - fn missing_hvar_advance() { - let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); - let mut outlines = Outlines::new(&font).unwrap(); - let coords = [F2Dot14::from_f32(0.5)]; - let ppem = Some(24.0); - let gid = font.charmap().map('A').unwrap(); - let outline = outlines.outline(gid).unwrap(); - let mut buf = [0u8; 1024]; - let scaler = - FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); - let scaled = scaler.scale(&outline.glyph, gid).unwrap(); - let advance_hvar = scaled.adjusted_advance_width(); - // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar - outlines.glyph_metrics.hvar = None; - outlines.var_metrics = AvailableVarMetrics::None; - let scaler = - FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); - let scaled = scaler.scale(&outline.glyph, gid).unwrap(); - let advance_gvar = scaled.adjusted_advance_width(); - // Make sure we have an advance and that the two are the same - assert!(advance_hvar != F26Dot6::ZERO); - assert_eq!(advance_hvar, advance_gvar); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,160 +0,0 @@ -//! TrueType outline types. - -use std::mem::size_of; - -use super::super::{ - path::{to_path, ToPathError}, - pen::PathStyle, - Hinting, OutlinePen, -}; -use raw::tables::glyf::PointCoord; -use read_fonts::{ - tables::glyf::{Glyph, PointFlags}, - types::{F26Dot6, Fixed, GlyphId, Point}, -}; - -/// Represents the information necessary to scale a glyph outline. -/// -/// Contains a reference to the glyph data itself as well as metrics that -/// can be used to compute the memory requirements for scaling the glyph. -#[derive(Clone, Default)] -pub struct Outline<'a> { - pub glyph_id: GlyphId, - /// The associated top-level glyph for the outline. - pub glyph: Option>, - /// Sum of the point counts of all simple glyphs in an outline. - pub points: usize, - /// Sum of the contour counts of all simple glyphs in an outline. - pub contours: usize, - /// Maximum number of points in a single simple glyph. - pub max_simple_points: usize, - /// "Other" points are the unscaled or original scaled points. - /// - /// The size of these buffer is the same and this value tracks the size - /// for one (not both) of the buffers. This is the maximum of - /// `max_simple_points` and the total number of points for all component - /// glyphs in a single composite glyph. - pub max_other_points: usize, - /// Maximum size of the component delta stack. - /// - /// For composite glyphs in variable fonts, delta values are computed - /// for each component. This tracks the maximum stack depth necessary - /// to store those values during processing. - pub max_component_delta_stack: usize, - /// Number of entries in the hinting value stack. - pub max_stack: usize, - /// Number of CVT entries for copy-on-write support. - pub cvt_count: usize, - /// Number of storage area entries for copy-on-write support. - pub storage_count: usize, - /// Maximum number of points in the twilight zone for hinting. - pub max_twilight_points: usize, - /// True if any component of a glyph has bytecode instructions. - pub has_hinting: bool, - /// True if the glyph requires variation delta processing. - pub has_variations: bool, - /// True if the glyph contains any simple or compound overlap flags. - pub has_overlaps: bool, -} - -impl Outline<'_> { - /// Returns the minimum size in bytes required to scale an outline based - /// on the computed sizes. - pub fn required_buffer_size(&self, hinting: Hinting) -> usize { - let mut size = 0; - let hinting = self.has_hinting && hinting == Hinting::Embedded; - // Scaled, unscaled and (for hinting) original scaled points - size += self.points * size_of::>(); - // Unscaled and (if hinted) original scaled points - size += self.max_other_points * size_of::>() * if hinting { 2 } else { 1 }; - // Contour end points - size += self.contours * size_of::(); - // Point flags - size += self.points * size_of::(); - if self.has_variations { - // Interpolation buffer for delta IUP - size += self.max_simple_points * size_of::>(); - // Delta buffer for points - size += self.max_simple_points * size_of::>(); - // Delta buffer for composite components - size += self.max_component_delta_stack * size_of::>(); - } - if hinting { - // Hinting value stack - size += self.max_stack * size_of::(); - // CVT and storage area copy-on-write buffers - size += (self.cvt_count + self.storage_count) * size_of::(); - // Twilight zone storage. Two point buffers plus one point flags buffer - size += self.max_twilight_points - * (size_of::>() * 2 + size_of::()); - } - if size != 0 { - // If we're given a buffer that is not aligned, we'll need to - // adjust, so add our maximum alignment requirement in bytes. - size += std::mem::align_of::(); - } - size - } -} - -#[derive(Debug)] -pub struct ScaledOutline<'a, C> -where - C: PointCoord, -{ - pub points: &'a mut [Point], - pub flags: &'a mut [PointFlags], - pub contours: &'a mut [u16], - pub phantom_points: [Point; 4], - pub hdmx_width: Option, -} - -impl<'a, C> ScaledOutline<'a, C> -where - C: PointCoord, -{ - pub(crate) fn new( - points: &'a mut [Point], - phantom_points: [Point; 4], - flags: &'a mut [PointFlags], - contours: &'a mut [u16], - hdmx_width: Option, - ) -> Self { - let x_shift = phantom_points[0].x; - if x_shift != C::zeroed() { - for point in points.iter_mut() { - point.x = point.x - x_shift; - } - } - Self { - points, - flags, - contours, - phantom_points, - hdmx_width, - } - } - - pub fn adjusted_lsb(&self) -> C { - self.phantom_points[0].x - } - - pub fn adjusted_advance_width(&self) -> C { - // Prefer widths from hdmx, otherwise take difference between first - // two phantom points - // - if let Some(hdmx_width) = self.hdmx_width { - C::from_i32(hdmx_width as i32) - } else { - self.phantom_points[1].x - self.phantom_points[0].x - } - } - - pub fn to_path( - &self, - path_style: PathStyle, - pen: &mut impl OutlinePen, - ) -> Result<(), ToPathError> { - to_path(self.points, self.flags, self.contours, path_style, pen) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,599 +0,0 @@ -//! Support for applying embedded hinting instructions. - -use super::{ - autohint, cff, - glyf::{self, FreeTypeScaler}, - pen::PathStyle, - AdjustedMetrics, DrawError, GlyphStyles, Hinting, LocationRef, NormalizedCoord, - OutlineCollectionKind, OutlineGlyph, OutlineGlyphCollection, OutlineKind, OutlinePen, Size, -}; -use crate::alloc::{boxed::Box, vec::Vec}; - -/// Configuration settings for a hinting instance. -#[derive(Clone, Default, Debug)] -pub struct HintingOptions { - /// Specifies the hinting engine to use. - /// - /// Defaults to [`Engine::AutoFallback`]. - pub engine: Engine, - /// Defines the properties of the intended target of a hinted outline. - /// - /// Defaults to a target with [`SmoothMode::Normal`] which is equivalent - /// to `FT_RENDER_MODE_NORMAL` in FreeType. - pub target: Target, -} - -impl From for HintingOptions { - fn from(value: Target) -> Self { - Self { - engine: Engine::AutoFallback, - target: value, - } - } -} - -/// Specifies the backend to use when applying hints. -#[derive(Clone, Default, Debug)] -pub enum Engine { - /// The TrueType or PostScript interpreter. - Interpreter, - /// The automatic hinter that performs just-in-time adjustment of - /// outlines. - /// - /// Glyph styles can be precomputed per font and may be provided here - /// as an optimization to avoid recomputing them for each instance. - Auto(Option), - /// Selects the engine based on the same rules that FreeType uses when - /// neither of the `FT_LOAD_NO_AUTOHINT` or `FT_LOAD_FORCE_AUTOHINT` - /// load flags are specified. - /// - /// Specifically, PostScript (CFF/CFF2) fonts will always use the hinting - /// engine in the PostScript interpreter and TrueType fonts will use the - /// interpreter for TrueType instructions if one of the `fpgm` or `prep` - /// tables is non-empty, falling back to the automatic hinter otherwise. - /// - /// This uses [`OutlineGlyphCollection::prefer_interpreter`] to make a - /// selection. - #[default] - AutoFallback, -} - -impl Engine { - /// Converts the `AutoFallback` variant into either `Interpreter` or - /// `Auto` based on the given outline set's preference for interpreter - /// mode. - fn resolve_auto_fallback(self, outlines: &OutlineGlyphCollection) -> Engine { - match self { - Self::Interpreter => Self::Interpreter, - Self::Auto(styles) => Self::Auto(styles), - Self::AutoFallback => { - if outlines.prefer_interpreter() { - Self::Interpreter - } else { - Self::Auto(None) - } - } - } - } -} - -impl From for HintingOptions { - fn from(value: Engine) -> Self { - Self { - engine: value, - target: Default::default(), - } - } -} - -/// Defines the target settings for hinting. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum Target { - /// Strong hinting style that should only be used for aliased, monochromatic - /// rasterization. - /// - /// Corresponds to `FT_LOAD_TARGET_MONO` in FreeType. - Mono, - /// Hinting style that is suitable for anti-aliased rasterization. - /// - /// Corresponds to the non-monochrome load targets in FreeType. See - /// [`SmoothMode`] for more detail. - Smooth { - /// The basic mode for smooth hinting. - /// - /// Defaults to [`SmoothMode::Normal`]. - mode: SmoothMode, - /// If true, TrueType bytecode may assume that the resulting outline - /// will be rasterized with supersampling in the vertical direction. - /// - /// When this is enabled, ClearType fonts will often generate wider - /// horizontal stems that may lead to blurry images when rendered with - /// an analytical area rasterizer (such as the one in FreeType). - /// - /// The effect of this setting is to control the "ClearType symmetric - /// rendering bit" of the TrueType `GETINFO` instruction. For more - /// detail, see this [issue](https://github.com/googlefonts/fontations/issues/1080). - /// - /// FreeType has no corresponding setting and behaves as if this is - /// always enabled. - /// - /// This only applies to the TrueType interpreter. - /// - /// Defaults to `true`. - symmetric_rendering: bool, - /// If true, prevents adjustment of the outline in the horizontal - /// direction and preserves inter-glyph spacing. - /// - /// This is useful for performing layout without concern that hinting - /// will modify the advance width of a glyph. Specifically, it means - /// that layout will not require evaluation of glyph outlines. - /// - /// FreeType has no corresponding setting and behaves as if this is - /// always disabled. - /// - /// This applies to the TrueType interpreter and the automatic hinter. - /// - /// Defaults to `false`. - preserve_linear_metrics: bool, - }, -} - -impl Default for Target { - fn default() -> Self { - SmoothMode::Normal.into() - } -} - -/// Mode selector for a smooth hinting target. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub enum SmoothMode { - /// The standard smooth hinting mode. - /// - /// Corresponds to `FT_LOAD_TARGET_NORMAL` in FreeType. - #[default] - Normal, - /// Hinting with a lighter touch, typically meaning less aggressive - /// adjustment in the horizontal direction. - /// - /// Corresponds to `FT_LOAD_TARGET_LIGHT` in FreeType. - Light, - /// Hinting that is optimized for subpixel rendering with horizontal LCD - /// layouts. - /// - /// Corresponds to `FT_LOAD_TARGET_LCD` in FreeType. - Lcd, - /// Hinting that is optimized for subpixel rendering with vertical LCD - /// layouts. - /// - /// Corresponds to `FT_LOAD_TARGET_LCD_V` in FreeType. - VerticalLcd, -} - -impl From for Target { - fn from(value: SmoothMode) -> Self { - Self::Smooth { - mode: value, - symmetric_rendering: true, - preserve_linear_metrics: false, - } - } -} - -/// Modes that control hinting when using embedded instructions. -/// -/// Only the TrueType interpreter supports all hinting modes. -/// -/// # FreeType compatibility -/// -/// The following table describes how to map FreeType hinting modes: -/// -/// | FreeType mode | Variant | -/// |-----------------------|--------------------------------------------------------------------------------------| -/// | FT_LOAD_TARGET_MONO | Strong | -/// | FT_LOAD_TARGET_NORMAL | Smooth { lcd_subpixel: None, preserve_linear_metrics: false } | -/// | FT_LOAD_TARGET_LCD | Smooth { lcd_subpixel: Some(LcdLayout::Horizontal), preserve_linear_metrics: false } | -/// | FT_LOAD_TARGET_LCD_V | Smooth { lcd_subpixel: Some(LcdLayout::Vertical), preserve_linear_metrics: false } | -/// -/// Note: `FT_LOAD_TARGET_LIGHT` is equivalent to `FT_LOAD_TARGET_NORMAL` since -/// FreeType 2.7. -/// -/// The default value of this type is equivalent to `FT_LOAD_TARGET_NORMAL`. -#[doc(hidden)] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum HintingMode { - /// Strong hinting mode that should only be used for aliased, monochromatic - /// rasterization. - /// - /// Corresponds to `FT_LOAD_TARGET_MONO` in FreeType. - Strong, - /// Lighter hinting mode that is intended for anti-aliased rasterization. - Smooth { - /// If set, enables support for optimized hinting that takes advantage - /// of subpixel layouts in LCD displays and corresponds to - /// `FT_LOAD_TARGET_LCD` or `FT_LOAD_TARGET_LCD_V` in FreeType. - /// - /// If unset, corresponds to `FT_LOAD_TARGET_NORMAL` in FreeType. - lcd_subpixel: Option, - /// If true, prevents adjustment of the outline in the horizontal - /// direction and preserves inter-glyph spacing. - /// - /// This is useful for performing layout without concern that hinting - /// will modify the advance width of a glyph. Specifically, it means - /// that layout will not require evaluation of glyph outlines. - /// - /// FreeType has no corresponding setting. - preserve_linear_metrics: bool, - }, -} - -impl Default for HintingMode { - fn default() -> Self { - Self::Smooth { - lcd_subpixel: None, - preserve_linear_metrics: false, - } - } -} - -impl From for HintingOptions { - fn from(value: HintingMode) -> Self { - let target = match value { - HintingMode::Strong => Target::Mono, - HintingMode::Smooth { - lcd_subpixel, - preserve_linear_metrics, - } => { - let mode = match lcd_subpixel { - Some(LcdLayout::Horizontal) => SmoothMode::Lcd, - Some(LcdLayout::Vertical) => SmoothMode::VerticalLcd, - None => SmoothMode::Normal, - }; - Target::Smooth { - mode, - preserve_linear_metrics, - symmetric_rendering: true, - } - } - }; - target.into() - } -} - -/// Specifies direction of pixel layout for LCD based subpixel hinting. -#[doc(hidden)] -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum LcdLayout { - /// Subpixels are ordered horizontally. - /// - /// Corresponds to `FT_LOAD_TARGET_LCD` in FreeType. - Horizontal, - /// Subpixels are ordered vertically. - /// - /// Corresponds to `FT_LOAD_TARGET_LCD_V` in FreeType. - Vertical, -} - -/// Hinting instance that uses information embedded in the font to perform -/// grid-fitting. -#[derive(Clone)] -pub struct HintingInstance { - size: Size, - coords: Vec, - target: Target, - kind: HinterKind, -} - -impl HintingInstance { - /// Creates a new embedded hinting instance for the given outline - /// collection, size, location in variation space and hinting mode. - pub fn new<'a>( - outline_glyphs: &OutlineGlyphCollection, - size: Size, - location: impl Into>, - options: impl Into, - ) -> Result { - let options = options.into(); - let mut hinter = Self { - size: Size::unscaled(), - coords: vec![], - target: options.target, - kind: HinterKind::None, - }; - hinter.reconfigure(outline_glyphs, size, location, options)?; - Ok(hinter) - } - - /// Returns the currently configured size. - pub fn size(&self) -> Size { - self.size - } - - /// Returns the currently configured normalized location in variation space. - pub fn location(&self) -> LocationRef { - LocationRef::new(&self.coords) - } - - /// Returns the currently configured hinting target. - pub fn target(&self) -> Target { - self.target - } - - /// Resets the hinter state for a new font instance with the given - /// outline collection and settings. - pub fn reconfigure<'a>( - &mut self, - outlines: &OutlineGlyphCollection, - size: Size, - location: impl Into>, - options: impl Into, - ) -> Result<(), DrawError> { - self.size = size; - self.coords.clear(); - self.coords.extend_from_slice(location.into().coords()); - let options = options.into(); - self.target = options.target; - let engine = options.engine.resolve_auto_fallback(outlines); - // Reuse memory if the font contains the same outline format - let current_kind = core::mem::replace(&mut self.kind, HinterKind::None); - match engine { - Engine::Interpreter => match &outlines.kind { - OutlineCollectionKind::Glyf(glyf) => { - let mut hint_instance = match current_kind { - HinterKind::Glyf(instance) => instance, - _ => Box::::default(), - }; - let ppem = size.ppem(); - let scale = glyf.compute_scale(ppem).1.to_bits(); - hint_instance.reconfigure( - glyf, - scale, - ppem.unwrap_or_default() as i32, - self.target, - &self.coords, - )?; - self.kind = HinterKind::Glyf(hint_instance); - } - OutlineCollectionKind::Cff(cff) => { - let mut subfonts = match current_kind { - HinterKind::Cff(subfonts) => subfonts, - _ => vec![], - }; - subfonts.clear(); - let ppem = size.ppem(); - for i in 0..cff.subfont_count() { - subfonts.push(cff.subfont(i, ppem, &self.coords)?); - } - self.kind = HinterKind::Cff(subfonts); - } - OutlineCollectionKind::None => {} - }, - Engine::Auto(styles) => { - let Some(font) = outlines.font() else { - return Ok(()); - }; - let instance = autohint::Instance::new( - font, - outlines, - &self.coords, - self.target, - styles, - true, - ); - self.kind = HinterKind::Auto(instance); - } - _ => {} - } - Ok(()) - } - - /// Returns true if hinting should actually be applied for this instance. - /// - /// Some TrueType fonts disable hinting dynamically based on the instance - /// configuration. - pub fn is_enabled(&self) -> bool { - match &self.kind { - HinterKind::Glyf(instance) => instance.is_enabled(), - HinterKind::Cff(_) | HinterKind::Auto(_) => true, - _ => false, - } - } - - pub(super) fn draw( - &self, - glyph: &OutlineGlyph, - memory: Option<&mut [u8]>, - path_style: PathStyle, - pen: &mut impl OutlinePen, - is_pedantic: bool, - ) -> Result { - let ppem = self.size.ppem(); - let coords = self.coords.as_slice(); - match (&self.kind, &glyph.kind) { - (HinterKind::Auto(instance), _) => { - instance.draw(self.size, coords, glyph, path_style, pen) - } - (HinterKind::Glyf(instance), OutlineKind::Glyf(glyf, outline)) => { - if matches!(path_style, PathStyle::HarfBuzz) { - return Err(DrawError::HarfBuzzHintingUnsupported); - } - super::with_glyf_memory(outline, Hinting::Embedded, memory, |buf| { - let scaled_outline = FreeTypeScaler::hinted( - glyf, - outline, - buf, - ppem, - coords, - instance, - is_pedantic, - )? - .scale(&outline.glyph, outline.glyph_id)?; - scaled_outline.to_path(path_style, pen)?; - Ok(AdjustedMetrics { - has_overlaps: outline.has_overlaps, - lsb: Some(scaled_outline.adjusted_lsb().to_f32()), - // When hinting is requested, we round the advance - // - advance_width: Some( - scaled_outline.adjusted_advance_width().round().to_f32(), - ), - }) - }) - } - (HinterKind::Cff(subfonts), OutlineKind::Cff(cff, glyph_id, subfont_ix)) => { - let Some(subfont) = subfonts.get(*subfont_ix as usize) else { - return Err(DrawError::NoSources); - }; - cff.draw(subfont, *glyph_id, &self.coords, true, pen)?; - Ok(AdjustedMetrics::default()) - } - _ => Err(DrawError::NoSources), - } - } -} - -#[derive(Clone)] -enum HinterKind { - /// Represents a hinting instance that is associated with an empty outline - /// collection. - None, - Glyf(Box), - Cff(Vec), - Auto(autohint::Instance), -} - -// Internal helpers for deriving various flags from the mode which -// change the behavior of certain instructions. -// See -impl Target { - pub(crate) fn is_smooth(&self) -> bool { - matches!(self, Self::Smooth { .. }) - } - - pub(crate) fn is_grayscale_cleartype(&self) -> bool { - match self { - Self::Smooth { mode, .. } => matches!(mode, SmoothMode::Normal | SmoothMode::Light), - _ => false, - } - } - - pub(crate) fn is_light(&self) -> bool { - matches!( - self, - Self::Smooth { - mode: SmoothMode::Light, - .. - } - ) - } - - pub(crate) fn is_lcd(&self) -> bool { - matches!( - self, - Self::Smooth { - mode: SmoothMode::Lcd, - .. - } - ) - } - - pub(crate) fn is_vertical_lcd(&self) -> bool { - matches!( - self, - Self::Smooth { - mode: SmoothMode::VerticalLcd, - .. - } - ) - } - - pub(crate) fn symmetric_rendering(&self) -> bool { - matches!( - self, - Self::Smooth { - symmetric_rendering: true, - .. - } - ) - } - - pub(crate) fn preserve_linear_metrics(&self) -> bool { - matches!( - self, - Self::Smooth { - preserve_linear_metrics: true, - .. - } - ) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{ - outline::{pen::NullPen, DrawSettings}, - raw::TableProvider, - FontRef, MetadataProvider, - }; - - // FreeType ignores the hdmx table when backward compatibility mode - // is enabled in the TrueType interpreter. - #[test] - fn ignore_hdmx_when_back_compat_enabled() { - let font = FontRef::new(font_test_data::TINOS_SUBSET).unwrap(); - let outlines = font.outline_glyphs(); - // Double quote was the most egregious failure - let gid = font.charmap().map('"').unwrap(); - let font_size = 16; - let hinter = HintingInstance::new( - &outlines, - Size::new(font_size as f32), - LocationRef::default(), - HintingOptions::default(), - ) - .unwrap(); - let HinterKind::Glyf(tt_hinter) = &hinter.kind else { - panic!("this is definitely a TrueType hinter"); - }; - // Make sure backward compatibility mode is enabled - assert!(tt_hinter.backward_compatibility()); - let outline = outlines.get(gid).unwrap(); - let metrics = outline.draw(&hinter, &mut NullPen).unwrap(); - // FreeType computes an advance width of 7 when hinting but hdmx contains 5 - let scaler_advance = metrics.advance_width.unwrap(); - assert_eq!(scaler_advance, 7.0); - let hdmx_advance = font - .hdmx() - .unwrap() - .record_for_size(font_size) - .unwrap() - .widths()[gid.to_u32() as usize]; - assert_eq!(hdmx_advance, 5); - } - - // When hinting is disabled by the prep table, FreeType still returns - // rounded advance widths - #[test] - fn round_advance_when_prep_disables_hinting() { - let font = FontRef::new(font_test_data::TINOS_SUBSET).unwrap(); - let outlines = font.outline_glyphs(); - let gid = font.charmap().map('"').unwrap(); - let size = Size::new(16.0); - let location = LocationRef::default(); - let mut hinter = - HintingInstance::new(&outlines, size, location, HintingOptions::default()).unwrap(); - let HinterKind::Glyf(tt_hinter) = &mut hinter.kind else { - panic!("this is definitely a TrueType hinter"); - }; - tt_hinter.simulate_prep_flag_suppress_hinting(); - let outline = outlines.get(gid).unwrap(); - // And we still have a rounded advance - let metrics = outline.draw(&hinter, &mut NullPen).unwrap(); - assert_eq!(metrics.advance_width, Some(7.0)); - // Unhinted advance has some fractional bits - let metrics = outline - .draw(DrawSettings::unhinted(size, location), &mut NullPen) - .unwrap(); - assert_eq!(metrics.advance_width, Some(6.53125)); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,374 +0,0 @@ -//! Name detection for fonts that require hinting to be run for correct -//! contours (FreeType calls these "tricky" fonts). - -use crate::{string::StringId, FontRef, MetadataProvider, Tag}; - -pub(super) fn require_interpreter(font: &FontRef) -> bool { - is_hint_reliant_by_name(font) || matches_hint_reliant_id_list(FontId::from_font(font)) -} - -fn is_hint_reliant_by_name(font: &FontRef) -> bool { - font.localized_strings(StringId::FAMILY_NAME) - .english_or_first() - .map(|name| { - let mut buf = [0u8; MAX_HINT_RELIANT_NAME_LEN]; - let mut len = 0; - let mut chars = name.chars(); - for ch in chars.by_ref().take(MAX_HINT_RELIANT_NAME_LEN) { - buf[len] = ch as u8; - len += 1; - } - if chars.next().is_some() { - return false; - } - matches_hint_reliant_name_list(core::str::from_utf8(&buf[..len]).unwrap_or_default()) - }) - .unwrap_or_default() -} - -/// Is this name on the list of fonts that require hinting? -/// -/// -fn matches_hint_reliant_name_list(name: &str) -> bool { - let name = skip_pdf_random_tag(name); - HINT_RELIANT_NAMES - .iter() - // FreeType uses strstr(name, tricky_name) so we use contains() to - // match behavior. - .any(|tricky_name| name.contains(*tricky_name)) -} - -/// Fonts embedded in PDFs add random prefixes. Strip these -/// for tricky font comparison purposes. -/// -/// -fn skip_pdf_random_tag(name: &str) -> &str { - let bytes = name.as_bytes(); - // Random tag is 6 uppercase letters followed by a + - if bytes.len() < 8 || bytes[6] != b'+' || !bytes.iter().take(6).all(|b| b.is_ascii_uppercase()) - { - return name; - } - core::str::from_utf8(&bytes[7..]).unwrap_or(name) -} - -/// -#[rustfmt::skip] -const HINT_RELIANT_NAMES: &[&str] = &[ - "cpop", /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */ - "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ - "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ - "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ - "DFHei", /* DynaLab Inc. 1992-1995 [DFHei-Bd-WIN-HK-BF] */ - /* covers "DFHei-Md-HK-BF", maybe DynaLab Inc. */ - - "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ - "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ - "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ - "DFKaiSho-SB", /* dfkaisb.ttf */ - "DFKaiShu", /* covers "DFKaiShu-Md-HK-BF", maybe DynaLab Inc. */ - "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ - - "DFMing", /* DynaLab Inc. 1992-1995 [DFMing-Md-WIN-HK-BF] */ - /* covers "DFMing-Bd-HK-BF", maybe DynaLab Inc. */ - - "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ - /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ - /* covers following */ - /* "DLCHayMedium", dftt-b5.ttf; version 1.00, 1993 */ - /* "DLCHayBold", dftt-b7.ttf; version 1.00, 1993 */ - /* "DLCKaiMedium", dftt-k5.ttf; version 1.00, 1992 */ - /* "DLCLiShu", dftt-l5.ttf; version 1.00, 1992 */ - /* "DLCRoundBold", dftt-r7.ttf; version 1.00, 1993 */ - - "HuaTianKaiTi?", /* htkt2.ttf */ - "HuaTianSongTi?", /* htst3.ttf */ - "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */ - /* iicore.ttf; version 0.07, 2007 [Ming] */ - "MingLiU", /* mingliu.ttf */ - /* mingliu.ttc; version 3.21, 2001 */ - "MingMedium", /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */ - "PMingLiU", /* mingliu.ttc; version 3.21, 2001 */ - "MingLi43", /* mingli.ttf; version 1.00, 1992 */ -]; - -const MAX_HINT_RELIANT_NAME_LEN: usize = 18; - -#[derive(Copy, Clone, PartialEq, Default, Debug)] -struct TableId { - checksum: u32, - len: u32, -} - -impl TableId { - fn from_font_and_tag(font: &FontRef, tag: Tag) -> Option { - let data = font.table_data(tag)?; - Some(Self { - // Note: FreeType always just computes the checksum - // - checksum: raw::tables::compute_checksum(data.as_bytes()), - len: data.len() as u32, - }) - } -} - -#[derive(Copy, Clone, PartialEq, Default, Debug)] -struct FontId { - cvt: TableId, - fpgm: TableId, - prep: TableId, -} - -impl FontId { - fn from_font(font: &FontRef) -> Self { - Self { - cvt: TableId::from_font_and_tag(font, Tag::new(b"cvt ")).unwrap_or_default(), - fpgm: TableId::from_font_and_tag(font, Tag::new(b"fpgm")).unwrap_or_default(), - prep: TableId::from_font_and_tag(font, Tag::new(b"prep")).unwrap_or_default(), - } - } -} - -/// Checks for fonts that require hinting based on the length and checksum of -/// the cvt, fpgm and prep tables. -/// -/// Roughly equivalent to -fn matches_hint_reliant_id_list(font_id: FontId) -> bool { - HINT_RELIANT_IDS.contains(&font_id) -} - -/// -#[rustfmt::skip] -const HINT_RELIANT_IDS: &[FontId] = &[ - // MingLiU 1995 - FontId { - cvt: TableId { checksum: 0x05BCF058, len: 0x000002E4 }, - fpgm: TableId { checksum: 0x28233BF1, len: 0x000087C4 }, - prep: TableId { checksum: 0xA344A1EA, len: 0x000001E1 }, - }, - // MingLiU 1996- - FontId { - cvt: TableId { checksum: 0x05BCF058, len: 0x000002E4 }, - fpgm: TableId { checksum: 0x28233BF1, len: 0x000087C4 }, - prep: TableId { checksum: 0xA344A1EB, len: 0x000001E1 }, - }, - // DFGothic-EB - FontId { - cvt: TableId { checksum: 0x12C3EBB2, len: 0x00000350 }, - fpgm: TableId { checksum: 0xB680EE64, len: 0x000087A7 }, - prep: TableId { checksum: 0xCE939563, len: 0x00000758 }, - }, - // DFGyoSho-Lt - FontId { - cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, - fpgm: TableId { checksum: 0xCE5956E9, len: 0x0000BC85 }, - prep: TableId { checksum: 0x8272F416, len: 0x00000045 }, - }, - // DFHei-Md-HK-BF - FontId { - cvt: TableId { checksum: 0x1257EB46, len: 0x00000350 }, - fpgm: TableId { checksum: 0xF699D160, len: 0x0000715F }, - prep: TableId { checksum: 0xD222F568, len: 0x000003BC }, - }, - // DFHSGothic-W5 - FontId { - cvt: TableId { checksum: 0x1262EB4E, len: 0x00000350 }, - fpgm: TableId { checksum: 0xE86A5D64, len: 0x00007940 }, - prep: TableId { checksum: 0x7850F729, len: 0x000005FF }, - }, - // DFHSMincho-W3 - FontId { - cvt: TableId { checksum: 0x122DEB0A, len: 0x00000350 }, - fpgm: TableId { checksum: 0x3D16328A, len: 0x0000859B }, - prep: TableId { checksum: 0xA93FC33B, len: 0x000002CB }, - }, - // DFHSMincho-W7 - FontId { - cvt: TableId { checksum: 0x125FEB26, len: 0x00000350 }, - fpgm: TableId { checksum: 0xA5ACC982, len: 0x00007EE1 }, - prep: TableId { checksum: 0x90999196, len: 0x0000041F }, - }, - // DFKaiShu - FontId { - cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, - fpgm: TableId { checksum: 0x5A30CA3B, len: 0x00009063 }, - prep: TableId { checksum: 0x13A42602, len: 0x0000007E }, - }, - // DFKaiShu, variant - FontId { - cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, - fpgm: TableId { checksum: 0xA6E78C01, len: 0x00008998 }, - prep: TableId { checksum: 0x13A42602, len: 0x0000007E }, - }, - // DFKaiShu-Md-HK-BF - FontId { - cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000360 }, - fpgm: TableId { checksum: 0x9DB282B2, len: 0x0000C06E }, - prep: TableId { checksum: 0x53E6D7CA, len: 0x00000082 }, - }, - // DFMing-Bd-HK-BF - FontId { - cvt: TableId { checksum: 0x1243EB18, len: 0x00000350 }, - fpgm: TableId { checksum: 0xBA0A8C30, len: 0x000074AD }, - prep: TableId { checksum: 0xF3D83409, len: 0x0000037B }, - }, - // DLCLiShu - FontId { - cvt: TableId { checksum: 0x07DCF546, len: 0x00000308 }, - fpgm: TableId { checksum: 0x40FE7C90, len: 0x00008E2A }, - prep: TableId { checksum: 0x608174B5, len: 0x0000007A }, - }, - // DLCHayBold - FontId { - cvt: TableId { checksum: 0xEB891238, len: 0x00000308 }, - fpgm: TableId { checksum: 0xD2E4DCD4, len: 0x0000676F }, - prep: TableId { checksum: 0x8EA5F293, len: 0x000003B8 }, - }, - // HuaTianKaiTi - FontId { - cvt: TableId { checksum: 0xFFFBFFFC, len: 0x00000008 }, - fpgm: TableId { checksum: 0x9C9E48B8, len: 0x0000BEA2 }, - prep: TableId { checksum: 0x70020112, len: 0x00000008 }, - }, - // HuaTianSongTi - FontId { - cvt: TableId { checksum: 0xFFFBFFFC, len: 0x00000008 }, - fpgm: TableId { checksum: 0x0A5A0483, len: 0x00017C39 }, - prep: TableId { checksum: 0x70020112, len: 0x00000008 }, - }, - // NEC fadpop7.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x40C92555, len: 0x000000E5 }, - prep: TableId { checksum: 0xA39B58E3, len: 0x0000117C }, - }, - // NEC fadrei5.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x33C41652, len: 0x000000E5 }, - prep: TableId { checksum: 0x26D6C52A, len: 0x00000F6A }, - }, - // NEC fangot7.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x6DB1651D, len: 0x0000019D }, - prep: TableId { checksum: 0x6C6E4B03, len: 0x00002492 }, - }, - // NEC fangyo5.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x40C92555, len: 0x000000E5 }, - prep: TableId { checksum: 0xDE51FAD0, len: 0x0000117C }, - }, - // NEC fankyo5.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x85E47664, len: 0x000000E5 }, - prep: TableId { checksum: 0xA6C62831, len: 0x00001CAA }, - }, - // NEC fanrgo5.ttf - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x2D891CFD, len: 0x0000019D }, - prep: TableId { checksum: 0xA0604633, len: 0x00001DE8 }, - }, - // NEC fangot5.ttc - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x40AA774C, len: 0x000001CB }, - prep: TableId { checksum: 0x9B5CAA96, len: 0x00001F9A }, - }, - // NEC fanmin3.ttc - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x0D3DE9CB, len: 0x00000141 }, - prep: TableId { checksum: 0xD4127766, len: 0x00002280 }, - }, - // NEC FA-Gothic, 1996 - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x4A692698, len: 0x000001F0 }, - prep: TableId { checksum: 0x340D4346, len: 0x00001FCA }, - }, - // NEC FA-Minchou, 1996 - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0xCD34C604, len: 0x00000166 }, - prep: TableId { checksum: 0x6CF31046, len: 0x000022B0 }, - }, - // NEC FA-RoundGothicB, 1996 - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0x5DA75315, len: 0x0000019D }, - prep: TableId { checksum: 0x40745A5F, len: 0x000022E0 }, - }, - // NEC FA-RoundGothicM, 1996 - FontId { - cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, - fpgm: TableId { checksum: 0xF055FC48, len: 0x000001C2 }, - prep: TableId { checksum: 0x3900DED3, len: 0x00001E18 }, - }, - // MINGLI.TTF, 1992 - FontId { - cvt: TableId { checksum: 0x00170003, len: 0x00000060 }, - fpgm: TableId { checksum: 0xDBB4306E, len: 0x000058AA }, - prep: TableId { checksum: 0xD643482A, len: 0x00000035 }, - }, - // DFHei-Bd-WIN-HK-BF, issue #1087 - FontId { - cvt: TableId { checksum: 0x1269EB58, len: 0x00000350 }, - fpgm: TableId { checksum: 0x5CD5957A, len: 0x00006A4E }, - prep: TableId { checksum: 0xF758323A, len: 0x00000380 }, - }, - // DFMing-Md-WIN-HK-BF, issue #1087 - FontId { - cvt: TableId { checksum: 0x122FEB0B, len: 0x00000350 }, - fpgm: TableId { checksum: 0x7F10919A, len: 0x000070A9 }, - prep: TableId { checksum: 0x7CD7E7B7, len: 0x0000025C }, - }, -]; - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn ensure_max_name_len() { - let max_len = HINT_RELIANT_NAMES - .iter() - .fold(0, |acc, name| acc.max(name.len())); - assert_eq!(max_len, MAX_HINT_RELIANT_NAME_LEN); - } - - #[test] - fn skip_pdf_tags() { - // length must be at least 8 - assert_eq!(skip_pdf_random_tag("ABCDEF+"), "ABCDEF+"); - // first six chars must be ascii uppercase - assert_eq!(skip_pdf_random_tag("AbCdEF+Arial"), "AbCdEF+Arial"); - // no numbers - assert_eq!(skip_pdf_random_tag("Ab12EF+Arial"), "Ab12EF+Arial"); - // missing + - assert_eq!(skip_pdf_random_tag("ABCDEFArial"), "ABCDEFArial"); - // too long - assert_eq!(skip_pdf_random_tag("ABCDEFG+Arial"), "ABCDEFG+Arial"); - // too short - assert_eq!(skip_pdf_random_tag("ABCDE+Arial"), "ABCDE+Arial"); - // just right - assert_eq!(skip_pdf_random_tag("ABCDEF+Arial"), "Arial"); - } - - #[test] - fn all_hint_reliant_names() { - for name in HINT_RELIANT_NAMES { - assert!(matches_hint_reliant_name_list(name)); - } - } - - #[test] - fn non_hint_reliant_names() { - for not_tricky in ["Roboto", "Arial", "Helvetica", "Blah", ""] { - assert!(!matches_hint_reliant_name_list(not_tricky)); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -//! Helper for loading (possibly variable) horizontal glyph metrics. - -use raw::{ - tables::{hmtx::Hmtx, hvar::Hvar}, - types::{F2Dot14, GlyphId}, - FontRef, TableProvider, -}; - -/// Access to horizontal glyph metrics. -#[derive(Clone)] -pub(crate) struct GlyphHMetrics<'a> { - pub hmtx: Hmtx<'a>, - pub hvar: Option>, -} - -impl<'a> GlyphHMetrics<'a> { - pub fn new(font: &FontRef<'a>) -> Option { - // Note: hmtx is required and HVAR is optional - let hmtx = font.hmtx().ok()?; - let hvar = font.hvar().ok(); - Some(Self { hmtx, hvar }) - } - - /// Returns the advance width (in font units) for the given glyph and - /// the location in variation space represented by the set of normalized - /// coordinates in 2.14 fixed point. - pub fn advance_width(&self, gid: GlyphId, coords: &'a [F2Dot14]) -> i32 { - let mut advance = self.hmtx.advance(gid).unwrap_or_default() as i32; - if let Some(hvar) = &self.hvar { - advance += hvar - .advance_width_delta(gid, coords) - .map(|delta| delta.to_i32()) - .unwrap_or(0); - } - advance - } - - /// Returns the left side bearing (in font units) for the given glyph and - /// the location in variation space represented by the set of normalized - /// coordinates in 2.14 fixed point. - pub fn lsb(&self, gid: GlyphId, coords: &'a [F2Dot14]) -> i32 { - let mut lsb = self.hmtx.side_bearing(gid).unwrap_or_default() as i32; - if let Some(hvar) = &self.hvar { - lsb += hvar - .lsb_delta(gid, coords) - .map(|delta| delta.to_i32()) - .unwrap_or(0); - } - lsb - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,1462 +0,0 @@ -//! Loading, scaling and hinting of glyph outlines. -//! -//! This module provides support for retrieving (optionally scaled and hinted) -//! glyph outlines in the form of vector paths. -//! -//! # Drawing a glyph -//! -//! Generating SVG [path commands](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands) -//! for a character (this assumes a local variable `font` of type [`FontRef`]): -//! -//! ```rust -//! use skrifa::{ -//! instance::{LocationRef, Size}, -//! outline::{DrawSettings, OutlinePen}, -//! FontRef, MetadataProvider, -//! }; -//! -//! # fn wrapper(font: FontRef) { -//! // First, grab the set of outline glyphs from the font. -//! let outlines = font.outline_glyphs(); -//! -//! // Find the glyph identifier for our character. -//! let glyph_id = font.charmap().map('Q').unwrap(); -//! -//! // Grab the outline glyph. -//! let glyph = outlines.get(glyph_id).unwrap(); -//! -//! // Define how we want the glyph to be drawn. This creates -//! // settings for an instance without hinting at a size of -//! // 16px with no variations applied. -//! let settings = DrawSettings::unhinted(Size::new(16.0), LocationRef::default()); -//! -//! // Alternatively, we can apply variations like so: -//! let var_location = font.axes().location(&[("wght", 650.0), ("wdth", 100.0)]); -//! let settings = DrawSettings::unhinted(Size::new(16.0), &var_location); -//! -//! // At this point, we need a "sink" to receive the resulting path. This -//! // is done by creating an implementation of the OutlinePen trait. -//! -//! // Let's make one that generates SVG path data. -//! #[derive(Default)] -//! struct SvgPath(String); -//! -//! // Implement the OutlinePen trait for this type. This emits the appropriate -//! // SVG path commands for each element type. -//! impl OutlinePen for SvgPath { -//! fn move_to(&mut self, x: f32, y: f32) { -//! self.0.push_str(&format!("M{x:.1},{y:.1} ")); -//! } -//! -//! fn line_to(&mut self, x: f32, y: f32) { -//! self.0.push_str(&format!("L{x:.1},{y:.1} ")); -//! } -//! -//! fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { -//! self.0 -//! .push_str(&format!("Q{cx0:.1},{cy0:.1} {x:.1},{y:.1} ")); -//! } -//! -//! fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { -//! self.0.push_str(&format!( -//! "C{cx0:.1},{cy0:.1} {cx1:.1},{cy1:.1} {x:.1},{y:.1} " -//! )); -//! } -//! -//! fn close(&mut self) { -//! self.0.push_str("Z "); -//! } -//! } -//! // Now, construct an instance of our pen. -//! let mut svg_path = SvgPath::default(); -//! -//! // And draw the glyph! -//! glyph.draw(settings, &mut svg_path).unwrap(); -//! -//! // See what we've drawn. -//! println!("{}", svg_path.0); -//! # } -//! ``` - -mod autohint; -mod cff; -mod glyf; -mod hint; -mod hint_reliant; -mod metrics; -mod path; -mod unscaled; - -#[cfg(test)] -mod testing; - -pub mod error; -pub mod pen; - -pub use autohint::GlyphStyles; -pub use hint::{ - Engine, HintingInstance, HintingMode, HintingOptions, LcdLayout, SmoothMode, Target, -}; -use metrics::GlyphHMetrics; -use raw::FontRef; -#[doc(inline)] -pub use {error::DrawError, pen::OutlinePen}; - -use self::glyf::{FreeTypeScaler, HarfBuzzScaler}; -use super::{ - instance::{LocationRef, NormalizedCoord, Size}, - GLYF_COMPOSITE_RECURSION_LIMIT, -}; -use core::fmt::Debug; -use pen::PathStyle; -use read_fonts::{types::GlyphId, TableProvider}; - -#[cfg(feature = "libm")] -#[allow(unused_imports)] -use core_maths::CoreFloat; - -/// Source format for an outline glyph. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum OutlineGlyphFormat { - /// TrueType outlines sourced from the `glyf` table. - Glyf, - /// PostScript outlines sourced from the `CFF` table. - Cff, - /// PostScript outlines sourced from the `CFF2` table. - Cff2, -} - -/// Specifies the hinting strategy for memory size calculations. -#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] -pub enum Hinting { - /// Hinting is disabled. - #[default] - None, - /// Application of hints that are embedded in the font. - /// - /// For TrueType, these are bytecode instructions associated with each - /// glyph outline. For PostScript (CFF/CFF2), these are stem hints - /// encoded in the character string. - Embedded, -} - -/// Information and adjusted metrics generated while drawing an outline glyph. -/// -/// When applying hints to a TrueType glyph, the outline may be shifted in -/// the horizontal direction, affecting the left side bearing and advance width -/// of the glyph. This captures those metrics. -#[derive(Copy, Clone, Default, Debug)] -pub struct AdjustedMetrics { - /// True if the underlying glyph contains flags indicating the - /// presence of overlapping contours or components. - pub has_overlaps: bool, - /// If present, an adjusted left side bearing value generated by the - /// scaler. - /// - /// This is equivalent to the `horiBearingX` value in - /// [`FT_Glyph_Metrics`](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_glyph_metrics). - pub lsb: Option, - /// If present, an adjusted advance width value generated by the - /// scaler. - /// - /// This is equivalent to the `advance.x` value in - /// [`FT_GlyphSlotRec`](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_glyphslotrec). - pub advance_width: Option, -} - -/// Options that define how a [glyph](OutlineGlyph) is drawn to a -/// [pen](OutlinePen). -pub struct DrawSettings<'a> { - instance: DrawInstance<'a>, - memory: Option<&'a mut [u8]>, - path_style: PathStyle, -} - -impl<'a> DrawSettings<'a> { - /// Creates settings for an unhinted draw operation with the given size and - /// location in variation space. - pub fn unhinted(size: Size, location: impl Into>) -> Self { - Self { - instance: DrawInstance::Unhinted(size, location.into()), - memory: None, - path_style: PathStyle::default(), - } - } - - /// Creates settings for a hinted draw operation using hinting data - /// contained in the font. - /// - /// If `is_pedantic` is true then any error that occurs during hinting will - /// cause drawing to fail. This is equivalent to the `FT_LOAD_PEDANTIC` flag - /// in FreeType. - /// - /// The font size, location in variation space and hinting mode are - /// defined by the current configuration of the given hinting instance. - pub fn hinted(instance: &'a HintingInstance, is_pedantic: bool) -> Self { - Self { - instance: DrawInstance::Hinted { - instance, - is_pedantic, - }, - memory: None, - path_style: PathStyle::default(), - } - } - - /// Builder method to associate a user memory buffer to be used for - /// temporary allocations during drawing. - /// - /// The required size of this buffer can be computed using the - /// [`OutlineGlyph::draw_memory_size`] method. - /// - /// If not provided, any necessary memory will be allocated internally. - pub fn with_memory(mut self, memory: Option<&'a mut [u8]>) -> Self { - self.memory = memory; - self - } - - /// Builder method to control nuances of [`glyf`](https://learn.microsoft.com/en-us/typography/opentype/spec/glyf) pointstream interpretation. - /// - /// Meant for use when trying to match legacy code behavior in Rust. - pub fn with_path_style(mut self, path_style: PathStyle) -> Self { - self.path_style = path_style; - self - } -} - -enum DrawInstance<'a> { - Unhinted(Size, LocationRef<'a>), - Hinted { - instance: &'a HintingInstance, - is_pedantic: bool, - }, -} - -impl<'a, L> From<(Size, L)> for DrawSettings<'a> -where - L: Into>, -{ - fn from(value: (Size, L)) -> Self { - DrawSettings::unhinted(value.0, value.1.into()) - } -} - -impl From for DrawSettings<'_> { - fn from(value: Size) -> Self { - DrawSettings::unhinted(value, LocationRef::default()) - } -} - -impl<'a> From<&'a HintingInstance> for DrawSettings<'a> { - fn from(value: &'a HintingInstance) -> Self { - DrawSettings::hinted(value, false) - } -} - -/// A scalable glyph outline. -/// -/// This can be sourced from the [`glyf`](https://learn.microsoft.com/en-us/typography/opentype/spec/glyf), -/// [`CFF`](https://learn.microsoft.com/en-us/typography/opentype/spec/cff) or -/// [`CFF2`](https://learn.microsoft.com/en-us/typography/opentype/spec/cff2) -/// tables. Use the [`format`](OutlineGlyph::format) method to determine which -/// was chosen for this glyph. -#[derive(Clone)] -pub struct OutlineGlyph<'a> { - kind: OutlineKind<'a>, -} - -impl<'a> OutlineGlyph<'a> { - /// Returns the underlying source format for this outline. - pub fn format(&self) -> OutlineGlyphFormat { - match &self.kind { - OutlineKind::Glyf(..) => OutlineGlyphFormat::Glyf, - OutlineKind::Cff(cff, ..) => { - if cff.is_cff2() { - OutlineGlyphFormat::Cff2 - } else { - OutlineGlyphFormat::Cff - } - } - } - } - - /// Returns the glyph identifier for this outline. - pub fn glyph_id(&self) -> GlyphId { - match &self.kind { - OutlineKind::Glyf(_, glyph) => glyph.glyph_id, - OutlineKind::Cff(_, gid, _) => *gid, - } - } - - /// Returns a value indicating if the outline may contain overlapping - /// contours or components. - /// - /// For CFF outlines, returns `None` since this information is unavailable. - pub fn has_overlaps(&self) -> Option { - match &self.kind { - OutlineKind::Glyf(_, outline) => Some(outline.has_overlaps), - _ => None, - } - } - - /// Returns a value indicating whether the outline has hinting - /// instructions. - /// - /// For CFF outlines, returns `None` since this is unknown prior - /// to loading the outline. - pub fn has_hinting(&self) -> Option { - match &self.kind { - OutlineKind::Glyf(_, outline) => Some(outline.has_hinting), - _ => None, - } - } - - /// Returns the size (in bytes) of the temporary memory required to draw - /// this outline. - /// - /// This is used to compute the size of the memory buffer required for the - /// [`DrawSettings::with_memory`] method. - /// - /// The `hinting` parameter determines which hinting method, if any, will - /// be used for drawing which has an effect on memory requirements. - /// - /// The appropriate hinting types are as follows: - /// - /// | For draw settings | Use hinting | - /// |------------------------------------|-----------------------| - /// | [`DrawSettings::unhinted`] | [`Hinting::None`] | - /// | [`DrawSettings::hinted`] | [`Hinting::Embedded`] | - pub fn draw_memory_size(&self, hinting: Hinting) -> usize { - match &self.kind { - OutlineKind::Glyf(_, outline) => outline.required_buffer_size(hinting), - _ => 0, - } - } - - /// Draws the outline glyph with the given settings and emits the resulting - /// path commands to the specified pen. - pub fn draw<'s>( - &self, - settings: impl Into>, - pen: &mut impl OutlinePen, - ) -> Result { - let settings: DrawSettings<'a> = settings.into(); - match (settings.instance, settings.path_style) { - (DrawInstance::Unhinted(size, location), PathStyle::FreeType) => { - self.draw_unhinted(size, location, settings.memory, settings.path_style, pen) - } - (DrawInstance::Unhinted(size, location), PathStyle::HarfBuzz) => { - self.draw_unhinted(size, location, settings.memory, settings.path_style, pen) - } - ( - DrawInstance::Hinted { - instance: hinting_instance, - is_pedantic, - }, - PathStyle::FreeType, - ) => { - if hinting_instance.is_enabled() { - hinting_instance.draw( - self, - settings.memory, - settings.path_style, - pen, - is_pedantic, - ) - } else { - let mut metrics = self.draw_unhinted( - hinting_instance.size(), - hinting_instance.location(), - settings.memory, - settings.path_style, - pen, - )?; - // Round advance width when hinting is requested, even if - // the instance is disabled. - if let Some(advance) = metrics.advance_width.as_mut() { - *advance = advance.round(); - } - Ok(metrics) - } - } - (DrawInstance::Hinted { .. }, PathStyle::HarfBuzz) => { - Err(DrawError::HarfBuzzHintingUnsupported) - } - } - } - - fn draw_unhinted( - &self, - size: Size, - location: impl Into>, - user_memory: Option<&mut [u8]>, - path_style: PathStyle, - pen: &mut impl OutlinePen, - ) -> Result { - let ppem = size.ppem(); - let coords = location.into().coords(); - match &self.kind { - OutlineKind::Glyf(glyf, outline) => { - with_glyf_memory(outline, Hinting::None, user_memory, |buf| { - let (lsb, advance_width) = match path_style { - PathStyle::FreeType => { - let scaled_outline = - FreeTypeScaler::unhinted(glyf, outline, buf, ppem, coords)? - .scale(&outline.glyph, outline.glyph_id)?; - scaled_outline.to_path(path_style, pen)?; - ( - scaled_outline.adjusted_lsb().to_f32(), - scaled_outline.adjusted_advance_width().to_f32(), - ) - } - PathStyle::HarfBuzz => { - let scaled_outline = - HarfBuzzScaler::unhinted(glyf, outline, buf, ppem, coords)? - .scale(&outline.glyph, outline.glyph_id)?; - scaled_outline.to_path(path_style, pen)?; - ( - scaled_outline.adjusted_lsb(), - scaled_outline.adjusted_advance_width(), - ) - } - }; - - Ok(AdjustedMetrics { - has_overlaps: outline.has_overlaps, - lsb: Some(lsb), - advance_width: Some(advance_width), - }) - }) - } - OutlineKind::Cff(cff, glyph_id, subfont_ix) => { - let subfont = cff.subfont(*subfont_ix, ppem, coords)?; - cff.draw(&subfont, *glyph_id, coords, false, pen)?; - Ok(AdjustedMetrics::default()) - } - } - } - - /// Internal drawing API for autohinting that offers unified compact - /// storage for unscaled outlines. - #[allow(dead_code)] - fn draw_unscaled( - &self, - location: impl Into>, - user_memory: Option<&mut [u8]>, - sink: &mut impl unscaled::UnscaledOutlineSink, - ) -> Result { - let coords = location.into().coords(); - let ppem = None; - match &self.kind { - OutlineKind::Glyf(glyf, outline) => { - with_glyf_memory(outline, Hinting::None, user_memory, |buf| { - let outline = FreeTypeScaler::unhinted(glyf, outline, buf, ppem, coords)? - .scale(&outline.glyph, outline.glyph_id)?; - sink.try_reserve(outline.points.len())?; - let mut contour_start = 0; - for contour_end in outline.contours.iter().map(|contour| *contour as usize) { - if contour_end >= contour_start { - if let Some(points) = outline.points.get(contour_start..=contour_end) { - let flags = &outline.flags[contour_start..=contour_end]; - sink.extend(points.iter().zip(flags).enumerate().map( - |(ix, (point, flags))| { - unscaled::UnscaledPoint::from_glyf_point( - *point, - *flags, - ix == 0, - ) - }, - ))?; - } - } - contour_start = contour_end + 1; - } - Ok(outline.adjusted_advance_width().to_bits() >> 6) - }) - } - OutlineKind::Cff(cff, glyph_id, subfont_ix) => { - let subfont = cff.subfont(*subfont_ix, ppem, coords)?; - let mut adapter = unscaled::UnscaledPenAdapter::new(sink); - cff.draw(&subfont, *glyph_id, coords, false, &mut adapter)?; - adapter.finish()?; - let advance = cff.glyph_metrics.advance_width(*glyph_id, coords); - Ok(advance) - } - } - } - - pub(crate) fn font(&self) -> &FontRef<'a> { - match &self.kind { - OutlineKind::Glyf(glyf, ..) => &glyf.font, - OutlineKind::Cff(cff, ..) => &cff.font, - } - } - - fn units_per_em(&self) -> u16 { - match &self.kind { - OutlineKind::Cff(cff, ..) => cff.units_per_em(), - OutlineKind::Glyf(glyf, ..) => glyf.units_per_em(), - } - } -} - -#[derive(Clone)] -enum OutlineKind<'a> { - Glyf(glyf::Outlines<'a>, glyf::Outline<'a>), - // Third field is subfont index - Cff(cff::Outlines<'a>, GlyphId, u32), -} - -impl Debug for OutlineKind<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::Glyf(_, outline) => f.debug_tuple("Glyf").field(&outline.glyph_id).finish(), - Self::Cff(_, gid, subfont_index) => f - .debug_tuple("Cff") - .field(gid) - .field(subfont_index) - .finish(), - } - } -} - -/// Collection of scalable glyph outlines. -#[derive(Debug, Clone)] -pub struct OutlineGlyphCollection<'a> { - kind: OutlineCollectionKind<'a>, -} - -impl<'a> OutlineGlyphCollection<'a> { - /// Creates a new outline collection for the given font. - pub fn new(font: &FontRef<'a>) -> Self { - let kind = if let Some(glyf) = glyf::Outlines::new(font) { - OutlineCollectionKind::Glyf(glyf) - } else if let Some(cff) = cff::Outlines::new(font) { - OutlineCollectionKind::Cff(cff) - } else { - OutlineCollectionKind::None - }; - Self { kind } - } - - /// Creates a new outline collection for the given font and outline - /// format. - /// - /// Returns `None` if the font does not contain outlines in the requested - /// format. - pub fn with_format(font: &FontRef<'a>, format: OutlineGlyphFormat) -> Option { - let kind = match format { - OutlineGlyphFormat::Glyf => OutlineCollectionKind::Glyf(glyf::Outlines::new(font)?), - OutlineGlyphFormat::Cff => { - let upem = font.head().ok()?.units_per_em(); - OutlineCollectionKind::Cff(cff::Outlines::from_cff(font, upem)?) - } - OutlineGlyphFormat::Cff2 => { - let upem = font.head().ok()?.units_per_em(); - OutlineCollectionKind::Cff(cff::Outlines::from_cff2(font, upem)?) - } - }; - Some(Self { kind }) - } - - /// Returns the underlying format of the source outline tables. - pub fn format(&self) -> Option { - match &self.kind { - OutlineCollectionKind::Glyf(..) => Some(OutlineGlyphFormat::Glyf), - OutlineCollectionKind::Cff(cff) => cff - .is_cff2() - .then_some(OutlineGlyphFormat::Cff2) - .or(Some(OutlineGlyphFormat::Cff)), - _ => None, - } - } - - /// Returns the outline for the given glyph identifier. - pub fn get(&self, glyph_id: GlyphId) -> Option> { - match &self.kind { - OutlineCollectionKind::None => None, - OutlineCollectionKind::Glyf(glyf) => Some(OutlineGlyph { - kind: OutlineKind::Glyf(glyf.clone(), glyf.outline(glyph_id).ok()?), - }), - OutlineCollectionKind::Cff(cff) => Some(OutlineGlyph { - kind: OutlineKind::Cff(cff.clone(), glyph_id, cff.subfont_index(glyph_id)), - }), - } - } - - /// Returns an iterator over all of the outline glyphs in the collection. - pub fn iter(&self) -> impl Iterator)> + 'a + Clone { - let len = match &self.kind { - OutlineCollectionKind::Glyf(glyf) => glyf.glyph_count(), - OutlineCollectionKind::Cff(cff) => cff.glyph_count(), - _ => 0, - } as u16; - let copy = self.clone(); - (0..len).filter_map(move |gid| { - let gid = GlyphId::from(gid); - let glyph = copy.get(gid)?; - Some((gid, glyph)) - }) - } - - /// Returns true if the interpreter engine should be used for hinting this - /// set of outlines. - /// - /// When this returns false, you likely want to use the automatic hinter - /// instead. - /// - /// This matches the logic used in FreeType when neither of the - /// `FT_LOAD_FORCE_AUTOHINT` or `FT_LOAD_NO_AUTOHINT` load flags are - /// specified. - /// - /// When setting [`HintingOptions::engine`] to [`Engine::AutoFallback`], - /// this is used to determine whether to use the interpreter or automatic - /// hinter. - pub fn prefer_interpreter(&self) -> bool { - match &self.kind { - OutlineCollectionKind::Glyf(glyf) => glyf.prefer_interpreter(), - _ => true, - } - } - - /// Returns true when the interpreter engine _must_ be used for hinting - /// this set of outlines to produce correct results. - /// - /// This corresponds so FreeType's `FT_FACE_FLAG_TRICKY` face flag. See - /// the documentation for that [flag](https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_face_flag_xxx) - /// for more detail. - /// - /// When this returns `true`, you should construct a [`HintingInstance`] - /// with [`HintingOptions::engine`] set to [`Engine::Interpreter`] and - /// [`HintingOptions::target`] set to [`Target::Mono`]. - /// - /// # Performance - /// This digs through the name table and potentially computes checksums - /// so it may be slow. You should cache the result of this function if - /// possible. - pub fn require_interpreter(&self) -> bool { - self.font() - .map(|font| hint_reliant::require_interpreter(font)) - .unwrap_or_default() - } - - pub(crate) fn font(&self) -> Option<&FontRef<'a>> { - match &self.kind { - OutlineCollectionKind::Glyf(glyf) => Some(&glyf.font), - OutlineCollectionKind::Cff(cff) => Some(&cff.font), - _ => None, - } - } -} - -#[derive(Clone)] -enum OutlineCollectionKind<'a> { - None, - Glyf(glyf::Outlines<'a>), - Cff(cff::Outlines<'a>), -} - -impl Debug for OutlineCollectionKind<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Self::None => write!(f, "None"), - Self::Glyf(..) => f.debug_tuple("Glyf").finish(), - Self::Cff(..) => f.debug_tuple("Cff").finish(), - } - } -} - -/// Invokes the callback with a memory buffer suitable for drawing -/// the given TrueType outline. -pub(super) fn with_glyf_memory( - outline: &glyf::Outline, - hinting: Hinting, - memory: Option<&mut [u8]>, - mut f: impl FnMut(&mut [u8]) -> R, -) -> R { - // Wrap in a function and prevent inlining to avoid stack allocation - // and zeroing if we don't take this code path. - #[inline(never)] - fn stack_mem(mut f: impl FnMut(&mut [u8]) -> R) -> R { - f(&mut [0u8; STACK_SIZE]) - } - match memory { - Some(buf) => f(buf), - None => { - let buf_size = outline.required_buffer_size(hinting); - // Use bucketed stack allocations to prevent excessive zeroing of - // memory - if buf_size <= 512 { - stack_mem::<512, _>(f) - } else if buf_size <= 1024 { - stack_mem::<1024, _>(f) - } else if buf_size <= 2048 { - stack_mem::<2048, _>(f) - } else if buf_size <= 4096 { - stack_mem::<4096, _>(f) - } else { - f(&mut vec![0u8; buf_size]) - } - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{instance::Location, MetadataProvider}; - use kurbo::{Affine, BezPath, PathEl, Point}; - use read_fonts::{types::GlyphId, FontRef, TableProvider}; - - use pretty_assertions::assert_eq; - - const PERIOD: u32 = 0x2E_u32; - const COMMA: u32 = 0x2C_u32; - - #[test] - fn outline_glyph_formats() { - let font_format_pairs = [ - (font_test_data::VAZIRMATN_VAR, OutlineGlyphFormat::Glyf), - ( - font_test_data::CANTARELL_VF_TRIMMED, - OutlineGlyphFormat::Cff2, - ), - ( - font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, - OutlineGlyphFormat::Cff, - ), - (font_test_data::COLRV0V1_VARIABLE, OutlineGlyphFormat::Glyf), - ]; - for (font_data, format) in font_format_pairs { - assert_eq!( - FontRef::new(font_data).unwrap().outline_glyphs().format(), - Some(format) - ); - } - } - - #[test] - fn vazirmatin_var() { - compare_glyphs( - font_test_data::VAZIRMATN_VAR, - font_test_data::VAZIRMATN_VAR_GLYPHS, - ); - } - - #[test] - fn cantarell_vf() { - compare_glyphs( - font_test_data::CANTARELL_VF_TRIMMED, - font_test_data::CANTARELL_VF_TRIMMED_GLYPHS, - ); - } - - #[test] - fn noto_serif_display() { - compare_glyphs( - font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, - font_test_data::NOTO_SERIF_DISPLAY_TRIMMED_GLYPHS, - ); - } - - #[test] - fn overlap_flags() { - let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); - let outlines = font.outline_glyphs(); - let glyph_count = font.maxp().unwrap().num_glyphs(); - // GID 2 is a composite glyph with the overlap bit on a component - // GID 3 is a simple glyph with the overlap bit on the first flag - let expected_gids_with_overlap = vec![2, 3]; - assert_eq!( - expected_gids_with_overlap, - (0..glyph_count) - .filter( - |gid| outlines.get(GlyphId::from(*gid)).unwrap().has_overlaps() == Some(true) - ) - .collect::>() - ); - } - - fn compare_glyphs(font_data: &[u8], expected_outlines: &str) { - let font = FontRef::new(font_data).unwrap(); - let expected_outlines = testing::parse_glyph_outlines(expected_outlines); - let mut path = testing::Path::default(); - for expected_outline in &expected_outlines { - if expected_outline.size == 0.0 && !expected_outline.coords.is_empty() { - continue; - } - let size = if expected_outline.size != 0.0 { - Size::new(expected_outline.size) - } else { - Size::unscaled() - }; - path.elements.clear(); - font.outline_glyphs() - .get(expected_outline.glyph_id) - .unwrap() - .draw( - DrawSettings::unhinted(size, expected_outline.coords.as_slice()), - &mut path, - ) - .unwrap(); - assert_eq!(path.elements, expected_outline.path, "mismatch in glyph path for id {} (size: {}, coords: {:?}): path: {:?} expected_path: {:?}", - expected_outline.glyph_id, - expected_outline.size, - expected_outline.coords, - &path.elements, - &expected_outline.path - ); - } - } - - #[derive(Copy, Clone, Debug, PartialEq)] - enum GlyphPoint { - On { x: f32, y: f32 }, - Off { x: f32, y: f32 }, - } - - impl GlyphPoint { - fn implied_oncurve(&self, other: Self) -> Self { - let (x1, y1) = self.xy(); - let (x2, y2) = other.xy(); - Self::On { - x: (x1 + x2) / 2.0, - y: (y1 + y2) / 2.0, - } - } - - fn xy(&self) -> (f32, f32) { - match self { - GlyphPoint::On { x, y } | GlyphPoint::Off { x, y } => (*x, *y), - } - } - } - - #[derive(Debug)] - struct PointPen { - points: Vec, - } - - impl PointPen { - fn new() -> Self { - Self { points: Vec::new() } - } - - fn into_points(self) -> Vec { - self.points - } - } - - impl OutlinePen for PointPen { - fn move_to(&mut self, x: f32, y: f32) { - self.points.push(GlyphPoint::On { x, y }); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.points.push(GlyphPoint::On { x, y }); - } - - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { - self.points.push(GlyphPoint::Off { x: cx0, y: cy0 }); - self.points.push(GlyphPoint::On { x, y }); - } - - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { - self.points.push(GlyphPoint::Off { x: cx0, y: cy0 }); - self.points.push(GlyphPoint::Off { x: cx1, y: cy1 }); - self.points.push(GlyphPoint::On { x, y }); - } - - fn close(&mut self) { - // We can't drop a 0-length closing line for fear of breaking interpolation compatibility - // - some other instance might have it not 0-length - // However, if the last command isn't a line and ends at the subpath start we can drop the endpoint - // - if any instance had it other than at the start there would be a closing line - // - and it wouldn't be interpolation compatible - // See - let np = self.points.len(); - // We need at least 3 points to satisfy subsequent conditions - if np > 2 - && self.points[0] == self.points[np - 1] - && matches!( - (self.points[0], self.points[np - 2]), - (GlyphPoint::On { .. }, GlyphPoint::Off { .. }) - ) - { - self.points.pop(); - } - } - } - - const STARTING_OFF_CURVE_POINTS: [GlyphPoint; 4] = [ - GlyphPoint::Off { x: 278.0, y: 710.0 }, - GlyphPoint::On { x: 278.0, y: 470.0 }, - GlyphPoint::On { x: 998.0, y: 470.0 }, - GlyphPoint::On { x: 998.0, y: 710.0 }, - ]; - - const MOSTLY_OFF_CURVE_POINTS: [GlyphPoint; 5] = [ - GlyphPoint::Off { x: 278.0, y: 710.0 }, - GlyphPoint::Off { x: 278.0, y: 470.0 }, - GlyphPoint::On { x: 998.0, y: 470.0 }, - GlyphPoint::Off { x: 998.0, y: 710.0 }, - GlyphPoint::Off { x: 750.0, y: 500.0 }, - ]; - - /// Captures the svg drawing command sequence, e.g. MLLZ. - /// - /// Intended use is to confirm the command sequence pushed to the pen is interpolation compatible. - #[derive(Default, Debug)] - struct CommandPen { - commands: String, - } - - impl OutlinePen for CommandPen { - fn move_to(&mut self, _x: f32, _y: f32) { - self.commands.push('M'); - } - - fn line_to(&mut self, _x: f32, _y: f32) { - self.commands.push('L'); - } - - fn quad_to(&mut self, _cx0: f32, _cy0: f32, _x: f32, _y: f32) { - self.commands.push('Q'); - } - - fn curve_to(&mut self, _cx0: f32, _cy0: f32, _cx1: f32, _cy1: f32, _x: f32, _y: f32) { - self.commands.push('C'); - } - - fn close(&mut self) { - self.commands.push('Z'); - } - } - - fn draw_to_pen(font: &[u8], codepoint: u32, settings: DrawSettings, pen: &mut impl OutlinePen) { - let font = FontRef::new(font).unwrap(); - let gid = font - .cmap() - .unwrap() - .map_codepoint(codepoint) - .unwrap_or_else(|| panic!("No gid for 0x{codepoint:04x}")); - let outlines = font.outline_glyphs(); - let outline = outlines.get(gid).unwrap_or_else(|| { - panic!( - "No outline for {gid:?} in collection of {:?}", - outlines.format() - ) - }); - - outline.draw(settings, pen).unwrap(); - } - - fn draw_commands(font: &[u8], codepoint: u32, settings: DrawSettings) -> String { - let mut pen = CommandPen::default(); - draw_to_pen(font, codepoint, settings, &mut pen); - pen.commands - } - - fn drawn_points(font: &[u8], codepoint: u32, settings: DrawSettings) -> Vec { - let mut pen = PointPen::new(); - draw_to_pen(font, codepoint, settings, &mut pen); - pen.into_points() - } - - fn insert_implicit_oncurve(pointstream: &[GlyphPoint]) -> Vec { - let mut expanded_points = Vec::new(); - - for i in 0..pointstream.len() - 1 { - expanded_points.push(pointstream[i]); - if matches!( - (pointstream[i], pointstream[i + 1]), - (GlyphPoint::Off { .. }, GlyphPoint::Off { .. }) - ) { - expanded_points.push(pointstream[i].implied_oncurve(pointstream[i + 1])); - } - } - - expanded_points.push(*pointstream.last().unwrap()); - - expanded_points - } - - fn as_on_off_sequence(points: &[GlyphPoint]) -> Vec<&'static str> { - points - .iter() - .map(|p| match p { - GlyphPoint::On { .. } => "On", - GlyphPoint::Off { .. } => "Off", - }) - .collect() - } - - #[test] - fn always_get_closing_lines() { - // - let period = draw_commands( - font_test_data::INTERPOLATE_THIS, - PERIOD, - Size::unscaled().into(), - ); - let comma = draw_commands( - font_test_data::INTERPOLATE_THIS, - COMMA, - Size::unscaled().into(), - ); - - assert_eq!( - period, comma, - "Incompatible\nperiod\n{period:#?}\ncomma\n{comma:#?}\n" - ); - assert_eq!( - "MLLLZ", period, - "We should get an explicit L for close even when it's a nop" - ); - } - - #[test] - fn triangle_and_square_retain_compatibility() { - // - let period = drawn_points( - font_test_data::INTERPOLATE_THIS, - PERIOD, - Size::unscaled().into(), - ); - let comma = drawn_points( - font_test_data::INTERPOLATE_THIS, - COMMA, - Size::unscaled().into(), - ); - - assert_ne!(period, comma); - assert_eq!( - as_on_off_sequence(&period), - as_on_off_sequence(&comma), - "Incompatible\nperiod\n{period:#?}\ncomma\n{comma:#?}\n" - ); - assert_eq!( - 4, - period.len(), - "we should have the same # of points we started with" - ); - } - - fn assert_walked_backwards_like_freetype(pointstream: &[GlyphPoint], font: &[u8]) { - assert!( - matches!(pointstream[0], GlyphPoint::Off { .. }), - "Bad testdata, should start off curve" - ); - - // The default: look for an oncurve at the back, as freetype would do - let mut expected_points = pointstream.to_vec(); - let last = *expected_points.last().unwrap(); - let first_move = if matches!(last, GlyphPoint::Off { .. }) { - expected_points[0].implied_oncurve(last) - } else { - expected_points.pop().unwrap() - }; - expected_points.insert(0, first_move); - - expected_points = insert_implicit_oncurve(&expected_points); - let actual = drawn_points(font, PERIOD, Size::unscaled().into()); - assert_eq!( - expected_points, actual, - "expected\n{expected_points:#?}\nactual\n{actual:#?}" - ); - } - - fn assert_walked_forwards_like_harfbuzz(pointstream: &[GlyphPoint], font: &[u8]) { - assert!( - matches!(pointstream[0], GlyphPoint::Off { .. }), - "Bad testdata, should start off curve" - ); - - // look for an oncurve at the front, as harfbuzz would do - let mut expected_points = pointstream.to_vec(); - let first = expected_points.remove(0); - expected_points.push(first); - if matches!(expected_points[0], GlyphPoint::Off { .. }) { - expected_points.insert(0, first.implied_oncurve(expected_points[0])) - }; - - expected_points = insert_implicit_oncurve(&expected_points); - - let settings: DrawSettings = Size::unscaled().into(); - let settings = settings.with_path_style(PathStyle::HarfBuzz); - let actual = drawn_points(font, PERIOD, settings); - assert_eq!( - expected_points, actual, - "expected\n{expected_points:#?}\nactual\n{actual:#?}" - ); - } - - #[test] - fn starting_off_curve_walk_backwards_like_freetype() { - assert_walked_backwards_like_freetype( - &STARTING_OFF_CURVE_POINTS, - font_test_data::STARTING_OFF_CURVE, - ); - } - - #[test] - fn mostly_off_curve_walk_backwards_like_freetype() { - assert_walked_backwards_like_freetype( - &MOSTLY_OFF_CURVE_POINTS, - font_test_data::MOSTLY_OFF_CURVE, - ); - } - - #[test] - fn starting_off_curve_walk_forwards_like_hbdraw() { - assert_walked_forwards_like_harfbuzz( - &STARTING_OFF_CURVE_POINTS, - font_test_data::STARTING_OFF_CURVE, - ); - } - - #[test] - fn mostly_off_curve_walk_forwards_like_hbdraw() { - assert_walked_forwards_like_harfbuzz( - &MOSTLY_OFF_CURVE_POINTS, - font_test_data::MOSTLY_OFF_CURVE, - ); - } - - // A location noted for making FreeType and HarfBuzz results differ - // See https://github.com/googlefonts/sleipnir/pull/15 - fn icon_loc_off_default(font: &FontRef) -> Location { - font.axes().location(&[ - ("wght", 700.0), - ("opsz", 48.0), - ("GRAD", 200.0), - ("FILL", 1.0), - ]) - } - - fn pt(x: f32, y: f32) -> Point { - (x as f64, y as f64).into() - } - - // String command rounded to two decimal places, suitable for assert comparison - fn svg_commands(elements: &[PathEl]) -> Vec { - elements - .iter() - .map(|e| match e { - PathEl::MoveTo(p) => format!("M{:.2},{:.2}", p.x, p.y), - PathEl::LineTo(p) => format!("L{:.2},{:.2}", p.x, p.y), - PathEl::QuadTo(c0, p) => format!("Q{:.2},{:.2} {:.2},{:.2}", c0.x, c0.y, p.x, p.y), - PathEl::CurveTo(c0, c1, p) => format!( - "C{:.2},{:.2} {:.2},{:.2} {:.2},{:.2}", - c0.x, c0.y, c1.x, c1.y, p.x, p.y - ), - PathEl::ClosePath => "Z".to_string(), - }) - .collect() - } - - // Declared here to avoid a write-fonts dependency that is awkward for google3 at time of writing - #[derive(Default)] - struct BezPen { - path: BezPath, - } - - impl OutlinePen for BezPen { - fn move_to(&mut self, x: f32, y: f32) { - self.path.move_to(pt(x, y)); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.path.line_to(pt(x, y)); - } - - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { - self.path.quad_to(pt(cx0, cy0), pt(x, y)); - } - - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { - self.path.curve_to(pt(cx0, cy0), pt(cx1, cy1), pt(x, y)); - } - - fn close(&mut self) { - self.path.close_path(); - } - } - - // We take glyph id here to bypass the need to resolve codepoint:gid and apply substitutions - fn assert_glyph_path_start_with( - font: &FontRef, - gid: GlyphId, - loc: Location, - path_style: PathStyle, - expected_path_start: &[PathEl], - ) { - let glyph = font - .outline_glyphs() - .get(gid) - .unwrap_or_else(|| panic!("No glyph for {gid}")); - - let mut pen = BezPen::default(); - glyph - .draw( - DrawSettings::unhinted(Size::unscaled(), &loc).with_path_style(path_style), - &mut pen, - ) - .unwrap_or_else(|e| panic!("Unable to draw {gid}: {e}")); - let bez = Affine::FLIP_Y * pen.path; // like an icon svg - let actual_path_start = &bez.elements()[..expected_path_start.len()]; - // round2 can still leave very small differences from the typed 2-decimal value - // and the diff isn't pleasant so just compare as svg string fragments - assert_eq!( - svg_commands(expected_path_start), - svg_commands(actual_path_start) - ); - } - - const MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT: GlyphId = GlyphId::new(1); - const MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT: GlyphId = GlyphId::new(2); - - #[test] - fn draw_icon_freetype_style_at_default() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - assert_glyph_path_start_with( - &font, - MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT, - Location::default(), - PathStyle::FreeType, - &[ - PathEl::MoveTo((160.0, -160.0).into()), - PathEl::QuadTo((127.0, -160.0).into(), (103.5, -183.5).into()), - PathEl::QuadTo((80.0, -207.0).into(), (80.0, -240.0).into()), - ], - ); - } - - #[test] - fn draw_icon_harfbuzz_style_at_default() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - assert_glyph_path_start_with( - &font, - MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT, - Location::default(), - PathStyle::HarfBuzz, - &[ - PathEl::MoveTo((160.0, -160.0).into()), - PathEl::QuadTo((127.0, -160.0).into(), (103.5, -183.5).into()), - PathEl::QuadTo((80.0, -207.0).into(), (80.0, -240.0).into()), - ], - ); - } - - #[test] - fn draw_icon_freetype_style_off_default() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - assert_glyph_path_start_with( - &font, - MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT, - icon_loc_off_default(&font), - PathStyle::FreeType, - &[ - PathEl::MoveTo((150.0, -138.0).into()), - PathEl::QuadTo((113.0, -138.0).into(), (86.0, -165.5).into()), - PathEl::QuadTo((59.0, -193.0).into(), (59.0, -229.0).into()), - ], - ); - } - - #[test] - fn draw_icon_harfbuzz_style_off_default() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - assert_glyph_path_start_with( - &font, - MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT, - icon_loc_off_default(&font), - PathStyle::HarfBuzz, - &[ - PathEl::MoveTo((150.0, -138.0).into()), - PathEl::QuadTo((113.22, -138.0).into(), (86.11, -165.61).into()), - PathEl::QuadTo((59.0, -193.22).into(), (59.0, -229.0).into()), - ], - ); - } - - const GLYF_COMPONENT_GID_NON_UNIFORM_SCALE: GlyphId = GlyphId::new(3); - const GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET: GlyphId = GlyphId::new(7); - const GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET: GlyphId = GlyphId::new(8); - - #[test] - fn draw_nonuniform_scale_component_freetype() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_NON_UNIFORM_SCALE, - Location::default(), - PathStyle::FreeType, - &[ - PathEl::MoveTo((-138.0, -185.0).into()), - PathEl::LineTo((-32.0, -259.0).into()), - PathEl::LineTo((26.0, -175.0).into()), - PathEl::LineTo((-80.0, -101.0).into()), - PathEl::ClosePath, - ], - ); - } - - #[test] - fn draw_nonuniform_scale_component_harfbuzz() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_NON_UNIFORM_SCALE, - Location::default(), - PathStyle::HarfBuzz, - &[ - PathEl::MoveTo((-137.8, -184.86).into()), - PathEl::LineTo((-32.15, -258.52).into()), - PathEl::LineTo((25.9, -175.24).into()), - PathEl::LineTo((-79.75, -101.58).into()), - PathEl::ClosePath, - ], - ); - } - - #[test] - fn draw_scaled_component_offset_freetype() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET, - Location::default(), - PathStyle::FreeType, - &[ - // Adds (x-transform magnitude * x-offset, y-transform magnitude * y-offset) to x/y offset - PathEl::MoveTo((715.0, -360.0).into()), - ], - ); - } - - #[test] - fn draw_no_scaled_component_offset_freetype() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET, - Location::default(), - PathStyle::FreeType, - &[PathEl::MoveTo((705.0, -340.0).into())], - ); - } - - #[test] - fn draw_scaled_component_offset_harfbuzz() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET, - Location::default(), - PathStyle::HarfBuzz, - &[ - // Adds (x-transform magnitude * x-offset, y-transform magnitude * y-offset) to x/y offset - PathEl::MoveTo((714.97, -360.0).into()), - ], - ); - } - - #[test] - fn draw_no_scaled_component_offset_harfbuzz() { - let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); - assert_glyph_path_start_with( - &font, - GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET, - Location::default(), - PathStyle::HarfBuzz, - &[PathEl::MoveTo((704.97, -340.0).into())], - ); - } - - #[cfg(feature = "spec_next")] - const CUBIC_GLYPH: GlyphId = GlyphId::new(2); - - #[test] - #[cfg(feature = "spec_next")] - fn draw_cubic() { - let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); - assert_glyph_path_start_with( - &font, - CUBIC_GLYPH, - Location::default(), - PathStyle::FreeType, - &[ - PathEl::MoveTo((278.0, -710.0).into()), - PathEl::LineTo((278.0, -470.0).into()), - PathEl::CurveTo( - (300.0, -500.0).into(), - (800.0, -500.0).into(), - (998.0, -470.0).into(), - ), - PathEl::LineTo((998.0, -710.0).into()), - ], - ); - } - - /// Case where a font subset caused hinting to fail because execution - /// budget was derived from glyph count. - /// - #[test] - fn tthint_with_subset() { - let font = FontRef::new(font_test_data::TTHINT_SUBSET).unwrap(); - let glyphs = font.outline_glyphs(); - let hinting = HintingInstance::new( - &glyphs, - Size::new(16.0), - LocationRef::default(), - HintingOptions::default(), - ) - .unwrap(); - let glyph = glyphs.get(GlyphId::new(1)).unwrap(); - // Shouldn't fail in pedantic mode - glyph - .draw(DrawSettings::hinted(&hinting, true), &mut BezPen::default()) - .unwrap(); - } - - #[test] - fn empty_glyph_advance_unhinted() { - let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); - let outlines = font.outline_glyphs(); - let coords = [NormalizedCoord::from_f32(0.5)]; - let gid = font.charmap().map(' ').unwrap(); - let outline = outlines.get(gid).unwrap(); - let advance = outline - .draw( - (Size::new(24.0), LocationRef::new(&coords)), - &mut super::pen::NullPen, - ) - .unwrap() - .advance_width - .unwrap(); - assert_eq!(advance, 10.796875); - } - - #[test] - fn empty_glyph_advance_hinted() { - let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); - let outlines = font.outline_glyphs(); - let coords = [NormalizedCoord::from_f32(0.5)]; - let hinter = HintingInstance::new( - &outlines, - Size::new(24.0), - LocationRef::new(&coords), - HintingOptions::default(), - ) - .unwrap(); - let gid = font.charmap().map(' ').unwrap(); - let outline = outlines.get(gid).unwrap(); - let advance = outline - .draw(&hinter, &mut super::pen::NullPen) - .unwrap() - .advance_width - .unwrap(); - assert_eq!(advance, 11.0); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -//! TrueType style outline to path conversion. - -use super::pen::{OutlinePen, PathStyle}; -use core::fmt; -use raw::{ - tables::glyf::{PointCoord, PointFlags}, - types::Point, -}; - -/// Errors that can occur when converting an outline to a path. -#[derive(Clone, Debug)] -pub enum ToPathError { - /// Contour end point at this index was less than its preceding end point. - ContourOrder(usize), - /// Expected a quadratic off-curve point at this index. - ExpectedQuad(usize), - /// Expected a quadratic off-curve or on-curve point at this index. - ExpectedQuadOrOnCurve(usize), - /// Expected a cubic off-curve point at this index. - ExpectedCubic(usize), - /// Expected number of points to == number of flags - PointFlagMismatch { num_points: usize, num_flags: usize }, -} - -impl fmt::Display for ToPathError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Self::ContourOrder(ix) => write!( - f, - "Contour end point at index {ix} was less than preceding end point" - ), - Self::ExpectedQuad(ix) => write!(f, "Expected quadatic off-curve point at index {ix}"), - Self::ExpectedQuadOrOnCurve(ix) => write!( - f, - "Expected quadatic off-curve or on-curve point at index {ix}" - ), - Self::ExpectedCubic(ix) => write!(f, "Expected cubic off-curve point at index {ix}"), - Self::PointFlagMismatch { - num_points, - num_flags, - } => write!( - f, - "Number of points ({num_points}) and flags ({num_flags}) must match" - ), - } - } -} - -/// Converts a `glyf` outline described by points, flags and contour end points -/// to a sequence of path elements and invokes the appropriate callback on the -/// given pen for each. -/// -/// The input points can have any coordinate type that implements -/// [`PointCoord`]. Output points are always generated in `f32`. -/// -/// This is roughly equivalent to [`FT_Outline_Decompose`](https://freetype.org/freetype2/docs/reference/ft2-outline_processing.html#ft_outline_decompose). -/// -/// See [`contour_to_path`] for a more general function that takes an iterator -/// if your outline data is in a different format. -pub(crate) fn to_path( - points: &[Point], - flags: &[PointFlags], - contours: &[u16], - path_style: PathStyle, - pen: &mut impl OutlinePen, -) -> Result<(), ToPathError> { - for contour_ix in 0..contours.len() { - let start_ix = (contour_ix > 0) - .then(|| contours[contour_ix - 1] as usize + 1) - .unwrap_or_default(); - let end_ix = contours[contour_ix] as usize; - if end_ix < start_ix || end_ix >= points.len() { - return Err(ToPathError::ContourOrder(contour_ix)); - } - let points = &points[start_ix..=end_ix]; - if points.is_empty() { - continue; - } - let flags = flags - .get(start_ix..=end_ix) - .ok_or(ToPathError::PointFlagMismatch { - num_points: points.len(), - num_flags: flags.len(), - })?; - let last_point = points.last().unwrap(); - let last_flags = flags.last().unwrap(); - let last_point = ContourPoint { - x: last_point.x, - y: last_point.y, - flags: *last_flags, - }; - contour_to_path( - points.iter().zip(flags).map(|(point, flags)| ContourPoint { - x: point.x, - y: point.y, - flags: *flags, - }), - last_point, - path_style, - pen, - ) - .map_err(|e| match &e { - ToPathError::ExpectedCubic(ix) => ToPathError::ExpectedCubic(ix + start_ix), - ToPathError::ExpectedQuad(ix) => ToPathError::ExpectedQuad(ix + start_ix), - ToPathError::ExpectedQuadOrOnCurve(ix) => { - ToPathError::ExpectedQuadOrOnCurve(ix + start_ix) - } - _ => e, - })? - } - Ok(()) -} - -/// Combination of point coordinates and flags. -#[derive(Copy, Clone, Default, Debug)] -pub(crate) struct ContourPoint { - pub x: T, - pub y: T, - pub flags: PointFlags, -} - -impl ContourPoint -where - T: PointCoord, -{ - fn point_f32(&self) -> Point { - Point::new(self.x.to_f32(), self.y.to_f32()) - } - - fn midpoint(&self, other: Self) -> ContourPoint { - let (x, y) = (self.x.midpoint(other.x), self.y.midpoint(other.y)); - Self { - x, - y, - flags: other.flags, - } - } -} - -/// Generates a path from an iterator of contour points. -/// -/// Note that this requires the last point of the contour to be passed -/// separately to support FreeType style path conversion when the contour -/// begins with an off curve point. The points iterator should still -/// yield the last point as well. -/// -/// This is more general than [`to_path`] and exists to support cases (such as -/// autohinting) where the source outline data is in a different format. -pub(crate) fn contour_to_path( - points: impl Iterator>, - last_point: ContourPoint, - style: PathStyle, - pen: &mut impl OutlinePen, -) -> Result<(), ToPathError> { - let mut points = points.enumerate().peekable(); - let Some((_, first_point)) = points.peek().copied() else { - // This is an empty contour - return Ok(()); - }; - // We don't accept an off curve cubic as the first point - if first_point.flags.is_off_curve_cubic() { - return Err(ToPathError::ExpectedQuadOrOnCurve(0)); - } - // For FreeType style, we may need to omit the last point if we find the - // first on curve there - let mut omit_last = false; - // For HarfBuzz style, may skip up to two points in finding the start, so - // process these at the end - let mut trailing_points = [None; 2]; - // Find our starting point - let start_point = if first_point.flags.is_off_curve_quad() { - // We're starting with an off curve, so select our first move based on - // the path style - match style { - PathStyle::FreeType => { - if last_point.flags.is_on_curve() { - // The last point is an on curve, so let's start there - omit_last = true; - last_point - } else { - // It's also an off curve, so take implicit midpoint - last_point.midpoint(first_point) - } - } - PathStyle::HarfBuzz => { - // Always consume the first point - points.next(); - // Then check the next point - let Some((_, next_point)) = points.peek().copied() else { - // This is a single point contour - return Ok(()); - }; - if next_point.flags.is_on_curve() { - points.next(); - trailing_points = [Some((0, first_point)), Some((1, next_point))]; - // Next is on curve, so let's start there - next_point - } else { - // It's also an off curve, so take the implicit midpoint - trailing_points = [Some((0, first_point)), None]; - first_point.midpoint(next_point) - } - } - } - } else { - // We're starting with an on curve, so consume the point - points.next(); - first_point - }; - let point = start_point.point_f32(); - pen.move_to(point.x, point.y); - let mut state = PendingState::default(); - if omit_last { - while let Some((ix, point)) = points.next() { - if points.peek().is_none() { - break; - } - state.emit(ix, point, pen)?; - } - } else { - for (ix, point) in points { - state.emit(ix, point, pen)?; - } - } - for (ix, point) in trailing_points.iter().filter_map(|x| *x) { - state.emit(ix, point, pen)?; - } - state.finish(0, start_point, pen)?; - Ok(()) -} - -#[derive(Copy, Clone, Default)] -enum PendingState { - /// No pending points. - #[default] - Empty, - /// Pending off-curve quad point. - PendingQuad(ContourPoint), - /// Single pending off-curve cubic point. - PendingCubic(ContourPoint), - /// Two pending off-curve cubic points. - TwoPendingCubics(ContourPoint, ContourPoint), -} - -impl PendingState -where - C: PointCoord, -{ - #[inline(always)] - fn emit( - &mut self, - ix: usize, - point: ContourPoint, - pen: &mut impl OutlinePen, - ) -> Result<(), ToPathError> { - let flags = point.flags; - match *self { - Self::Empty => { - if flags.is_off_curve_quad() { - *self = Self::PendingQuad(point); - } else if flags.is_off_curve_cubic() { - *self = Self::PendingCubic(point); - } else { - let p = point.point_f32(); - pen.line_to(p.x, p.y); - } - } - Self::PendingQuad(quad) => { - if flags.is_off_curve_quad() { - let c0 = quad.point_f32(); - let p = quad.midpoint(point).point_f32(); - pen.quad_to(c0.x, c0.y, p.x, p.y); - *self = Self::PendingQuad(point); - } else if flags.is_off_curve_cubic() { - return Err(ToPathError::ExpectedQuadOrOnCurve(ix)); - } else { - let c0 = quad.point_f32(); - let p = point.point_f32(); - pen.quad_to(c0.x, c0.y, p.x, p.y); - *self = Self::Empty; - } - } - Self::PendingCubic(cubic) => { - if flags.is_off_curve_cubic() { - *self = Self::TwoPendingCubics(cubic, point); - } else { - return Err(ToPathError::ExpectedCubic(ix)); - } - } - Self::TwoPendingCubics(cubic0, cubic1) => { - if flags.is_off_curve_quad() { - return Err(ToPathError::ExpectedCubic(ix)); - } else if flags.is_off_curve_cubic() { - let c0 = cubic0.point_f32(); - let c1 = cubic1.point_f32(); - let p = cubic1.midpoint(point).point_f32(); - pen.curve_to(c0.x, c0.y, c1.x, c1.y, p.x, p.y); - *self = Self::PendingCubic(point); - } else { - let c0 = cubic0.point_f32(); - let c1 = cubic1.point_f32(); - let p = point.point_f32(); - pen.curve_to(c0.x, c0.y, c1.x, c1.y, p.x, p.y); - *self = Self::Empty; - } - } - } - Ok(()) - } - - fn finish( - mut self, - start_ix: usize, - mut start_point: ContourPoint, - pen: &mut impl OutlinePen, - ) -> Result<(), ToPathError> { - match self { - Self::Empty => {} - _ => { - // We always want to end with an explicit on-curve - start_point.flags = PointFlags::on_curve(); - self.emit(start_ix, start_point, pen)?; - } - } - pen.close(); - Ok(()) - } -} - -#[cfg(test)] -mod tests { - use super::{super::pen::SvgPen, *}; - use raw::types::F26Dot6; - - fn assert_off_curve_path_to_svg(expected: &str, path_style: PathStyle, all_off_curve: bool) { - fn pt(x: i32, y: i32) -> Point { - Point::new(x, y).map(F26Dot6::from_bits) - } - let mut flags = [PointFlags::off_curve_quad(); 4]; - if !all_off_curve { - flags[1] = PointFlags::on_curve(); - } - let contours = [3]; - // This test is meant to prevent a bug where the first move-to was computed improperly - // for a contour consisting of all off curve points. - // In this case, the start of the path should be the midpoint between the first and last points. - // For this test case (in 26.6 fixed point): [(640, 128) + (128, 128)] / 2 = (384, 128) - // which becomes (6.0, 2.0) when converted to floating point. - let points = [pt(640, 128), pt(256, 64), pt(640, 64), pt(128, 128)]; - let mut pen = SvgPen::with_precision(1); - to_path(&points, &flags, &contours, path_style, &mut pen).unwrap(); - assert_eq!(pen.as_ref(), expected); - } - - #[test] - fn all_off_curve_to_path_scan_backward() { - assert_off_curve_path_to_svg( - "M6.0,2.0 Q10.0,2.0 7.0,1.5 Q4.0,1.0 7.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Z", - PathStyle::FreeType, - true, - ); - } - - #[test] - fn all_off_curve_to_path_scan_forward() { - assert_off_curve_path_to_svg( - "M7.0,1.5 Q4.0,1.0 7.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Q10.0,2.0 7.0,1.5 Z", - PathStyle::HarfBuzz, - true, - ); - } - - #[test] - fn start_off_curve_to_path_scan_backward() { - assert_off_curve_path_to_svg( - "M6.0,2.0 Q10.0,2.0 4.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Z", - PathStyle::FreeType, - false, - ); - } - - #[test] - fn start_off_curve_to_path_scan_forward() { - assert_off_curve_path_to_svg( - "M4.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Q10.0,2.0 4.0,1.0 Z", - PathStyle::HarfBuzz, - false, - ); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,247 +0,0 @@ -//! Types for collecting the output when drawing a glyph outline. - -use alloc::{string::String, vec::Vec}; -use core::fmt::{self, Write}; - -/// Interface for accepting a sequence of path commands. -pub trait OutlinePen { - /// Emit a command to begin a new subpath at (x, y). - fn move_to(&mut self, x: f32, y: f32); - - /// Emit a line segment from the current point to (x, y). - fn line_to(&mut self, x: f32, y: f32); - - /// Emit a quadratic bezier segment from the current point with a control - /// point at (cx0, cy0) and ending at (x, y). - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32); - - /// Emit a cubic bezier segment from the current point with control - /// points at (cx0, cy0) and (cx1, cy1) and ending at (x, y). - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32); - - /// Emit a command to close the current subpath. - fn close(&mut self); -} - -/// Single element of a path. -#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] -pub enum PathElement { - /// Begin a new subpath at (x, y). - MoveTo { x: f32, y: f32 }, - /// Draw a line from the current point to (x, y). - LineTo { x: f32, y: f32 }, - /// Draw a quadratic bezier from the current point with a control point at - /// (cx0, cy0) and ending at (x, y). - QuadTo { cx0: f32, cy0: f32, x: f32, y: f32 }, - /// Draw a cubic bezier from the current point with control points at - /// (cx0, cy0) and (cx1, cy1) and ending at (x, y). - CurveTo { - cx0: f32, - cy0: f32, - cx1: f32, - cy1: f32, - x: f32, - y: f32, - }, - /// Close the current subpath. - Close, -} - -/// Style for path conversion. -/// -/// The order to process points in a glyf point stream is ambiguous when the -/// first point is off-curve. Major implementations differ. Which one would -/// you like to match? -/// -/// **If you add a new one make sure to update the fuzzer.** -#[derive(Debug, Default, Copy, Clone)] -pub enum PathStyle { - /// If the first point is off-curve, check if the last is on-curve - /// If it is, start there. If it isn't, start at the implied midpoint - /// between first and last. - #[default] - FreeType, - /// If the first point is off-curve, check if the second is on-curve. - /// If it is, start there. If it isn't, start at the implied midpoint - /// between first and second. - /// - /// Matches hb-draw's interpretation of a point stream. - HarfBuzz, -} - -impl OutlinePen for Vec { - fn move_to(&mut self, x: f32, y: f32) { - self.push(PathElement::MoveTo { x, y }) - } - - fn line_to(&mut self, x: f32, y: f32) { - self.push(PathElement::LineTo { x, y }) - } - - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { - self.push(PathElement::QuadTo { cx0, cy0, x, y }) - } - - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { - self.push(PathElement::CurveTo { - cx0, - cy0, - cx1, - cy1, - x, - y, - }) - } - - fn close(&mut self) { - self.push(PathElement::Close) - } -} - -/// Pen that drops all drawing output into the ether. -pub struct NullPen; - -impl OutlinePen for NullPen { - fn move_to(&mut self, _x: f32, _y: f32) {} - fn line_to(&mut self, _x: f32, _y: f32) {} - fn quad_to(&mut self, _cx0: f32, _cy0: f32, _x: f32, _y: f32) {} - fn curve_to(&mut self, _cx0: f32, _cy0: f32, _cx1: f32, _cy1: f32, _x: f32, _y: f32) {} - fn close(&mut self) {} -} - -/// Pen that generates SVG style path data. -#[derive(Clone, Default, Debug)] -pub struct SvgPen(String, Option); - -impl SvgPen { - /// Creates a new SVG pen that formats floating point values with the - /// standard behavior. - pub fn new() -> Self { - Self::default() - } - - /// Creates a new SVG pen with the given precision (the number of digits - /// that will be printed after the decimal). - pub fn with_precision(precision: usize) -> Self { - Self(String::default(), Some(precision)) - } - - /// Clears the content of the internal string. - pub fn clear(&mut self) { - self.0.clear(); - } - - fn maybe_push_space(&mut self) { - if !self.0.is_empty() { - self.0.push(' '); - } - } -} - -impl core::ops::Deref for SvgPen { - type Target = str; - - fn deref(&self) -> &Self::Target { - self.0.as_str() - } -} - -impl OutlinePen for SvgPen { - fn move_to(&mut self, x: f32, y: f32) { - self.maybe_push_space(); - let _ = if let Some(prec) = self.1 { - write!(self.0, "M{x:.0$},{y:.0$}", prec) - } else { - write!(self.0, "M{x},{y}") - }; - } - - fn line_to(&mut self, x: f32, y: f32) { - self.maybe_push_space(); - let _ = if let Some(prec) = self.1 { - write!(self.0, "L{x:.0$},{y:.0$}", prec) - } else { - write!(self.0, "L{x},{y}") - }; - } - - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { - self.maybe_push_space(); - let _ = if let Some(prec) = self.1 { - write!(self.0, "Q{cx0:.0$},{cy0:.0$} {x:.0$},{y:.0$}", prec) - } else { - write!(self.0, "Q{cx0},{cy0} {x},{y}") - }; - } - - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { - self.maybe_push_space(); - let _ = if let Some(prec) = self.1 { - write!( - self.0, - "C{cx0:.0$},{cy0:.0$} {cx1:.0$},{cy1:.0$} {x:.0$},{y:.0$}", - prec - ) - } else { - write!(self.0, "C{cx0},{cy0} {cx1},{cy1} {x},{y}") - }; - } - - fn close(&mut self) { - self.maybe_push_space(); - self.0.push('Z'); - } -} - -impl AsRef for SvgPen { - fn as_ref(&self) -> &str { - self.0.as_ref() - } -} - -impl From for SvgPen { - fn from(value: String) -> Self { - Self(value, None) - } -} - -impl From for String { - fn from(value: SvgPen) -> Self { - value.0 - } -} - -impl fmt::Display for SvgPen { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.0) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn svg_pen_precision() { - let svg_data = [None, Some(1), Some(4)].map(|prec| { - let mut pen = match prec { - None => SvgPen::new(), - Some(prec) => SvgPen::with_precision(prec), - }; - pen.move_to(1.0, 2.45556); - pen.line_to(1.2, 4.0); - pen.quad_to(2.0345, 3.56789, -0.157, -425.07); - pen.curve_to(-37.0010, 4.5, 2.0, 1.0, -0.5, -0.25); - pen.close(); - pen.to_string() - }); - let expected = [ - "M1,2.45556 L1.2,4 Q2.0345,3.56789 -0.157,-425.07 C-37.001,4.5 2,1 -0.5,-0.25 Z", - "M1.0,2.5 L1.2,4.0 Q2.0,3.6 -0.2,-425.1 C-37.0,4.5 2.0,1.0 -0.5,-0.2 Z", - "M1.0000,2.4556 L1.2000,4.0000 Q2.0345,3.5679 -0.1570,-425.0700 C-37.0010,4.5000 2.0000,1.0000 -0.5000,-0.2500 Z" - ]; - for (result, expected) in svg_data.iter().zip(&expected) { - assert_eq!(result, expected); - } - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ -//! Helpers for unit testing - -use super::OutlinePen; -use core::str::FromStr; -use raw::{ - tables::glyf::PointFlags, - types::{F26Dot6, F2Dot14, GlyphId, Point}, -}; - -#[derive(Copy, Clone, PartialEq, Debug)] -// clippy doesn't like the common To suffix -#[allow(clippy::enum_variant_names)] -pub enum PathElement { - MoveTo([f32; 2]), - LineTo([f32; 2]), - QuadTo([f32; 4]), - CurveTo([f32; 6]), -} - -#[derive(Default)] -pub struct Path { - pub elements: Vec, - last_end: Option<[f32; 2]>, -} - -impl OutlinePen for Path { - fn move_to(&mut self, x: f32, y: f32) { - self.elements.push(PathElement::MoveTo([x, y])); - self.last_end = Some([x, y]); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.elements.push(PathElement::LineTo([x, y])); - self.last_end = Some([x, y]); - } - - fn quad_to(&mut self, x0: f32, y0: f32, x1: f32, y1: f32) { - self.elements.push(PathElement::QuadTo([x0, y0, x1, y1])); - self.last_end = Some([x1, y1]); - } - - fn curve_to(&mut self, x0: f32, y0: f32, x1: f32, y1: f32, x2: f32, y2: f32) { - self.elements - .push(PathElement::CurveTo([x0, y0, x1, y1, x2, y2])); - self.last_end = Some([x2, y2]); - } - - fn close(&mut self) { - // FT_Outline_Decompose does not generate close commands, so for - // testing purposes, we insert a line to same point as the most - // recent move_to (if the last command didn't end at the same point) - // which copies FreeType's behavior. - let last_move = self - .elements - .iter() - .rev() - .find(|element| matches!(*element, PathElement::MoveTo(_))) - .copied(); - if let Some(PathElement::MoveTo(point)) = last_move { - if Some(point) != self.last_end { - self.elements.push(PathElement::LineTo(point)); - } - } - } -} - -#[derive(Clone, Default, Debug)] -pub struct GlyphOutline { - pub glyph_id: GlyphId, - pub size: f32, - pub coords: Vec, - pub points: Vec>, - pub contours: Vec, - pub flags: Vec, - pub path: Vec, -} - -pub fn parse_glyph_outlines(source: &str) -> Vec { - let mut outlines = vec![]; - let mut cur_outline = GlyphOutline::default(); - for line in source.lines() { - let line = line.trim(); - if line == "-" { - outlines.push(cur_outline.clone()); - } else if line.starts_with("glyph") { - cur_outline = GlyphOutline::default(); - let parts = line.split(' ').collect::>(); - cur_outline.glyph_id = GlyphId::new(parts[1].parse().unwrap()); - cur_outline.size = parts[2].parse().unwrap(); - } else if line.starts_with("coords") { - for coord in line.split(' ').skip(1) { - cur_outline - .coords - .push(F2Dot14::from_f32(coord.parse().unwrap())); - } - } else if line.starts_with("contours") { - for contour in line.split(' ').skip(1) { - cur_outline.contours.push(contour.parse().unwrap()); - } - } else if line.starts_with("points") { - let is_scaled = cur_outline.size != 0.0; - for mut point in parse_points(line.strip_prefix("points").unwrap().trim()) { - if !is_scaled { - point[0] <<= 6; - point[1] <<= 6; - } - cur_outline.points.push(Point { - x: F26Dot6::from_bits(point[0]), - y: F26Dot6::from_bits(point[1]), - }); - } - } else if line.starts_with("tags") { - for tag in line.split(' ').skip(1) { - cur_outline - .flags - .push(PointFlags::from_bits(tag.parse().unwrap())); - } - } else { - match line.as_bytes()[0] { - b'm' => { - let points = parse_points(line.strip_prefix("m ").unwrap().trim()); - cur_outline.path.push(PathElement::MoveTo(points[0])); - } - b'l' => { - let points = parse_points(line.strip_prefix("l ").unwrap().trim()); - cur_outline.path.push(PathElement::LineTo(points[0])); - } - b'q' => { - let points = parse_points(line.strip_prefix("q ").unwrap().trim()); - cur_outline.path.push(PathElement::QuadTo([ - points[0][0], - points[0][1], - points[1][0], - points[1][1], - ])); - } - b'c' => { - let points = parse_points(line.strip_prefix("c ").unwrap().trim()); - cur_outline.path.push(PathElement::CurveTo([ - points[0][0], - points[0][1], - points[1][0], - points[1][1], - points[2][0], - points[2][1], - ])); - } - _ => panic!("unexpected path element"), - } - } - } - outlines -} - -fn parse_points(source: &str) -> Vec<[F; 2]> -where - F: FromStr + Copy + Default, - ::Err: core::fmt::Debug, -{ - let mut points = vec![]; - for point in source.split(' ') { - let point = point.trim(); - if point.is_empty() { - continue; - } - let mut components = [F::default(); 2]; - for (i, component) in point.trim().split(',').take(2).enumerate() { - components[i] = F::from_str(component).unwrap(); - } - points.push(components); - } - points -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,367 +0,0 @@ -//! Compact representation of an unscaled, unhinted outline. - -#![allow(dead_code)] - -use super::DrawError; -use crate::collections::SmallVec; -use core::ops::Range; -use raw::{ - tables::glyf::PointFlags, - types::{F26Dot6, Point}, -}; - -#[derive(Copy, Clone, Default, Debug)] -pub(super) struct UnscaledPoint { - pub x: i16, - pub y: i16, - pub flags: PointFlags, - pub is_contour_start: bool, -} - -impl UnscaledPoint { - pub fn from_glyf_point( - point: Point, - flags: PointFlags, - is_contour_start: bool, - ) -> Self { - let point = point.map(|x| (x.to_bits() >> 6) as i16); - Self { - x: point.x, - y: point.y, - flags: flags.without_markers(), - is_contour_start, - } - } - - pub fn is_on_curve(self) -> bool { - self.flags.is_on_curve() - } -} - -pub(super) trait UnscaledOutlineSink { - fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError>; - fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError>; - fn extend(&mut self, points: impl IntoIterator) -> Result<(), DrawError> { - for point in points.into_iter() { - self.push(point)?; - } - Ok(()) - } -} - -// please can I have smallvec? -pub(super) struct UnscaledOutlineBuf(SmallVec); - -impl UnscaledOutlineBuf { - pub fn new() -> Self { - Self(SmallVec::new()) - } - - pub fn clear(&mut self) { - self.0.clear(); - } - - pub fn as_ref(&self) -> UnscaledOutlineRef { - UnscaledOutlineRef { - points: self.0.as_slice(), - } - } -} - -impl UnscaledOutlineSink for UnscaledOutlineBuf { - fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError> { - if !self.0.try_reserve(additional) { - Err(DrawError::InsufficientMemory) - } else { - Ok(()) - } - } - - fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError> { - self.0.push(point); - Ok(()) - } -} - -#[derive(Copy, Clone, Debug)] -pub(super) struct UnscaledOutlineRef<'a> { - pub points: &'a [UnscaledPoint], -} - -impl UnscaledOutlineRef<'_> { - /// Returns the range of contour points and the index of the point within - /// that contour for the last point where `f` returns true. - /// - /// This is common code used for finding extrema when materializing blue - /// zones. - /// - /// For example: - pub fn find_last_contour( - &self, - mut f: impl FnMut(&UnscaledPoint) -> bool, - ) -> Option<(Range, usize)> { - if self.points.is_empty() { - return None; - } - let mut best_contour = 0..0; - // Index of the best point relative to the start of the best contour - let mut best_point = 0; - let mut cur_contour = 0..0; - let mut found_best_in_cur_contour = false; - for (point_ix, point) in self.points.iter().enumerate() { - if point.is_contour_start { - if found_best_in_cur_contour { - best_contour = cur_contour; - } - cur_contour = point_ix..point_ix; - found_best_in_cur_contour = false; - // Ignore single point contours - match self.points.get(point_ix + 1) { - Some(next_point) if next_point.is_contour_start => continue, - None => continue, - _ => {} - } - } - cur_contour.end += 1; - if f(point) { - best_point = point_ix - cur_contour.start; - found_best_in_cur_contour = true; - } - } - if found_best_in_cur_contour { - best_contour = cur_contour; - } - if !best_contour.is_empty() { - Some((best_contour, best_point)) - } else { - None - } - } -} - -/// Adapts an UnscaledOutlineSink to be fed from a pen while tracking -/// memory allocation errors. -pub(super) struct UnscaledPenAdapter<'a, T> { - sink: &'a mut T, - failed: bool, -} - -impl<'a, T> UnscaledPenAdapter<'a, T> { - pub fn new(sink: &'a mut T) -> Self { - Self { - sink, - failed: false, - } - } - - pub fn finish(self) -> Result<(), DrawError> { - if self.failed { - Err(DrawError::InsufficientMemory) - } else { - Ok(()) - } - } -} - -impl UnscaledPenAdapter<'_, T> -where - T: UnscaledOutlineSink, -{ - fn push(&mut self, x: f32, y: f32, flags: PointFlags, is_contour_start: bool) { - if self - .sink - .push(UnscaledPoint { - x: x as i16, - y: y as i16, - flags, - is_contour_start, - }) - .is_err() - { - self.failed = true; - } - } -} - -impl super::OutlinePen for UnscaledPenAdapter<'_, T> { - fn move_to(&mut self, x: f32, y: f32) { - self.push(x, y, PointFlags::on_curve(), true); - } - - fn line_to(&mut self, x: f32, y: f32) { - self.push(x, y, PointFlags::on_curve(), false); - } - - fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { - self.push(cx0, cy0, PointFlags::off_curve_quad(), false); - self.push(x, y, PointFlags::on_curve(), false); - } - - fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { - self.push(cx0, cy0, PointFlags::off_curve_cubic(), false); - self.push(cx1, cy1, PointFlags::off_curve_cubic(), false); - self.push(x, y, PointFlags::on_curve(), false); - } - - fn close(&mut self) {} -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::{prelude::LocationRef, MetadataProvider}; - use raw::{types::GlyphId, FontRef}; - - #[test] - fn read_glyf_outline() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - let glyph = font.outline_glyphs().get(GlyphId::new(5)).unwrap(); - let mut outline = UnscaledOutlineBuf::<32>::new(); - glyph - .draw_unscaled(LocationRef::default(), None, &mut outline) - .unwrap(); - let outline = outline.as_ref(); - let expected = [ - // contour 0 - (400, 80, 1), - (400, 360, 1), - (320, 360, 1), - (320, 600, 1), - (320, 633, 0), - (367, 680, 0), - (400, 680, 1), - (560, 680, 1), - (593, 680, 0), - (640, 633, 0), - (640, 600, 1), - (640, 360, 1), - (560, 360, 1), - (560, 80, 1), - // contour 1 - (480, 720, 1), - (447, 720, 0), - (400, 767, 0), - (400, 800, 1), - (400, 833, 0), - (447, 880, 0), - (480, 880, 1), - (513, 880, 0), - (560, 833, 0), - (560, 800, 1), - (560, 767, 0), - (513, 720, 0), - ]; - let points = outline - .points - .iter() - .map(|point| (point.x, point.y, point.flags.to_bits())) - .collect::>(); - assert_eq!(points, expected); - } - - #[test] - #[cfg(feature = "spec_next")] - fn read_cubic_glyf_outline() { - let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); - let glyph = font.outline_glyphs().get(GlyphId::new(2)).unwrap(); - let mut outline = UnscaledOutlineBuf::<32>::new(); - glyph - .draw_unscaled(LocationRef::default(), None, &mut outline) - .unwrap(); - let outline = outline.as_ref(); - let expected = [ - // contour 0 - (278, 710, 1), - (278, 470, 1), - (300, 500, 128), - (800, 500, 128), - (998, 470, 1), - (998, 710, 1), - ]; - let points = outline - .points - .iter() - .map(|point| (point.x, point.y, point.flags.to_bits())) - .collect::>(); - assert_eq!(points, expected); - } - - #[test] - fn read_cff_outline() { - let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); - let glyph = font.outline_glyphs().get(GlyphId::new(2)).unwrap(); - let mut outline = UnscaledOutlineBuf::<32>::new(); - glyph - .draw_unscaled(LocationRef::default(), None, &mut outline) - .unwrap(); - let outline = outline.as_ref(); - let expected = [ - // contour 0 - (83, 0, 1), - (163, 0, 1), - (163, 482, 1), - (83, 482, 1), - // contour 1 - (124, 595, 1), - (160, 595, 128), - (181, 616, 128), - (181, 652, 1), - (181, 688, 128), - (160, 709, 128), - (124, 709, 1), - (88, 709, 128), - (67, 688, 128), - (67, 652, 1), - (67, 616, 128), - (88, 595, 128), - (124, 595, 1), - ]; - let points = outline - .points - .iter() - .map(|point| (point.x, point.y, point.flags.to_bits())) - .collect::>(); - assert_eq!(points, expected); - } - - #[test] - fn find_vertical_extrema() { - let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); - let glyph = font.outline_glyphs().get(GlyphId::new(5)).unwrap(); - let mut outline = UnscaledOutlineBuf::<32>::new(); - glyph - .draw_unscaled(LocationRef::default(), None, &mut outline) - .unwrap(); - let outline = outline.as_ref(); - // Find the maximum Y value and its containing contour - let mut top_y = None; - let (top_contour, top_point_ix) = outline - .find_last_contour(|point| { - if top_y.is_none() || Some(point.y) > top_y { - top_y = Some(point.y); - true - } else { - false - } - }) - .unwrap(); - assert_eq!(top_contour, 14..26); - assert_eq!(top_point_ix, 5); - assert_eq!(top_y, Some(880)); - // Find the minimum Y value and its containing contour - let mut bottom_y = None; - let (bottom_contour, bottom_point_ix) = outline - .find_last_contour(|point| { - if bottom_y.is_none() || Some(point.y) < bottom_y { - bottom_y = Some(point.y); - true - } else { - false - } - }) - .unwrap(); - assert_eq!(bottom_contour, 0..14); - assert_eq!(bottom_point_ix, 0); - assert_eq!(bottom_y, Some(80)); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,104 +0,0 @@ -use super::{ - attribute::Attributes, - charmap::Charmap, - color::ColorGlyphCollection, - instance::{LocationRef, Size}, - metrics::{GlyphMetrics, Metrics}, - outline::OutlineGlyphCollection, - string::{LocalizedStrings, StringId}, - variation::{AxisCollection, NamedInstanceCollection}, - FontRef, -}; - -/// Interface for types that can provide font metadata. -pub trait MetadataProvider<'a>: Sized { - /// Returns the primary attributes for font classification-- stretch, - /// style and weight. - fn attributes(&self) -> Attributes; - - /// Returns the collection of variation axes. - fn axes(&self) -> AxisCollection<'a>; - - /// Returns the collection of named variation instances. - fn named_instances(&self) -> NamedInstanceCollection<'a>; - - /// Returns an iterator over the collection of localized strings for the - /// given informational string identifier. - fn localized_strings(&self, id: StringId) -> LocalizedStrings<'a>; - - /// Returns the global font metrics for the specified size and location in - /// normalized variation space. - fn metrics(&self, size: Size, location: impl Into>) -> Metrics; - - /// Returns the glyph specific metrics for the specified size and location - /// in normalized variation space. - fn glyph_metrics(&self, size: Size, location: impl Into>) -> GlyphMetrics<'a>; - - /// Returns the character to nominal glyph identifier mapping. - fn charmap(&self) -> Charmap<'a>; - - /// Returns the collection of scalable glyph outlines. - /// - /// If the font contains multiple outline sources, this method prioritizes - /// `glyf`, `CFF2` and `CFF` in that order. To select a specific outline - /// source, use the [`OutlineGlyphCollection::with_format`] method. - fn outline_glyphs(&self) -> OutlineGlyphCollection<'a>; - - // Returns a collection of paintable color glyphs. - fn color_glyphs(&self) -> ColorGlyphCollection<'a>; -} - -impl<'a> MetadataProvider<'a> for FontRef<'a> { - /// Returns the primary attributes for font classification-- stretch, - /// style and weight. - fn attributes(&self) -> Attributes { - Attributes::new(self) - } - - /// Returns the collection of variation axes. - fn axes(&self) -> AxisCollection<'a> { - AxisCollection::new(self) - } - - /// Returns the collection of named variation instances. - fn named_instances(&self) -> NamedInstanceCollection<'a> { - NamedInstanceCollection::new(self) - } - - /// Returns an iterator over the collection of localized strings for the - /// given informational string identifier. - fn localized_strings(&self, id: StringId) -> LocalizedStrings<'a> { - LocalizedStrings::new(self, id) - } - - /// Returns the global font metrics for the specified size and location in - /// normalized variation space. - fn metrics(&self, size: Size, location: impl Into>) -> Metrics { - Metrics::new(self, size, location) - } - - /// Returns the glyph specific metrics for the specified size and location - /// in normalized variation space. - fn glyph_metrics(&self, size: Size, location: impl Into>) -> GlyphMetrics<'a> { - GlyphMetrics::new(self, size, location) - } - - /// Returns the character to nominal glyph identifier mapping. - fn charmap(&self) -> Charmap<'a> { - Charmap::new(self) - } - - /// Returns the collection of scalable glyph outlines. - /// - /// If the font contains multiple outline sources, this method prioritizes - /// `glyf`, `CFF2` and `CFF` in that order. To select a specific outline - /// source, use the [`OutlineGlyphCollection::with_format`] method. - fn outline_glyphs(&self) -> OutlineGlyphCollection<'a> { - OutlineGlyphCollection::new(self) - } - - // Returns a collection of paintable color glyphs. - fn color_glyphs(&self) -> ColorGlyphCollection<'a> { - ColorGlyphCollection::new(self) - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -//! Definitions for specifying variations and typographic features. - -use super::Tag; -use core::str::FromStr; - -/// Setting defined by a selector tag and an associated value. -/// -/// This type is a generic container for properties that can be activated -/// or defined by a `(Tag, T)` pair where the tag selects the target -/// setting and the generic value of type `T` specifies the value for that -/// setting. -/// -/// ## Usage -/// Current usage is for specifying variation axis settings (similar to the -/// CSS property [font-variation-settings](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings)). -/// See [`VariationSetting`]. -/// -/// In the future, this will likely also be used for specifying feature settings -/// (analogous to the CSS property [font-feature-settings](https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings)) -/// for selecting OpenType [features](https://learn.microsoft.com/en-us/typography/opentype/spec/featuretags). -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub struct Setting { - /// Tag that specifies the target setting. - pub selector: Tag, - /// The desired value for the setting. - pub value: T, -} - -impl Setting { - /// Creates a new setting from the given selector tag and its associated - /// value. - pub fn new(selector: Tag, value: T) -> Self { - Self { selector, value } - } -} - -// This is provided so that &[VariationSetting] can be passed to the -// variation_settings() method of ScalerBuilder. -impl From<&'_ Setting> for Setting { - fn from(value: &'_ Setting) -> Self { - *value - } -} - -impl From<(Tag, T)> for Setting { - fn from(s: (Tag, T)) -> Self { - Self { - selector: s.0, - value: s.1, - } - } -} - -impl From<&(Tag, T)> for Setting { - fn from(s: &(Tag, T)) -> Self { - Self { - selector: s.0, - value: s.1, - } - } -} - -impl From<(&str, T)> for Setting { - fn from(s: (&str, T)) -> Self { - Self { - selector: Tag::from_str(s.0).unwrap_or_default(), - value: s.1, - } - } -} - -impl From<&(&str, T)> for Setting { - fn from(s: &(&str, T)) -> Self { - Self { - selector: Tag::from_str(s.0).unwrap_or_default(), - value: s.1, - } - } -} - -/// Type for specifying a variation axis setting in user coordinates. -/// -/// The `selector` field should contain a tag that corresponds to a -/// variation axis while the `value` field specifies the desired position -/// on the axis in user coordinates (i.e. within the range defined by -/// the minimum and maximum values of the axis). -/// -/// # Example -/// ``` -/// use skrifa::{Tag, setting::VariationSetting}; -/// -/// // For convenience, a conversion from (&str, f32) is provided. -/// let slightly_bolder: VariationSetting = ("wght", 720.0).into(); -/// -/// assert_eq!(slightly_bolder, VariationSetting::new(Tag::new(b"wght"), 720.0)); -/// ``` -pub type VariationSetting = Setting; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,649 +0,0 @@ -//! Localized strings describing font names and other metadata. -//! -//! This provides higher level interfaces for accessing the data in the -//! OpenType [name](https://learn.microsoft.com/en-us/typography/opentype/spec/name) -//! table. -//! -//! # Example -//! The following function will print all localized strings from the set -//! of predefined identifiers in a font: -//! ``` -//! use skrifa::{string::StringId, MetadataProvider}; -//! -//! fn print_well_known_strings<'a>(font: &impl MetadataProvider<'a>) { -//! for id in StringId::predefined() { -//! let strings = font.localized_strings(id); -//! if strings.clone().next().is_some() { -//! println!("[{:?}]", id); -//! for string in font.localized_strings(id) { -//! println!("{:?} {}", string.language(), string.to_string()); -//! } -//! } -//! } -//! } -//! ``` - -use read_fonts::{ - tables::name::{CharIter, Name, NameRecord, NameString}, - TableProvider, -}; - -use core::fmt; - -#[doc(inline)] -pub use read_fonts::types::NameId as StringId; - -/// Iterator over the characters of a string. -#[derive(Clone)] -pub struct Chars<'a> { - inner: Option>, -} - -impl Iterator for Chars<'_> { - type Item = char; - - fn next(&mut self) -> Option { - self.inner.as_mut()?.next() - } -} - -/// Iterator over a collection of localized strings for a specific identifier. -#[derive(Clone)] -pub struct LocalizedStrings<'a> { - name: Option>, - records: core::slice::Iter<'a, NameRecord>, - id: StringId, -} - -impl<'a> LocalizedStrings<'a> { - /// Creates a new localized string iterator from the given font and string identifier. - pub fn new(font: &impl TableProvider<'a>, id: StringId) -> Self { - let name = font.name().ok(); - let records = name - .as_ref() - .map(|name| name.name_record().iter()) - .unwrap_or([].iter()); - Self { name, records, id } - } - - /// Returns the informational string identifier for this iterator. - pub fn id(&self) -> StringId { - self.id - } - - /// Returns the best available English string or the first string in the sequence. - /// - /// This prefers the following languages, in order: "en-US", "en", - /// "" (empty, for bare Unicode platform strings which don't have an associated - /// language). - /// - /// If none of these are found, returns the first string, or `None` if the sequence - /// is empty. - pub fn english_or_first(self) -> Option> { - let mut best_rank = -1; - let mut best_string = None; - for (i, string) in self.enumerate() { - let rank = match (i, string.language()) { - (_, Some("en-US")) => return Some(string), - (_, Some("en")) => 2, - (_, None) => 1, - (0, _) => 0, - _ => continue, - }; - if rank > best_rank { - best_rank = rank; - best_string = Some(string); - } - } - best_string - } -} - -impl<'a> Iterator for LocalizedStrings<'a> { - type Item = LocalizedString<'a>; - - fn next(&mut self) -> Option { - let name = self.name.as_ref()?; - loop { - let record = self.records.next()?; - if record.name_id() == self.id { - return Some(LocalizedString::new(name, record)); - } - } - } -} - -impl Default for LocalizedStrings<'_> { - fn default() -> Self { - Self { - name: None, - records: [].iter(), - id: StringId::default(), - } - } -} - -/// String containing a name or other font metadata in a specific language. -#[derive(Clone, Debug)] -pub struct LocalizedString<'a> { - language: Option, - value: Option>, -} - -impl<'a> LocalizedString<'a> { - fn new(name: &Name<'a>, record: &NameRecord) -> Self { - let language = Language::new(name, record); - let value = record.string(name.string_data()).ok(); - Self { language, value } - } - - /// Returns the BCP-47 language identifier for the localized string. - pub fn language(&self) -> Option<&str> { - self.language.as_ref().map(|language| language.as_str()) - } - - /// Returns an iterator over the characters of the localized string. - pub fn chars(&self) -> Chars<'a> { - Chars { - inner: self.value.map(|value| value.chars()), - } - } -} - -impl fmt::Display for LocalizedString<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - for ch in self.chars() { - ch.fmt(f)?; - } - Ok(()) - } -} - -/// This value is chosen arbitrarily to accommodate common language tags that -/// are almost always <= 11 bytes (LLL-SSSS-RR where L is primary language, S -/// is script and R is region) and to keep the Language enum at a reasonable -/// 32 bytes in size. -const MAX_INLINE_LANGUAGE_LEN: usize = 30; - -#[derive(Copy, Clone, Debug)] -#[repr(u8)] -enum Language { - Inline { - buf: [u8; MAX_INLINE_LANGUAGE_LEN], - len: u8, - }, - Static(&'static str), -} - -impl Language { - fn new(name: &Name, record: &NameRecord) -> Option { - let language_id = record.language_id(); - // For version 1 name tables, prefer language tags: - // https://learn.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-1 - const BASE_LANGUAGE_TAG_ID: u16 = 0x8000; - if name.version() == 1 && language_id >= BASE_LANGUAGE_TAG_ID { - let index = (language_id - BASE_LANGUAGE_TAG_ID) as usize; - let language_string = name - .lang_tag_record()? - .get(index)? - .lang_tag(name.string_data()) - .ok()?; - Self::from_name_string(&language_string) - } else { - match record.platform_id() { - // We only match Macintosh and Windows language ids. - 1 | 3 => Self::from_language_id(language_id), - _ => None, - } - } - } - - /// Decodes a language tag string into an inline ASCII byte sequence. - fn from_name_string(s: &NameString) -> Option { - let mut buf = [0u8; MAX_INLINE_LANGUAGE_LEN]; - let mut len = 0; - for ch in s.chars() { - // From "Tags for Identifying Languages" : - // "Although [RFC5234] refers to octets, the language tags described in - // this document are sequences of characters from the US-ASCII [ISO646] - // repertoire" - // Therefore we assume that non-ASCII characters signal an invalid language tag. - if !ch.is_ascii() || len == MAX_INLINE_LANGUAGE_LEN { - return None; - } - buf[len] = ch as u8; - len += 1; - } - Some(Self::Inline { - buf, - len: len as u8, - }) - } - - fn from_language_id(language_id: u16) -> Option { - Some(Self::Static(language_id_to_bcp47(language_id)?)) - } - - fn as_str(&self) -> &str { - match self { - Self::Inline { buf: data, len } => { - let data = &data[..*len as usize]; - core::str::from_utf8(data).unwrap_or_default() - } - Self::Static(str) => str, - } - } -} - -/// Converts an OpenType language identifier to a BCP-47 language tag. -fn language_id_to_bcp47(language_id: u16) -> Option<&'static str> { - match LANGUAGE_ID_TO_BCP47.binary_search_by(|entry| entry.0.cmp(&language_id)) { - Ok(ix) => LANGUAGE_ID_TO_BCP47.get(ix).map(|entry| entry.1), - _ => None, - } -} - -/// Mapping of OpenType name table language identifier to BCP-47 language tag. -/// Borrowed from Skia: -const LANGUAGE_ID_TO_BCP47: &[(u16, &str)] = &[ - /* A mapping from Mac Language Designators to BCP 47 codes. - * The following list was constructed more or less manually. - * Apple now uses BCP 47 (post OSX10.4), so there will be no new entries. - */ - (0, "en"), //English - (1, "fr"), //French - (2, "de"), //German - (3, "it"), //Italian - (4, "nl"), //Dutch - (5, "sv"), //Swedish - (6, "es"), //Spanish - (7, "da"), //Danish - (8, "pt"), //Portuguese - (9, "nb"), //Norwegian - (10, "he"), //Hebrew - (11, "ja"), //Japanese - (12, "ar"), //Arabic - (13, "fi"), //Finnish - (14, "el"), //Greek - (15, "is"), //Icelandic - (16, "mt"), //Maltese - (17, "tr"), //Turkish - (18, "hr"), //Croatian - (19, "zh-Hant"), //Chinese (Traditional) - (20, "ur"), //Urdu - (21, "hi"), //Hindi - (22, "th"), //Thai - (23, "ko"), //Korean - (24, "lt"), //Lithuanian - (25, "pl"), //Polish - (26, "hu"), //Hungarian - (27, "et"), //Estonian - (28, "lv"), //Latvian - (29, "se"), //Sami - (30, "fo"), //Faroese - (31, "fa"), //Farsi (Persian) - (32, "ru"), //Russian - (33, "zh-Hans"), //Chinese (Simplified) - (34, "nl"), //Dutch - (35, "ga"), //Irish(Gaelic) - (36, "sq"), //Albanian - (37, "ro"), //Romanian - (38, "cs"), //Czech - (39, "sk"), //Slovak - (40, "sl"), //Slovenian - (41, "yi"), //Yiddish - (42, "sr"), //Serbian - (43, "mk"), //Macedonian - (44, "bg"), //Bulgarian - (45, "uk"), //Ukrainian - (46, "be"), //Byelorussian - (47, "uz"), //Uzbek - (48, "kk"), //Kazakh - (49, "az-Cyrl"), //Azerbaijani (Cyrillic) - (50, "az-Arab"), //Azerbaijani (Arabic) - (51, "hy"), //Armenian - (52, "ka"), //Georgian - (53, "mo"), //Moldavian - (54, "ky"), //Kirghiz - (55, "tg"), //Tajiki - (56, "tk"), //Turkmen - (57, "mn-Mong"), //Mongolian (Traditional) - (58, "mn-Cyrl"), //Mongolian (Cyrillic) - (59, "ps"), //Pashto - (60, "ku"), //Kurdish - (61, "ks"), //Kashmiri - (62, "sd"), //Sindhi - (63, "bo"), //Tibetan - (64, "ne"), //Nepali - (65, "sa"), //Sanskrit - (66, "mr"), //Marathi - (67, "bn"), //Bengali - (68, "as"), //Assamese - (69, "gu"), //Gujarati - (70, "pa"), //Punjabi - (71, "or"), //Oriya - (72, "ml"), //Malayalam - (73, "kn"), //Kannada - (74, "ta"), //Tamil - (75, "te"), //Telugu - (76, "si"), //Sinhalese - (77, "my"), //Burmese - (78, "km"), //Khmer - (79, "lo"), //Lao - (80, "vi"), //Vietnamese - (81, "id"), //Indonesian - (82, "tl"), //Tagalog - (83, "ms-Latn"), //Malay (Roman) - (84, "ms-Arab"), //Malay (Arabic) - (85, "am"), //Amharic - (86, "ti"), //Tigrinya - (87, "om"), //Oromo - (88, "so"), //Somali - (89, "sw"), //Swahili - (90, "rw"), //Kinyarwanda/Ruanda - (91, "rn"), //Rundi - (92, "ny"), //Nyanja/Chewa - (93, "mg"), //Malagasy - (94, "eo"), //Esperanto - (128, "cy"), //Welsh - (129, "eu"), //Basque - (130, "ca"), //Catalan - (131, "la"), //Latin - (132, "qu"), //Quechua - (133, "gn"), //Guarani - (134, "ay"), //Aymara - (135, "tt"), //Tatar - (136, "ug"), //Uighur - (137, "dz"), //Dzongkha - (138, "jv-Latn"), //Javanese (Roman) - (139, "su-Latn"), //Sundanese (Roman) - (140, "gl"), //Galician - (141, "af"), //Afrikaans - (142, "br"), //Breton - (143, "iu"), //Inuktitut - (144, "gd"), //Scottish (Gaelic) - (145, "gv"), //Manx (Gaelic) - (146, "ga"), //Irish (Gaelic with Lenition) - (147, "to"), //Tongan - (148, "el"), //Greek (Polytonic) Note: ISO 15924 does not have an equivalent script name. - (149, "kl"), //Greenlandic - (150, "az-Latn"), //Azerbaijani (Roman) - (151, "nn"), //Nynorsk - /* A mapping from Windows LCID to BCP 47 codes. - * This list is the sorted, curated output of tools/win_lcid.cpp. - * Note that these are sorted by value for quick binary lookup, and not logically by lsb. - * The 'bare' language ids (e.g. 0x0001 for Arabic) are omitted - * as they do not appear as valid language ids in the OpenType specification. - */ - (0x0401, "ar-SA"), //Arabic - (0x0402, "bg-BG"), //Bulgarian - (0x0403, "ca-ES"), //Catalan - (0x0404, "zh-TW"), //Chinese (Traditional) - (0x0405, "cs-CZ"), //Czech - (0x0406, "da-DK"), //Danish - (0x0407, "de-DE"), //German - (0x0408, "el-GR"), //Greek - (0x0409, "en-US"), //English - (0x040a, "es-ES_tradnl"), //Spanish - (0x040b, "fi-FI"), //Finnish - (0x040c, "fr-FR"), //French - (0x040d, "he-IL"), //Hebrew - (0x040d, "he"), //Hebrew - (0x040e, "hu-HU"), //Hungarian - (0x040e, "hu"), //Hungarian - (0x040f, "is-IS"), //Icelandic - (0x0410, "it-IT"), //Italian - (0x0411, "ja-JP"), //Japanese - (0x0412, "ko-KR"), //Korean - (0x0413, "nl-NL"), //Dutch - (0x0414, "nb-NO"), //Norwegian (Bokmål) - (0x0415, "pl-PL"), //Polish - (0x0416, "pt-BR"), //Portuguese - (0x0417, "rm-CH"), //Romansh - (0x0418, "ro-RO"), //Romanian - (0x0419, "ru-RU"), //Russian - (0x041a, "hr-HR"), //Croatian - (0x041b, "sk-SK"), //Slovak - (0x041c, "sq-AL"), //Albanian - (0x041d, "sv-SE"), //Swedish - (0x041e, "th-TH"), //Thai - (0x041f, "tr-TR"), //Turkish - (0x0420, "ur-PK"), //Urdu - (0x0421, "id-ID"), //Indonesian - (0x0422, "uk-UA"), //Ukrainian - (0x0423, "be-BY"), //Belarusian - (0x0424, "sl-SI"), //Slovenian - (0x0425, "et-EE"), //Estonian - (0x0426, "lv-LV"), //Latvian - (0x0427, "lt-LT"), //Lithuanian - (0x0428, "tg-Cyrl-TJ"), //Tajik (Cyrillic) - (0x0429, "fa-IR"), //Persian - (0x042a, "vi-VN"), //Vietnamese - (0x042b, "hy-AM"), //Armenian - (0x042c, "az-Latn-AZ"), //Azeri (Latin) - (0x042d, "eu-ES"), //Basque - (0x042e, "hsb-DE"), //Upper Sorbian - (0x042f, "mk-MK"), //Macedonian (FYROM) - (0x0432, "tn-ZA"), //Setswana - (0x0434, "xh-ZA"), //isiXhosa - (0x0435, "zu-ZA"), //isiZulu - (0x0436, "af-ZA"), //Afrikaans - (0x0437, "ka-GE"), //Georgian - (0x0438, "fo-FO"), //Faroese - (0x0439, "hi-IN"), //Hindi - (0x043a, "mt-MT"), //Maltese - (0x043b, "se-NO"), //Sami (Northern) - (0x043e, "ms-MY"), //Malay - (0x043f, "kk-KZ"), //Kazakh - (0x0440, "ky-KG"), //Kyrgyz - (0x0441, "sw-KE"), //Kiswahili - (0x0442, "tk-TM"), //Turkmen - (0x0443, "uz-Latn-UZ"), //Uzbek (Latin) - (0x0443, "uz"), //Uzbek - (0x0444, "tt-RU"), //Tatar - (0x0445, "bn-IN"), //Bengali - (0x0446, "pa-IN"), //Punjabi - (0x0447, "gu-IN"), //Gujarati - (0x0448, "or-IN"), //Oriya - (0x0449, "ta-IN"), //Tamil - (0x044a, "te-IN"), //Telugu - (0x044b, "kn-IN"), //Kannada - (0x044c, "ml-IN"), //Malayalam - (0x044d, "as-IN"), //Assamese - (0x044e, "mr-IN"), //Marathi - (0x044f, "sa-IN"), //Sanskrit - (0x0450, "mn-Cyrl"), //Mongolian (Cyrillic) - (0x0451, "bo-CN"), //Tibetan - (0x0452, "cy-GB"), //Welsh - (0x0453, "km-KH"), //Khmer - (0x0454, "lo-LA"), //Lao - (0x0456, "gl-ES"), //Galician - (0x0457, "kok-IN"), //Konkani - (0x045a, "syr-SY"), //Syriac - (0x045b, "si-LK"), //Sinhala - (0x045d, "iu-Cans-CA"), //Inuktitut (Syllabics) - (0x045e, "am-ET"), //Amharic - (0x0461, "ne-NP"), //Nepali - (0x0462, "fy-NL"), //Frisian - (0x0463, "ps-AF"), //Pashto - (0x0464, "fil-PH"), //Filipino - (0x0465, "dv-MV"), //Divehi - (0x0468, "ha-Latn-NG"), //Hausa (Latin) - (0x046a, "yo-NG"), //Yoruba - (0x046b, "quz-BO"), //Quechua - (0x046c, "nso-ZA"), //Sesotho sa Leboa - (0x046d, "ba-RU"), //Bashkir - (0x046e, "lb-LU"), //Luxembourgish - (0x046f, "kl-GL"), //Greenlandic - (0x0470, "ig-NG"), //Igbo - (0x0478, "ii-CN"), //Yi - (0x047a, "arn-CL"), //Mapudungun - (0x047c, "moh-CA"), //Mohawk - (0x047e, "br-FR"), //Breton - (0x0480, "ug-CN"), //Uyghur - (0x0481, "mi-NZ"), //Maori - (0x0482, "oc-FR"), //Occitan - (0x0483, "co-FR"), //Corsican - (0x0484, "gsw-FR"), //Alsatian - (0x0485, "sah-RU"), //Yakut - (0x0486, "qut-GT"), //K'iche - (0x0487, "rw-RW"), //Kinyarwanda - (0x0488, "wo-SN"), //Wolof - (0x048c, "prs-AF"), //Dari - (0x0491, "gd-GB"), //Scottish Gaelic - (0x0801, "ar-IQ"), //Arabic - (0x0804, "zh-Hans"), //Chinese (Simplified) - (0x0807, "de-CH"), //German - (0x0809, "en-GB"), //English - (0x080a, "es-MX"), //Spanish - (0x080c, "fr-BE"), //French - (0x0810, "it-CH"), //Italian - (0x0813, "nl-BE"), //Dutch - (0x0814, "nn-NO"), //Norwegian (Nynorsk) - (0x0816, "pt-PT"), //Portuguese - (0x081a, "sr-Latn-CS"), //Serbian (Latin) - (0x081d, "sv-FI"), //Swedish - (0x082c, "az-Cyrl-AZ"), //Azeri (Cyrillic) - (0x082e, "dsb-DE"), //Lower Sorbian - (0x082e, "dsb"), //Lower Sorbian - (0x083b, "se-SE"), //Sami (Northern) - (0x083c, "ga-IE"), //Irish - (0x083e, "ms-BN"), //Malay - (0x0843, "uz-Cyrl-UZ"), //Uzbek (Cyrillic) - (0x0845, "bn-BD"), //Bengali - (0x0850, "mn-Mong-CN"), //Mongolian (Traditional Mongolian) - (0x085d, "iu-Latn-CA"), //Inuktitut (Latin) - (0x085f, "tzm-Latn-DZ"), //Tamazight (Latin) - (0x086b, "quz-EC"), //Quechua - (0x0c01, "ar-EG"), //Arabic - (0x0c04, "zh-Hant"), //Chinese (Traditional) - (0x0c07, "de-AT"), //German - (0x0c09, "en-AU"), //English - (0x0c0a, "es-ES"), //Spanish - (0x0c0c, "fr-CA"), //French - (0x0c1a, "sr-Cyrl-CS"), //Serbian (Cyrillic) - (0x0c3b, "se-FI"), //Sami (Northern) - (0x0c6b, "quz-PE"), //Quechua - (0x1001, "ar-LY"), //Arabic - (0x1004, "zh-SG"), //Chinese (Simplified) - (0x1007, "de-LU"), //German - (0x1009, "en-CA"), //English - (0x100a, "es-GT"), //Spanish - (0x100c, "fr-CH"), //French - (0x101a, "hr-BA"), //Croatian (Latin) - (0x103b, "smj-NO"), //Sami (Lule) - (0x1401, "ar-DZ"), //Arabic - (0x1404, "zh-MO"), //Chinese (Traditional) - (0x1407, "de-LI"), //German - (0x1409, "en-NZ"), //English - (0x140a, "es-CR"), //Spanish - (0x140c, "fr-LU"), //French - (0x141a, "bs-Latn-BA"), //Bosnian (Latin) - (0x141a, "bs"), //Bosnian - (0x143b, "smj-SE"), //Sami (Lule) - (0x143b, "smj"), //Sami (Lule) - (0x1801, "ar-MA"), //Arabic - (0x1809, "en-IE"), //English - (0x180a, "es-PA"), //Spanish - (0x180c, "fr-MC"), //French - (0x181a, "sr-Latn-BA"), //Serbian (Latin) - (0x183b, "sma-NO"), //Sami (Southern) - (0x1c01, "ar-TN"), //Arabic - (0x1c09, "en-ZA"), //English - (0x1c0a, "es-DO"), //Spanish - (0x1c1a, "sr-Cyrl-BA"), //Serbian (Cyrillic) - (0x1c3b, "sma-SE"), //Sami (Southern) - (0x1c3b, "sma"), //Sami (Southern) - (0x2001, "ar-OM"), //Arabic - (0x2009, "en-JM"), //English - (0x200a, "es-VE"), //Spanish - (0x201a, "bs-Cyrl-BA"), //Bosnian (Cyrillic) - (0x201a, "bs-Cyrl"), //Bosnian (Cyrillic) - (0x203b, "sms-FI"), //Sami (Skolt) - (0x203b, "sms"), //Sami (Skolt) - (0x2401, "ar-YE"), //Arabic - (0x2409, "en-029"), //English - (0x240a, "es-CO"), //Spanish - (0x241a, "sr-Latn-RS"), //Serbian (Latin) - (0x243b, "smn-FI"), //Sami (Inari) - (0x2801, "ar-SY"), //Arabic - (0x2809, "en-BZ"), //English - (0x280a, "es-PE"), //Spanish - (0x281a, "sr-Cyrl-RS"), //Serbian (Cyrillic) - (0x2c01, "ar-JO"), //Arabic - (0x2c09, "en-TT"), //English - (0x2c0a, "es-AR"), //Spanish - (0x2c1a, "sr-Latn-ME"), //Serbian (Latin) - (0x3001, "ar-LB"), //Arabic - (0x3009, "en-ZW"), //English - (0x300a, "es-EC"), //Spanish - (0x301a, "sr-Cyrl-ME"), //Serbian (Cyrillic) - (0x3401, "ar-KW"), //Arabic - (0x3409, "en-PH"), //English - (0x340a, "es-CL"), //Spanish - (0x3801, "ar-AE"), //Arabic - (0x380a, "es-UY"), //Spanish - (0x3c01, "ar-BH"), //Arabic - (0x3c0a, "es-PY"), //Spanish - (0x4001, "ar-QA"), //Arabic - (0x4009, "en-IN"), //English - (0x400a, "es-BO"), //Spanish - (0x4409, "en-MY"), //English - (0x440a, "es-SV"), //Spanish - (0x4809, "en-SG"), //English - (0x480a, "es-HN"), //Spanish - (0x4c0a, "es-NI"), //Spanish - (0x500a, "es-PR"), //Spanish - (0x540a, "es-US"), //Spanish -]; - -#[cfg(test)] -mod tests { - use crate::MetadataProvider; - - use super::*; - use read_fonts::FontRef; - - #[test] - fn localized() { - let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); - let mut subfamily_names = font - .localized_strings(StringId::SUBFAMILY_NAME) - .map(|s| (s.language().unwrap().to_string(), s.to_string())) - .collect::>(); - subfamily_names.sort_by(|a, b| a.0.cmp(&b.0)); - let expected = [ - (String::from("ar-SA"), String::from("عادي")), - (String::from("el-GR"), String::from("Κανονικά")), - (String::from("en"), String::from("Regular")), - (String::from("eu-ES"), String::from("Arrunta")), - (String::from("pl-PL"), String::from("Normalny")), - (String::from("zh-Hans"), String::from("正常")), - ]; - assert_eq!(subfamily_names.as_slice(), expected); - } - - #[test] - fn find_by_language() { - let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); - assert_eq!( - font.localized_strings(StringId::SUBFAMILY_NAME) - .find(|s| s.language() == Some("pl-PL")) - .unwrap() - .to_string(), - "Normalny" - ); - } - - #[test] - fn english_or_first() { - let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); - assert_eq!( - font.localized_strings(StringId::SUBFAMILY_NAME) - .english_or_first() - .unwrap() - .to_string(), - "Regular" - ); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,519 +0,0 @@ -//! Axes of variation in a variable font. - -use read_fonts::{ - tables::avar::Avar, - tables::fvar::{self, Fvar}, - types::{Fixed, Tag}, - TableProvider, -}; - -use crate::{ - collections::SmallVec, - instance::{Location, NormalizedCoord}, - setting::VariationSetting, - string::StringId, -}; - -/// Axis of variation in a variable font. -/// -/// In variable fonts, an axis usually refers to a single aspect of a -/// typeface's design that can be altered by the user. -/// -/// See -#[derive(Clone)] -pub struct Axis { - index: usize, - record: fvar::VariationAxisRecord, -} - -impl Axis { - /// Returns the tag that identifies the axis. - pub fn tag(&self) -> Tag { - self.record.axis_tag() - } - - /// Returns the index of the axis in its owning collection. - pub fn index(&self) -> usize { - self.index - } - - /// Returns the localized string identifier for the name of the axis. - pub fn name_id(&self) -> StringId { - self.record.axis_name_id() - } - - /// Returns true if the axis should be hidden in user interfaces. - pub fn is_hidden(&self) -> bool { - const AXIS_HIDDEN_FLAG: u16 = 0x1; - self.record.flags() & AXIS_HIDDEN_FLAG != 0 - } - - /// Returns the minimum value of the axis. - pub fn min_value(&self) -> f32 { - self.record.min_value().to_f64() as _ - } - - /// Returns the default value of the axis. - pub fn default_value(&self) -> f32 { - self.record.default_value().to_f64() as _ - } - - /// Returns the maximum value of the axis. - pub fn max_value(&self) -> f32 { - self.record.max_value().to_f64() as _ - } - - /// Returns a normalized coordinate for the given user coordinate. - /// - /// The value will be clamped to the range specified by the minimum - /// and maximum values. - /// - /// This does not apply any axis variation remapping. - pub fn normalize(&self, coord: f32) -> NormalizedCoord { - self.record - .normalize(Fixed::from_f64(coord as _)) - .to_f2dot14() - } -} - -/// Collection of axes in a variable font. -/// -/// Converts user ([fvar](https://learn.microsoft.com/en-us/typography/opentype/spec/fvar)) -/// locations to normalized locations. See [`Self::location`]. -/// -/// See the [`Axis`] type for more detail. -#[derive(Clone)] -pub struct AxisCollection<'a> { - fvar: Option>, - avar: Option>, -} - -impl<'a> AxisCollection<'a> { - /// Creates a new axis collection from the given font. - pub fn new(font: &impl TableProvider<'a>) -> Self { - let fvar = font.fvar().ok(); - let avar = font.avar().ok(); - Self { fvar, avar } - } - - /// Returns the number of variation axes in the font. - pub fn len(&self) -> usize { - self.fvar - .as_ref() - .map(|fvar| fvar.axis_count() as usize) - .unwrap_or(0) - } - - /// Returns true if the collection is empty. - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Returns the axis at the given index. - pub fn get(&self, index: usize) -> Option { - let record = *self.fvar.as_ref()?.axes().ok()?.get(index)?; - Some(Axis { index, record }) - } - - /// Returns the axis with the given tag. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// let opsz = Tag::new(b"opsz"); - /// assert_eq!(font.axes().get_by_tag(opsz).unwrap().tag(), opsz); - /// # } - /// ``` - pub fn get_by_tag(&self, tag: Tag) -> Option { - self.iter().find(|axis| axis.tag() == tag) - } - - /// Given an iterator of variation settings in user space, computes an - /// ordered sequence of normalized coordinates. - /// - /// * Setting selectors that don't match an axis are ignored. - /// * Setting values are clamped to the range of their associated axis - /// before normalization. - /// * If more than one setting for an axis is provided, the last one is - /// used. - /// * Omitted settings are set to 0.0, representing the default position - /// in variation space. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// let location = font.axes().location([("wght", 250.0), ("wdth", 75.0)]); - /// # } - /// ``` - pub fn location(&self, settings: I) -> Location - where - I: IntoIterator, - I::Item: Into, - { - let mut location = Location::new(self.len()); - self.location_to_slice(settings, location.coords_mut()); - location - } - - /// Given an iterator of variation settings in user space, computes an - /// ordered sequence of normalized coordinates and stores them in the - /// target slice. - /// - /// * Setting selectors that don't match an axis are ignored. - /// * Setting values are clamped to the range of their associated axis - /// before normalization. - /// * If more than one setting for an axis is provided, the last one is - /// used. - /// * If no setting for an axis is provided, the associated coordinate is - /// set to the normalized value 0.0, representing the default position - /// in variation space. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// let axes = font.axes(); - /// let mut location = vec![NormalizedCoord::default(); axes.len()]; - /// axes.location_to_slice([("wght", 250.0), ("wdth", 75.0)], &mut location); - /// # } - /// ``` - pub fn location_to_slice(&self, settings: I, location: &mut [NormalizedCoord]) - where - I: IntoIterator, - I::Item: Into, - { - if let Some(fvar) = self.fvar.as_ref() { - fvar.user_to_normalized( - self.avar.as_ref(), - settings - .into_iter() - .map(|setting| setting.into()) - .map(|setting| (setting.selector, Fixed::from_f64(setting.value as f64))), - location, - ); - } else { - location.fill(NormalizedCoord::default()); - } - } - - /// Given an iterator of variation settings in user space, returns a - /// new iterator yielding those settings that are valid for this axis - /// collection. - /// - /// * Setting selectors that don't match an axis are dropped. - /// * If more than one setting for an axis is provided, the last one is - /// retained. - /// * Setting values are clamped to the range of their associated axis. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// // Assuming a font contains a single "wght" (weight) axis with range - /// // 100-900: - /// let axes = font.axes(); - /// let filtered: Vec<_> = axes - /// .filter([("wght", 400.0), ("opsz", 100.0), ("wght", 1200.0)]) - /// .collect(); - /// // The first "wght" and "opsz" settings are dropped and the final - /// // "wght" axis is clamped to the maximum value of 900. - /// assert_eq!(&filtered, &[("wght", 900.0).into()]); - /// # } - /// ``` - pub fn filter(&self, settings: I) -> impl Iterator + Clone - where - I: IntoIterator, - I::Item: Into, - { - #[derive(Copy, Clone, Default)] - struct Entry { - tag: Tag, - min: f32, - max: f32, - value: f32, - present: bool, - } - let mut results = SmallVec::<_, 8>::with_len(self.len(), Entry::default()); - for (axis, result) in self.iter().zip(results.as_mut_slice()) { - result.tag = axis.tag(); - result.min = axis.min_value(); - result.max = axis.max_value(); - result.value = axis.default_value(); - } - for setting in settings { - let setting = setting.into(); - for entry in results.as_mut_slice() { - if entry.tag == setting.selector { - entry.value = setting.value.max(entry.min).min(entry.max); - entry.present = true; - } - } - } - results - .into_iter() - .filter(|entry| entry.present) - .map(|entry| VariationSetting::new(entry.tag, entry.value)) - } - - /// Returns an iterator over the axes in the collection. - pub fn iter(&self) -> impl Iterator + 'a + Clone { - let copy = self.clone(); - (0..self.len()).filter_map(move |i| copy.get(i)) - } -} - -/// Named instance of a variation. -/// -/// A set of fixed axis positions selected by the type designer and assigned a -/// name. -/// -/// See -#[derive(Clone)] -pub struct NamedInstance<'a> { - axes: AxisCollection<'a>, - record: fvar::InstanceRecord<'a>, -} - -impl<'a> NamedInstance<'a> { - /// Returns the string identifier for the subfamily name of the instance. - pub fn subfamily_name_id(&self) -> StringId { - self.record.subfamily_name_id - } - - /// Returns the string identifier for the PostScript name of the instance. - pub fn postscript_name_id(&self) -> Option { - self.record.post_script_name_id - } - - /// Returns an iterator over the ordered sequence of user space coordinates - /// that define the instance, one coordinate per axis. - pub fn user_coords(&self) -> impl Iterator + 'a + Clone { - self.record - .coordinates - .iter() - .map(|coord| coord.get().to_f64() as _) - } - - /// Computes a location in normalized variation space for this instance. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// let location = font.named_instances().get(0).unwrap().location(); - /// # } - /// ``` - pub fn location(&self) -> Location { - let mut location = Location::new(self.axes.len()); - self.location_to_slice(location.coords_mut()); - location - } - - /// Computes a location in normalized variation space for this instance and - /// stores the result in the given slice. - /// - /// # Examples - /// - /// ```rust - /// # use skrifa::prelude::*; - /// # fn wrapper(font: &FontRef) { - /// let instance = font.named_instances().get(0).unwrap(); - /// let mut location = vec![NormalizedCoord::default(); instance.user_coords().count()]; - /// instance.location_to_slice(&mut location); - /// # } - /// ``` - pub fn location_to_slice(&self, location: &mut [NormalizedCoord]) { - let settings = self - .axes - .iter() - .map(|axis| axis.tag()) - .zip(self.user_coords()); - self.axes.location_to_slice(settings, location); - } -} - -/// Collection of named instances in a variable font. -/// -/// See the [`NamedInstance`] type for more detail. -#[derive(Clone)] -pub struct NamedInstanceCollection<'a> { - axes: AxisCollection<'a>, -} - -impl<'a> NamedInstanceCollection<'a> { - /// Creates a new instance collection from the given font. - pub fn new(font: &impl TableProvider<'a>) -> Self { - Self { - axes: AxisCollection::new(font), - } - } - - /// Returns the number of instances in the collection. - pub fn len(&self) -> usize { - self.axes - .fvar - .as_ref() - .map(|fvar| fvar.instance_count() as usize) - .unwrap_or(0) - } - - /// Returns true if the collection is empty. - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - /// Returns the instance at the given index. - pub fn get(&self, index: usize) -> Option> { - let record = self.axes.fvar.as_ref()?.instances().ok()?.get(index).ok()?; - Some(NamedInstance { - axes: self.axes.clone(), - record, - }) - } - - /// Returns an iterator over the instances in the collection. - pub fn iter(&self) -> impl Iterator> + 'a + Clone { - let copy = self.clone(); - (0..self.len()).filter_map(move |i| copy.get(i)) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::MetadataProvider as _; - use font_test_data::VAZIRMATN_VAR; - use read_fonts::FontRef; - use std::str::FromStr; - - #[test] - fn axis() { - let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); - let axis = font.axes().get(0).unwrap(); - assert_eq!(axis.index(), 0); - assert_eq!(axis.tag(), Tag::new(b"wght")); - assert_eq!(axis.min_value(), 100.0); - assert_eq!(axis.default_value(), 400.0); - assert_eq!(axis.max_value(), 900.0); - assert_eq!(axis.name_id(), StringId::new(257)); - assert_eq!( - font.localized_strings(axis.name_id()) - .english_or_first() - .unwrap() - .to_string(), - "Weight" - ); - } - - #[test] - fn named_instances() { - let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); - let named_instances = font.named_instances(); - let thin = named_instances.get(0).unwrap(); - assert_eq!(thin.subfamily_name_id(), StringId::new(258)); - assert_eq!( - font.localized_strings(thin.subfamily_name_id()) - .english_or_first() - .unwrap() - .to_string(), - "Thin" - ); - assert_eq!(thin.location().coords(), &[NormalizedCoord::from_f32(-1.0)]); - let regular = named_instances.get(3).unwrap(); - assert_eq!(regular.subfamily_name_id(), StringId::new(261)); - assert_eq!( - font.localized_strings(regular.subfamily_name_id()) - .english_or_first() - .unwrap() - .to_string(), - "Regular" - ); - assert_eq!( - regular.location().coords(), - &[NormalizedCoord::from_f32(0.0)] - ); - let bold = named_instances.get(6).unwrap(); - assert_eq!(bold.subfamily_name_id(), StringId::new(264)); - assert_eq!( - font.localized_strings(bold.subfamily_name_id()) - .english_or_first() - .unwrap() - .to_string(), - "Bold" - ); - assert_eq!( - bold.location().coords(), - &[NormalizedCoord::from_f32(0.6776123)] - ); - } - - #[test] - fn location() { - let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); - let axes = font.axes(); - let axis = axes.get_by_tag(Tag::from_str("wght").unwrap()).unwrap(); - assert_eq!( - axes.location([("wght", -1000.0)]).coords(), - &[NormalizedCoord::from_f32(-1.0)] - ); - assert_eq!( - axes.location([("wght", 100.0)]).coords(), - &[NormalizedCoord::from_f32(-1.0)] - ); - assert_eq!( - axes.location([("wght", 200.0)]).coords(), - &[NormalizedCoord::from_f32(-0.5)] - ); - assert_eq!( - axes.location([("wght", 400.0)]).coords(), - &[NormalizedCoord::from_f32(0.0)] - ); - // avar table maps 0.8 to 0.83875 - assert_eq!( - axes.location(&[( - "wght", - axis.default_value() + (axis.max_value() - axis.default_value()) * 0.8, - )]) - .coords(), - &[NormalizedCoord::from_f32(0.83875)] - ); - assert_eq!( - axes.location([("wght", 900.0)]).coords(), - &[NormalizedCoord::from_f32(1.0)] - ); - assert_eq!( - axes.location([("wght", 1251.5)]).coords(), - &[NormalizedCoord::from_f32(1.0)] - ); - } - - #[test] - fn filter() { - let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); - // This font contains one wght axis with the range 100-900 and default - // value of 400. - let axes = font.axes(); - // Drop axes that are not present in the font - let drop_missing: Vec<_> = axes.filter(&[("slnt", 25.0), ("wdth", 50.0)]).collect(); - assert_eq!(&drop_missing, &[]); - // Clamp an out of range value - let clamp: Vec<_> = axes.filter(&[("wght", 50.0)]).collect(); - assert_eq!(&clamp, &[("wght", 100.0).into()]); - // Combination of the above two: drop the missing axis and clamp out of range value - let drop_missing_and_clamp: Vec<_> = - axes.filter(&[("slnt", 25.0), ("wght", 1000.0)]).collect(); - assert_eq!(&drop_missing_and_clamp, &[("wght", 900.0).into()]); - // Ensure we take the later value in the case of duplicates - let drop_duplicate_and_missing: Vec<_> = axes - .filter(&[("wght", 400.0), ("opsz", 100.0), ("wght", 120.5)]) - .collect(); - assert_eq!(&drop_duplicate_and_missing, &[("wght", 120.5).into()]); - } -} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo-checksum.json chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo-checksum.json --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo-checksum.json 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo-checksum.json 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1 @@ +{"files":{}} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo_vcs_info.json chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo_vcs_info.json --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/.cargo_vcs_info.json 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "0ecc7ac2105be5a44e7d973291f767b35581670e" + }, + "path_in_vcs": "skrifa" +} \ No newline at end of file diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/Cargo.toml chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/Cargo.toml --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/Cargo.toml 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,88 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "skrifa" +version = "0.26.6" +build = false +autolib = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Metadata reader and glyph scaler for OpenType fonts." +readme = "README.md" +categories = [ + "text-processing", + "parsing", + "graphics", +] +license = "MIT OR Apache-2.0" +repository = "https://github.com/googlefonts/fontations" + +[package.metadata.docs.rs] +all-features = true + +[lib] +name = "skrifa" +path = "src/lib.rs" + +[dependencies.bytemuck] +version = "1.13.1" + +[dependencies.core_maths] +version = "0.1" +optional = true + +[dependencies.read-fonts] +version = "0.25.3" +default-features = false + +[dev-dependencies.kurbo] +version = "0.11.0" + +[dev-dependencies.pretty_assertions] +version = "1.3.0" + +[dev-dependencies.read-fonts] +version = "0.25.3" +features = [ + "scaler_test", + "serde", +] +default-features = false + +[dev-dependencies.serde] +version = "1.0" + +[dev-dependencies.serde_json] +version = "1.0" + +[dev-dependencies.write-fonts] +version = "0.33.1" + +[features] +autohint_shaping = [] +default = [ + "autohint_shaping", + "traversal", +] +libm = [ + "dep:core_maths", + "read-fonts/libm", +] +spec_next = ["read-fonts/spec_next"] +std = ["read-fonts/std"] +traversal = [ + "std", + "read-fonts/experimental_traverse", +] diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1 @@ +../LICENSE-APACHE \ No newline at end of file diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-MIT chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-MIT --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-MIT 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-MIT 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1 @@ +../LICENSE-MIT \ No newline at end of file diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/README.md chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/README.md --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/README.md 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/README.md 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,62 @@ +# skrifa + +[![Crates.io](https://img.shields.io/crates/v/skrifa.svg)](https://crates.io/crates/skrifa) +[![Docs](https://docs.rs/skrifa/badge.svg)](https://docs.rs/skrifa) +[![MIT/Apache 2.0](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](#license) + +This crate aims to be a robust, ergonomic, high performance library for reading +OpenType fonts. It is built on top of the +[read-fonts](https://github.com/googlefonts/fontations/tree/main/read-fonts) +low level parsing library and is also part of the +[oxidize](https://github.com/googlefonts/oxidize) project. + +## Features + +### Metadata + +The following information is currently exposed: + +* Global font metrics with variation support (units per em, ascender, +descender, etc) +* Glyph metrics with variation support (advance width, left side-bearing, etc) +* Codepoint to nominal glyph identifier mapping + * Unicode variation sequences +* Localized strings +* Attributes (stretch, style and weight) +* Variation axes and named instances + * Conversion from user coordinates to normalized design coordinates + +Future goals include: + +* Color palettes +* Embedded bitmap strikes + +### Glyph formats + +| Source | Decoding | Variations | Hinting | +|--------|----------|------------|---------| +| glyf | ✔️ | ✔️ | ✔️ | +| CFF | ✔️ | - | ✔️ | +| CFF2 | ✔️ | ✔️ | ✔️ | +| COLRv0 | ✔️ | - | - | +| COLRv1 | ✔️ | ✔️ | - | +| EBDT | ✔️* | - | - | +| CBDT | ✔️* | - | - | +| sbix | ✔️* | - | - | + +\* Raw support available through the `read-fonts` crate. + +## Panicking + +This library should not panic regardless of API misuse or use of +corrupted/malicious font files. Please file an issue if this occurs. + +## The name? + +Following along with our theme, *skrifa* is Old Norse for "write" or "it is +written." And so it is named. + +## Safety + +Unsafe code is forbidden by a `#![forbid(unsafe_code)]` attribute in the root +of the library. diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/generated/generated_autohint_styles.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/generated/generated_autohint_styles.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/generated/generated_autohint_styles.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/generated/generated_autohint_styles.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1440 @@ +// THIS FILE IS AUTOGENERATED. +// Any changes to this file will be overwritten. +// Use ../scripts/gen_autohint_scripts.py to regenerate. + +#[rustfmt::skip] +pub(super) const SCRIPT_CLASSES: &[ScriptClass] = &[ + ScriptClass { + name: "Adlam", + group: ScriptGroup::Default, + tag: Tag::new(b"Adlm"), + hint_top_to_bottom: false, + std_chars: "𞤌 𞤮", + blues: &[ + ("𞤌 𞤅 𞤈 𞤏 𞤔 𞤚", BlueZones::TOP), + ("𞤂 𞤖", BlueZones::NONE), + ("𞤬 𞤮 𞤻 𞤼 𞤾", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Arabic", + group: ScriptGroup::Default, + tag: Tag::new(b"Arab"), + hint_top_to_bottom: false, + std_chars: "ل ح ـ", + blues: &[ + ("ا إ ل ك ط ظ", BlueZones::TOP), + ("ت ث ط ظ ك", BlueZones::NONE), + ("ـ", BlueZones::NEUTRAL), + ], + }, + ScriptClass { + name: "Armenian", + group: ScriptGroup::Default, + tag: Tag::new(b"Armn"), + hint_top_to_bottom: false, + std_chars: "ս Ս", + blues: &[ + ("Ա Մ Ւ Ս Բ Գ Դ Օ", BlueZones::TOP), + ("Ւ Ո Դ Ճ Շ Ս Տ Օ", BlueZones::NONE), + ("ե է ի մ վ ֆ ճ", BlueZones::TOP), + ("ա յ ւ ս գ շ ր օ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("հ ո ճ ա ե ծ ս օ", BlueZones::NONE), + ("բ ը ի լ ղ պ փ ց", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Avestan", + group: ScriptGroup::Default, + tag: Tag::new(b"Avst"), + hint_top_to_bottom: false, + std_chars: "𐬚", + blues: &[ + ("𐬀 𐬁 𐬐 𐬛", BlueZones::TOP), + ("𐬀 𐬁", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Bamum", + group: ScriptGroup::Default, + tag: Tag::new(b"Bamu"), + hint_top_to_bottom: false, + std_chars: "ꛁ ꛯ", + blues: &[ + ("ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ", BlueZones::TOP), + ("ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Bengali", + group: ScriptGroup::Default, + tag: Tag::new(b"Beng"), + hint_top_to_bottom: true, + std_chars: "০ ৪", + blues: &[ + ("ই ট ঠ ি ী ৈ ৗ", BlueZones::TOP), + ("ও এ ড ত ন ব ল ক", BlueZones::TOP), + ("অ ড ত ন ব ভ ল ক", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), + ("অ ড ত ন ব ভ ল ক", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Buhid", + group: ScriptGroup::Default, + tag: Tag::new(b"Buhd"), + hint_top_to_bottom: false, + std_chars: "ᝋ ᝏ", + blues: &[ + ("ᝐ ᝈ", BlueZones::TOP), + ("ᝅ ᝊ ᝎ", BlueZones::TOP), + ("ᝂ ᝃ ᝉ ᝌ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Chakma", + group: ScriptGroup::Default, + tag: Tag::new(b"Cakm"), + hint_top_to_bottom: false, + std_chars: "𑄤 𑄉 𑄛", + blues: &[ + ("𑄃 𑄅 𑄉 𑄙 𑄗", BlueZones::TOP), + ("𑄅 𑄛 𑄝 𑄗 𑄓", BlueZones::NONE), + ("𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Canadian Syllabics", + group: ScriptGroup::Default, + tag: Tag::new(b"Cans"), + hint_top_to_bottom: false, + std_chars: "ᑌ ᓚ", + blues: &[ + ("ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ", BlueZones::TOP), + ("ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ", BlueZones::NONE), + ("ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ", BlueZones::NONE), + ("ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ", BlueZones::TOP), + ("ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Carian", + group: ScriptGroup::Default, + tag: Tag::new(b"Cari"), + hint_top_to_bottom: false, + std_chars: "𐊫 𐋉", + blues: &[ + ("𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿", BlueZones::TOP), + ("𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Cherokee", + group: ScriptGroup::Default, + tag: Tag::new(b"Cher"), + hint_top_to_bottom: false, + std_chars: "Ꭴ Ꮕ ꮕ", + blues: &[ + ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", BlueZones::TOP), + ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", BlueZones::NONE), + ("ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ", BlueZones::TOP), + ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", BlueZones::NONE), + ("ᏸ ꮐ ꭹ ꭻ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Coptic", + group: ScriptGroup::Default, + tag: Tag::new(b"Copt"), + hint_top_to_bottom: false, + std_chars: "Ⲟ ⲟ", + blues: &[ + ("Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ", BlueZones::TOP), + ("Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ", BlueZones::NONE), + ("ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Cypriot", + group: ScriptGroup::Default, + tag: Tag::new(b"Cprt"), + hint_top_to_bottom: false, + std_chars: "𐠅 𐠣", + blues: &[ + ("𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦", BlueZones::TOP), + ("𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐", BlueZones::NONE), + ("𐠈 𐠏 𐠖", BlueZones::TOP), + ("𐠈 𐠏 𐠖", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Cyrillic", + group: ScriptGroup::Default, + tag: Tag::new(b"Cyrl"), + hint_top_to_bottom: false, + std_chars: "о О", + blues: &[ + ("Б В Е П З О С Э", BlueZones::TOP), + ("Б В Е Ш З О С Э", BlueZones::NONE), + ("х п н ш е з о с", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("х п н ш е з о с", BlueZones::NONE), + ("р у ф", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Devanagari", + group: ScriptGroup::Default, + tag: Tag::new(b"Deva"), + hint_top_to_bottom: true, + std_chars: "ठ व ट", + blues: &[ + ("ई ऐ ओ औ ि ी ो ौ", BlueZones::TOP), + ("क म अ आ थ ध भ श", BlueZones::TOP), + ("क न म उ छ ट ठ ड", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), + ("क न म उ छ ट ठ ड", BlueZones::NONE), + ("ु ृ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Deseret", + group: ScriptGroup::Default, + tag: Tag::new(b"Dsrt"), + hint_top_to_bottom: false, + std_chars: "𐐄 𐐬", + blues: &[ + ("𐐂 𐐄 𐐋 𐐗 𐐑", BlueZones::TOP), + ("𐐀 𐐂 𐐄 𐐗 𐐛", BlueZones::NONE), + ("𐐪 𐐬 𐐳 𐐿 𐐹", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("𐐨 𐐪 𐐬 𐐿 𐑃", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Ethiopic", + group: ScriptGroup::Default, + tag: Tag::new(b"Ethi"), + hint_top_to_bottom: false, + std_chars: "ዐ", + blues: &[ + ("ሀ ሃ ዘ ፐ ማ በ ዋ ዐ", BlueZones::TOP), + ("ለ ሐ በ ዘ ሀ ሪ ዐ ጨ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Georgian (Mkhedruli)", + group: ScriptGroup::Default, + tag: Tag::new(b"Geor"), + hint_top_to_bottom: false, + std_chars: "ი ე ა Ჿ", + blues: &[ + ("გ დ ე ვ თ ი ო ღ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ა ზ მ ს შ ძ ხ პ", BlueZones::NONE), + ("ს ხ ქ ზ მ შ ჩ წ", BlueZones::TOP), + ("ე ვ ჟ ტ უ ფ ქ ყ", BlueZones::NONE), + ("Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ", BlueZones::TOP), + ("Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Georgian (Khutsuri)", + group: ScriptGroup::Default, + tag: Tag::new(b"Geok"), + hint_top_to_bottom: false, + std_chars: "Ⴖ Ⴑ ⴙ", + blues: &[ + ("Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ", BlueZones::TOP), + ("Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ", BlueZones::NONE), + ("ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ", BlueZones::NONE), + ("ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ", BlueZones::TOP), + ("ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Glagolitic", + group: ScriptGroup::Default, + tag: Tag::new(b"Glag"), + hint_top_to_bottom: false, + std_chars: "Ⱅ ⱅ", + blues: &[ + ("Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ", BlueZones::TOP), + ("Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ", BlueZones::NONE), + ("ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Gothic", + group: ScriptGroup::Default, + tag: Tag::new(b"Goth"), + hint_top_to_bottom: true, + std_chars: "𐌴 𐌾 𐍃", + blues: &[ + ("𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾", BlueZones::TOP), + ("𐌶 𐌴 𐍃 𐍈", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Greek", + group: ScriptGroup::Default, + tag: Tag::new(b"Grek"), + hint_top_to_bottom: false, + std_chars: "ο Ο", + blues: &[ + ("Γ Β Ε Ζ Θ Ο Ω", BlueZones::TOP), + ("Β Δ Ζ Ξ Θ Ο", BlueZones::NONE), + ("β θ δ ζ λ ξ", BlueZones::TOP), + ("α ε ι ο π σ τ ω", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("α ε ι ο π σ τ ω", BlueZones::NONE), + ("β γ η μ ρ φ χ ψ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Gujarati", + group: ScriptGroup::Default, + tag: Tag::new(b"Gujr"), + hint_top_to_bottom: false, + std_chars: "ટ ૦", + blues: &[ + ("ત ન ઋ ઌ છ ટ ર ૦", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ખ ગ ઘ ઞ ઇ ઈ ઠ જ", BlueZones::NONE), + ("ઈ ઊ િ ી લી શ્ચિ જિ સી", BlueZones::TOP), + ("ુ ૃ ૄ ખુ છૃ છૄ", BlueZones::NONE), + ("૦ ૧ ૨ ૩ ૭", BlueZones::TOP), + ], + }, + ScriptClass { + name: "Gurmukhi", + group: ScriptGroup::Default, + tag: Tag::new(b"Guru"), + hint_top_to_bottom: true, + std_chars: "ਠ ਰ ੦", + blues: &[ + ("ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ", BlueZones::TOP), + ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", BlueZones::TOP), + ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", BlueZones::TOP.union(BlueZones::NEUTRAL).union(BlueZones::X_HEIGHT)), + ("ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ", BlueZones::NONE), + ("੦ ੧ ੨ ੩ ੭", BlueZones::TOP), + ], + }, + ScriptClass { + name: "Hebrew", + group: ScriptGroup::Default, + tag: Tag::new(b"Hebr"), + hint_top_to_bottom: false, + std_chars: "ם", + blues: &[ + ("ב ד ה ח ך כ ם ס", BlueZones::TOP.union(BlueZones::LONG)), + ("ב ט כ ם ס צ", BlueZones::NONE), + ("ק ך ן ף ץ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Kayah Li", + group: ScriptGroup::Default, + tag: Tag::new(b"Kali"), + hint_top_to_bottom: false, + std_chars: "ꤍ ꤀", + blues: &[ + ("꤅ ꤏ ꤁ ꤋ ꤀ ꤍ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("꤈ ꤘ ꤀ ꤍ ꤢ", BlueZones::NONE), + ("ꤖ ꤡ", BlueZones::TOP), + ("ꤑ ꤜ ꤞ", BlueZones::NONE), + ("ꤑ꤬ ꤜ꤭ ꤔ꤬", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Khmer", + group: ScriptGroup::Default, + tag: Tag::new(b"Khmr"), + hint_top_to_bottom: false, + std_chars: "០", + blues: &[ + ("ខ ទ ន ឧ ឩ ា", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ក្ក ក្ខ ក្គ ក្ថ", BlueZones::SUB_TOP), + ("ខ ឃ ច ឋ ប ម យ ឲ", BlueZones::NONE), + ("ត្រ រៀ ឲ្យ អឿ", BlueZones::NONE), + ("ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Khmer Symbols", + group: ScriptGroup::Default, + tag: Tag::new(b"Khms"), + hint_top_to_bottom: false, + std_chars: "᧡ ᧪", + blues: &[ + ("᧠ ᧡", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("᧶ ᧹", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Kannada", + group: ScriptGroup::Default, + tag: Tag::new(b"Knda"), + hint_top_to_bottom: false, + std_chars: "೦ ಬ", + blues: &[ + ("ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ", BlueZones::TOP), + ("ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Lao", + group: ScriptGroup::Default, + tag: Tag::new(b"Laoo"), + hint_top_to_bottom: false, + std_chars: "໐", + blues: &[ + ("າ ດ ອ ມ ລ ວ ຣ ງ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("າ ອ ບ ຍ ຣ ຮ ວ ຢ", BlueZones::NONE), + ("ປ ຢ ຟ ຝ", BlueZones::TOP), + ("ໂ ໄ ໃ", BlueZones::TOP), + ("ງ ຊ ຖ ຽ ໆ ຯ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Latin", + group: ScriptGroup::Default, + tag: Tag::new(b"Latn"), + hint_top_to_bottom: false, + std_chars: "o O 0", + blues: &[ + ("T H E Z O C Q S", BlueZones::TOP), + ("H E Z L O C U S", BlueZones::NONE), + ("f i j k d b h", BlueZones::TOP), + ("u v x z o e s c", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("n r x z o e s c", BlueZones::NONE), + ("p q g j y", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Latin Subscript Fallback", + group: ScriptGroup::Default, + tag: Tag::new(b"Latb"), + hint_top_to_bottom: false, + std_chars: "ₒ ₀", + blues: &[ + ("₀ ₃ ₅ ₇ ₈", BlueZones::TOP), + ("₀ ₁ ₂ ₃ ₈", BlueZones::NONE), + ("ᵢ ⱼ ₕ ₖ ₗ", BlueZones::TOP), + ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", BlueZones::NONE), + ("ᵦ ᵧ ᵨ ᵩ ₚ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Latin Superscript Fallback", + group: ScriptGroup::Default, + tag: Tag::new(b"Latp"), + hint_top_to_bottom: false, + std_chars: "ᵒ ᴼ ⁰", + blues: &[ + ("⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ", BlueZones::TOP), + ("⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ", BlueZones::NONE), + ("ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ", BlueZones::TOP), + ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", BlueZones::NONE), + ("ᵖ ʸ ᵍ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Lisu", + group: ScriptGroup::Default, + tag: Tag::new(b"Lisu"), + hint_top_to_bottom: false, + std_chars: "ꓳ", + blues: &[ + ("ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ", BlueZones::TOP), + ("ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Malayalam", + group: ScriptGroup::Default, + tag: Tag::new(b"Mlym"), + hint_top_to_bottom: false, + std_chars: "ഠ റ", + blues: &[ + ("ഒ ട ഠ റ ച പ ച്ച പ്പ", BlueZones::TOP), + ("ട ഠ ധ ശ ഘ ച ഥ ല", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Medefaidrin", + group: ScriptGroup::Default, + tag: Tag::new(b"Medf"), + hint_top_to_bottom: false, + std_chars: "𖹡 𖹛 𖹯", + blues: &[ + ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟", BlueZones::TOP), + ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓", BlueZones::NONE), + ("𖹤 𖹬 𖹧 𖹴 𖹶 𖹾", BlueZones::TOP), + ("𖹠 𖹡 𖹢 𖹹 𖹳 𖹮", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("𖹠 𖹡 𖹢 𖹳 𖹭 𖹽", BlueZones::NONE), + ("𖹥 𖹨 𖹩", BlueZones::NONE), + ("𖺀 𖺅 𖺈 𖺄 𖺍", BlueZones::TOP), + ], + }, + ScriptClass { + name: "Mongolian", + group: ScriptGroup::Default, + tag: Tag::new(b"Mong"), + hint_top_to_bottom: true, + std_chars: "ᡂ ᠪ", + blues: &[ + ("ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍", BlueZones::TOP), + ("ᡃ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Myanmar", + group: ScriptGroup::Default, + tag: Tag::new(b"Mymr"), + hint_top_to_bottom: false, + std_chars: "ဝ င ဂ", + blues: &[ + ("ခ ဂ င ဒ ဝ ၥ ၊ ။", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("င ဎ ဒ ပ ဗ ဝ ၊ ။", BlueZones::NONE), + ("ဩ ြ ၍ ၏ ၆ ါ ိ", BlueZones::TOP), + ("ဉ ည ဥ ဩ ဨ ၂ ၅ ၉", BlueZones::NONE), + ], + }, + ScriptClass { + name: "N'Ko", + group: ScriptGroup::Default, + tag: Tag::new(b"Nkoo"), + hint_top_to_bottom: false, + std_chars: "ߋ ߀", + blues: &[ + ("ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ", BlueZones::TOP), + ("߀ ߘ ߡ ߠ ߥ", BlueZones::NONE), + ("ߏ ߛ ߋ", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("ߎ ߏ ߛ ߋ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "no script", + group: ScriptGroup::Default, + tag: Tag::new(b"None"), + hint_top_to_bottom: false, + std_chars: "", + blues: &[], + }, + ScriptClass { + name: "Ol Chiki", + group: ScriptGroup::Default, + tag: Tag::new(b"Olck"), + hint_top_to_bottom: false, + std_chars: "ᱛ", + blues: &[ + ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", BlueZones::TOP), + ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Old Turkic", + group: ScriptGroup::Default, + tag: Tag::new(b"Orkh"), + hint_top_to_bottom: false, + std_chars: "𐰗", + blues: &[ + ("𐰗 𐰘 𐰧", BlueZones::TOP), + ("𐰉 𐰗 𐰦 𐰧", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Osage", + group: ScriptGroup::Default, + tag: Tag::new(b"Osge"), + hint_top_to_bottom: false, + std_chars: "𐓂 𐓪", + blues: &[ + ("𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆", BlueZones::TOP), + ("𐒰 𐓍 𐓂 𐒿 𐓎 𐒹", BlueZones::NONE), + ("𐒼 𐒽 𐒾", BlueZones::NONE), + ("𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶", BlueZones::NONE), + ("𐓤 𐓦 𐓸 𐓹 𐓛", BlueZones::TOP), + ("𐓤 𐓥 𐓦", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Osmanya", + group: ScriptGroup::Default, + tag: Tag::new(b"Osma"), + hint_top_to_bottom: false, + std_chars: "𐒆 𐒠", + blues: &[ + ("𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣", BlueZones::TOP), + ("𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Hanifi Rohingya", + group: ScriptGroup::Default, + tag: Tag::new(b"Rohg"), + hint_top_to_bottom: false, + std_chars: "𐴰", + blues: &[ + ("𐴃 𐴀 𐴆 𐴖 𐴕", BlueZones::TOP), + ("𐴔 𐴖 𐴕 𐴑 𐴐", BlueZones::NONE), + ("ـ", BlueZones::NEUTRAL), + ], + }, + ScriptClass { + name: "Saurashtra", + group: ScriptGroup::Default, + tag: Tag::new(b"Saur"), + hint_top_to_bottom: false, + std_chars: "ꢝ ꣐", + blues: &[ + ("ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ", BlueZones::TOP), + ("ꢂ ꢨ ꢺ ꢤ ꢎ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Shavian", + group: ScriptGroup::Default, + tag: Tag::new(b"Shaw"), + hint_top_to_bottom: false, + std_chars: "𐑴", + blues: &[ + ("𐑕 𐑙", BlueZones::TOP), + ("𐑔 𐑖 𐑗 𐑹 𐑻", BlueZones::NONE), + ("𐑟 𐑣", BlueZones::NONE), + ("𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("𐑴 𐑻 𐑹", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Sinhala", + group: ScriptGroup::Default, + tag: Tag::new(b"Sinh"), + hint_top_to_bottom: false, + std_chars: "ට", + blues: &[ + ("ඉ ක ඝ ඳ ප ය ල ෆ", BlueZones::TOP), + ("එ ඔ ඝ ජ ට ථ ධ ර", BlueZones::NONE), + ("ද ඳ උ ල තූ තු බු දු", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Sundanese", + group: ScriptGroup::Default, + tag: Tag::new(b"Sund"), + hint_top_to_bottom: false, + std_chars: "᮰", + blues: &[ + ("ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ", BlueZones::TOP), + ("ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ", BlueZones::NONE), + ("ᮼ ᳄", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Tamil", + group: ScriptGroup::Default, + tag: Tag::new(b"Taml"), + hint_top_to_bottom: false, + std_chars: "௦", + blues: &[ + ("உ ஒ ஓ ற ஈ க ங ச", BlueZones::TOP), + ("க ச ல ஶ உ ங ட ப", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Tai Viet", + group: ScriptGroup::Default, + tag: Tag::new(b"Tavt"), + hint_top_to_bottom: false, + std_chars: "ꪒ ꪫ", + blues: &[ + ("ꪆ ꪔ ꪒ ꪖ ꪫ", BlueZones::TOP), + ("ꪉ ꪫ ꪮ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Telugu", + group: ScriptGroup::Default, + tag: Tag::new(b"Telu"), + hint_top_to_bottom: false, + std_chars: "౦ ౧", + blues: &[ + ("ఇ ఌ ఙ ఞ ణ ఱ ౯", BlueZones::TOP), + ("అ క చ ర ఽ ౨ ౬", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Tifinagh", + group: ScriptGroup::Default, + tag: Tag::new(b"Tfng"), + hint_top_to_bottom: false, + std_chars: "ⵔ", + blues: &[ + ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", BlueZones::TOP), + ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Thai", + group: ScriptGroup::Default, + tag: Tag::new(b"Thai"), + hint_top_to_bottom: false, + std_chars: "า ๅ ๐", + blues: &[ + ("บ เ แ อ ก า", BlueZones::TOP.union(BlueZones::X_HEIGHT)), + ("บ ป ษ ฯ อ ย ฮ", BlueZones::NONE), + ("ป ฝ ฟ", BlueZones::TOP), + ("โ ใ ไ", BlueZones::TOP), + ("ฎ ฏ ฤ ฦ", BlueZones::NONE), + ("ญ ฐ", BlueZones::NONE), + ("๐ ๑ ๓", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Vai", + group: ScriptGroup::Default, + tag: Tag::new(b"Vaii"), + hint_top_to_bottom: false, + std_chars: "ꘓ ꖜ ꖴ", + blues: &[ + ("ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ", BlueZones::TOP), + ("ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ", BlueZones::NONE), + ], + }, + ScriptClass { + name: "Limbu", + group: ScriptGroup::Indic, + tag: Tag::new(b"Limb"), + hint_top_to_bottom: false, + std_chars: "o", + blues: &[], + }, + ScriptClass { + name: "Oriya", + group: ScriptGroup::Indic, + tag: Tag::new(b"Orya"), + hint_top_to_bottom: false, + std_chars: "o", + blues: &[], + }, + ScriptClass { + name: "Syloti Nagri", + group: ScriptGroup::Indic, + tag: Tag::new(b"Sylo"), + hint_top_to_bottom: false, + std_chars: "o", + blues: &[], + }, + ScriptClass { + name: "Tibetan", + group: ScriptGroup::Indic, + tag: Tag::new(b"Tibt"), + hint_top_to_bottom: false, + std_chars: "o", + blues: &[], + }, + ScriptClass { + name: "CJKV ideographs", + group: ScriptGroup::Cjk, + tag: Tag::new(b"Hani"), + hint_top_to_bottom: false, + std_chars: "田 囗", + blues: &[ + ("他 们 你 來 們 到 和 地 对 對 就 席 我 时 時 會 来 為 能 舰 說 说 这 這 齊 | 军 同 已 愿 既 星 是 景 民 照 现 現 理 用 置 要 軍 那 配 里 開 雷 露 面 顾", BlueZones::TOP), + ("个 为 人 他 以 们 你 來 個 們 到 和 大 对 對 就 我 时 時 有 来 為 要 說 说 | 主 些 因 它 想 意 理 生 當 看 着 置 者 自 著 裡 过 还 进 進 過 道 還 里 面", BlueZones::NONE), + (" 些 们 你 來 們 到 和 地 她 将 將 就 年 得 情 最 样 樣 理 能 說 说 这 這 通 | 即 吗 吧 听 呢 品 响 嗎 师 師 收 断 斷 明 眼 間 间 际 陈 限 除 陳 随 際 隨", BlueZones::HORIZONTAL), + ("事 前 學 将 將 情 想 或 政 斯 新 样 樣 民 沒 没 然 特 现 現 球 第 經 谁 起 | 例 別 别 制 动 動 吗 嗎 增 指 明 朝 期 构 物 确 种 調 调 費 费 那 都 間 间", BlueZones::HORIZONTAL.union(BlueZones::RIGHT)), + ], + }, +]; + +#[allow(unused)]impl ScriptClass { + pub const ADLM: usize = 0; + pub const ARAB: usize = 1; + pub const ARMN: usize = 2; + pub const AVST: usize = 3; + pub const BAMU: usize = 4; + pub const BENG: usize = 5; + pub const BUHD: usize = 6; + pub const CAKM: usize = 7; + pub const CANS: usize = 8; + pub const CARI: usize = 9; + pub const CHER: usize = 10; + pub const COPT: usize = 11; + pub const CPRT: usize = 12; + pub const CYRL: usize = 13; + pub const DEVA: usize = 14; + pub const DSRT: usize = 15; + pub const ETHI: usize = 16; + pub const GEOR: usize = 17; + pub const GEOK: usize = 18; + pub const GLAG: usize = 19; + pub const GOTH: usize = 20; + pub const GREK: usize = 21; + pub const GUJR: usize = 22; + pub const GURU: usize = 23; + pub const HEBR: usize = 24; + pub const KALI: usize = 25; + pub const KHMR: usize = 26; + pub const KHMS: usize = 27; + pub const KNDA: usize = 28; + pub const LAOO: usize = 29; + pub const LATN: usize = 30; + pub const LATB: usize = 31; + pub const LATP: usize = 32; + pub const LISU: usize = 33; + pub const MLYM: usize = 34; + pub const MEDF: usize = 35; + pub const MONG: usize = 36; + pub const MYMR: usize = 37; + pub const NKOO: usize = 38; + pub const NONE: usize = 39; + pub const OLCK: usize = 40; + pub const ORKH: usize = 41; + pub const OSGE: usize = 42; + pub const OSMA: usize = 43; + pub const ROHG: usize = 44; + pub const SAUR: usize = 45; + pub const SHAW: usize = 46; + pub const SINH: usize = 47; + pub const SUND: usize = 48; + pub const TAML: usize = 49; + pub const TAVT: usize = 50; + pub const TELU: usize = 51; + pub const TFNG: usize = 52; + pub const THAI: usize = 53; + pub const VAII: usize = 54; + pub const LIMB: usize = 55; + pub const ORYA: usize = 56; + pub const SYLO: usize = 57; + pub const TIBT: usize = 58; + pub const HANI: usize = 59; +} + +#[rustfmt::skip] +pub(super) const STYLE_CLASSES: &[StyleClass] = &[ + StyleClass { name: "Adlam", index: 0, script: &SCRIPT_CLASSES[0], feature: None }, + StyleClass { name: "Arabic", index: 1, script: &SCRIPT_CLASSES[1], feature: None }, + StyleClass { name: "Armenian", index: 2, script: &SCRIPT_CLASSES[2], feature: None }, + StyleClass { name: "Avestan", index: 3, script: &SCRIPT_CLASSES[3], feature: None }, + StyleClass { name: "Bamum", index: 4, script: &SCRIPT_CLASSES[4], feature: None }, + StyleClass { name: "Bengali", index: 5, script: &SCRIPT_CLASSES[5], feature: None }, + StyleClass { name: "Buhid", index: 6, script: &SCRIPT_CLASSES[6], feature: None }, + StyleClass { name: "Chakma", index: 7, script: &SCRIPT_CLASSES[7], feature: None }, + StyleClass { name: "Canadian Syllabics", index: 8, script: &SCRIPT_CLASSES[8], feature: None }, + StyleClass { name: "Carian", index: 9, script: &SCRIPT_CLASSES[9], feature: None }, + StyleClass { name: "Cherokee", index: 10, script: &SCRIPT_CLASSES[10], feature: None }, + StyleClass { name: "Coptic", index: 11, script: &SCRIPT_CLASSES[11], feature: None }, + StyleClass { name: "Cypriot", index: 12, script: &SCRIPT_CLASSES[12], feature: None }, + StyleClass { name: "Cyrillic petite capitals from capitals", index: 13, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"c2cp")) }, + StyleClass { name: "Cyrillic small capitals from capitals", index: 14, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"c2sc")) }, + StyleClass { name: "Cyrillic ordinals", index: 15, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"ordn")) }, + StyleClass { name: "Cyrillic petite capitals", index: 16, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"pcap")) }, + StyleClass { name: "Cyrillic ruby", index: 17, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"ruby")) }, + StyleClass { name: "Cyrillic scientific inferiors", index: 18, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"sinf")) }, + StyleClass { name: "Cyrillic small capitals", index: 19, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"smcp")) }, + StyleClass { name: "Cyrillic subscript", index: 20, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"subs")) }, + StyleClass { name: "Cyrillic superscript", index: 21, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"sups")) }, + StyleClass { name: "Cyrillic titling", index: 22, script: &SCRIPT_CLASSES[13], feature: Some(Tag::new(b"titl")) }, + StyleClass { name: "Cyrillic", index: 23, script: &SCRIPT_CLASSES[13], feature: None }, + StyleClass { name: "Devanagari", index: 24, script: &SCRIPT_CLASSES[14], feature: None }, + StyleClass { name: "Deseret", index: 25, script: &SCRIPT_CLASSES[15], feature: None }, + StyleClass { name: "Ethiopic", index: 26, script: &SCRIPT_CLASSES[16], feature: None }, + StyleClass { name: "Georgian (Mkhedruli)", index: 27, script: &SCRIPT_CLASSES[17], feature: None }, + StyleClass { name: "Georgian (Khutsuri)", index: 28, script: &SCRIPT_CLASSES[18], feature: None }, + StyleClass { name: "Glagolitic", index: 29, script: &SCRIPT_CLASSES[19], feature: None }, + StyleClass { name: "Gothic", index: 30, script: &SCRIPT_CLASSES[20], feature: None }, + StyleClass { name: "Greek petite capitals from capitals", index: 31, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"c2cp")) }, + StyleClass { name: "Greek small capitals from capitals", index: 32, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"c2sc")) }, + StyleClass { name: "Greek ordinals", index: 33, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"ordn")) }, + StyleClass { name: "Greek petite capitals", index: 34, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"pcap")) }, + StyleClass { name: "Greek ruby", index: 35, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"ruby")) }, + StyleClass { name: "Greek scientific inferiors", index: 36, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"sinf")) }, + StyleClass { name: "Greek small capitals", index: 37, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"smcp")) }, + StyleClass { name: "Greek subscript", index: 38, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"subs")) }, + StyleClass { name: "Greek superscript", index: 39, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"sups")) }, + StyleClass { name: "Greek titling", index: 40, script: &SCRIPT_CLASSES[21], feature: Some(Tag::new(b"titl")) }, + StyleClass { name: "Greek", index: 41, script: &SCRIPT_CLASSES[21], feature: None }, + StyleClass { name: "Gujarati", index: 42, script: &SCRIPT_CLASSES[22], feature: None }, + StyleClass { name: "Gurmukhi", index: 43, script: &SCRIPT_CLASSES[23], feature: None }, + StyleClass { name: "Hebrew", index: 44, script: &SCRIPT_CLASSES[24], feature: None }, + StyleClass { name: "Kayah Li", index: 45, script: &SCRIPT_CLASSES[25], feature: None }, + StyleClass { name: "Khmer", index: 46, script: &SCRIPT_CLASSES[26], feature: None }, + StyleClass { name: "Khmer Symbols", index: 47, script: &SCRIPT_CLASSES[27], feature: None }, + StyleClass { name: "Kannada", index: 48, script: &SCRIPT_CLASSES[28], feature: None }, + StyleClass { name: "Lao", index: 49, script: &SCRIPT_CLASSES[29], feature: None }, + StyleClass { name: "Latin petite capitals from capitals", index: 50, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"c2cp")) }, + StyleClass { name: "Latin small capitals from capitals", index: 51, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"c2sc")) }, + StyleClass { name: "Latin ordinals", index: 52, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"ordn")) }, + StyleClass { name: "Latin petite capitals", index: 53, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"pcap")) }, + StyleClass { name: "Latin ruby", index: 54, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"ruby")) }, + StyleClass { name: "Latin scientific inferiors", index: 55, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"sinf")) }, + StyleClass { name: "Latin small capitals", index: 56, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"smcp")) }, + StyleClass { name: "Latin subscript", index: 57, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"subs")) }, + StyleClass { name: "Latin superscript", index: 58, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"sups")) }, + StyleClass { name: "Latin titling", index: 59, script: &SCRIPT_CLASSES[30], feature: Some(Tag::new(b"titl")) }, + StyleClass { name: "Latin", index: 60, script: &SCRIPT_CLASSES[30], feature: None }, + StyleClass { name: "Latin Subscript Fallback", index: 61, script: &SCRIPT_CLASSES[31], feature: None }, + StyleClass { name: "Latin Superscript Fallback", index: 62, script: &SCRIPT_CLASSES[32], feature: None }, + StyleClass { name: "Lisu", index: 63, script: &SCRIPT_CLASSES[33], feature: None }, + StyleClass { name: "Malayalam", index: 64, script: &SCRIPT_CLASSES[34], feature: None }, + StyleClass { name: "Medefaidrin", index: 65, script: &SCRIPT_CLASSES[35], feature: None }, + StyleClass { name: "Mongolian", index: 66, script: &SCRIPT_CLASSES[36], feature: None }, + StyleClass { name: "Myanmar", index: 67, script: &SCRIPT_CLASSES[37], feature: None }, + StyleClass { name: "N'Ko", index: 68, script: &SCRIPT_CLASSES[38], feature: None }, + StyleClass { name: "no script", index: 69, script: &SCRIPT_CLASSES[39], feature: None }, + StyleClass { name: "Ol Chiki", index: 70, script: &SCRIPT_CLASSES[40], feature: None }, + StyleClass { name: "Old Turkic", index: 71, script: &SCRIPT_CLASSES[41], feature: None }, + StyleClass { name: "Osage", index: 72, script: &SCRIPT_CLASSES[42], feature: None }, + StyleClass { name: "Osmanya", index: 73, script: &SCRIPT_CLASSES[43], feature: None }, + StyleClass { name: "Hanifi Rohingya", index: 74, script: &SCRIPT_CLASSES[44], feature: None }, + StyleClass { name: "Saurashtra", index: 75, script: &SCRIPT_CLASSES[45], feature: None }, + StyleClass { name: "Shavian", index: 76, script: &SCRIPT_CLASSES[46], feature: None }, + StyleClass { name: "Sinhala", index: 77, script: &SCRIPT_CLASSES[47], feature: None }, + StyleClass { name: "Sundanese", index: 78, script: &SCRIPT_CLASSES[48], feature: None }, + StyleClass { name: "Tamil", index: 79, script: &SCRIPT_CLASSES[49], feature: None }, + StyleClass { name: "Tai Viet", index: 80, script: &SCRIPT_CLASSES[50], feature: None }, + StyleClass { name: "Telugu", index: 81, script: &SCRIPT_CLASSES[51], feature: None }, + StyleClass { name: "Tifinagh", index: 82, script: &SCRIPT_CLASSES[52], feature: None }, + StyleClass { name: "Thai", index: 83, script: &SCRIPT_CLASSES[53], feature: None }, + StyleClass { name: "Vai", index: 84, script: &SCRIPT_CLASSES[54], feature: None }, + StyleClass { name: "Limbu", index: 85, script: &SCRIPT_CLASSES[55], feature: None }, + StyleClass { name: "Oriya", index: 86, script: &SCRIPT_CLASSES[56], feature: None }, + StyleClass { name: "Syloti Nagri", index: 87, script: &SCRIPT_CLASSES[57], feature: None }, + StyleClass { name: "Tibetan", index: 88, script: &SCRIPT_CLASSES[58], feature: None }, + StyleClass { name: "CJKV ideographs", index: 89, script: &SCRIPT_CLASSES[59], feature: None }, +]; + +#[allow(unused)]impl StyleClass { + pub const ADLM: usize = 0; + pub const ARAB: usize = 1; + pub const ARMN: usize = 2; + pub const AVST: usize = 3; + pub const BAMU: usize = 4; + pub const BENG: usize = 5; + pub const BUHD: usize = 6; + pub const CAKM: usize = 7; + pub const CANS: usize = 8; + pub const CARI: usize = 9; + pub const CHER: usize = 10; + pub const COPT: usize = 11; + pub const CPRT: usize = 12; + pub const CYRL_C2CP: usize = 13; + pub const CYRL_C2SC: usize = 14; + pub const CYRL_ORDN: usize = 15; + pub const CYRL_PCAP: usize = 16; + pub const CYRL_RUBY: usize = 17; + pub const CYRL_SINF: usize = 18; + pub const CYRL_SMCP: usize = 19; + pub const CYRL_SUBS: usize = 20; + pub const CYRL_SUPS: usize = 21; + pub const CYRL_TITL: usize = 22; + pub const CYRL: usize = 23; + pub const DEVA: usize = 24; + pub const DSRT: usize = 25; + pub const ETHI: usize = 26; + pub const GEOR: usize = 27; + pub const GEOK: usize = 28; + pub const GLAG: usize = 29; + pub const GOTH: usize = 30; + pub const GREK_C2CP: usize = 31; + pub const GREK_C2SC: usize = 32; + pub const GREK_ORDN: usize = 33; + pub const GREK_PCAP: usize = 34; + pub const GREK_RUBY: usize = 35; + pub const GREK_SINF: usize = 36; + pub const GREK_SMCP: usize = 37; + pub const GREK_SUBS: usize = 38; + pub const GREK_SUPS: usize = 39; + pub const GREK_TITL: usize = 40; + pub const GREK: usize = 41; + pub const GUJR: usize = 42; + pub const GURU: usize = 43; + pub const HEBR: usize = 44; + pub const KALI: usize = 45; + pub const KHMR: usize = 46; + pub const KHMS: usize = 47; + pub const KNDA: usize = 48; + pub const LAOO: usize = 49; + pub const LATN_C2CP: usize = 50; + pub const LATN_C2SC: usize = 51; + pub const LATN_ORDN: usize = 52; + pub const LATN_PCAP: usize = 53; + pub const LATN_RUBY: usize = 54; + pub const LATN_SINF: usize = 55; + pub const LATN_SMCP: usize = 56; + pub const LATN_SUBS: usize = 57; + pub const LATN_SUPS: usize = 58; + pub const LATN_TITL: usize = 59; + pub const LATN: usize = 60; + pub const LATB: usize = 61; + pub const LATP: usize = 62; + pub const LISU: usize = 63; + pub const MLYM: usize = 64; + pub const MEDF: usize = 65; + pub const MONG: usize = 66; + pub const MYMR: usize = 67; + pub const NKOO: usize = 68; + pub const NONE: usize = 69; + pub const OLCK: usize = 70; + pub const ORKH: usize = 71; + pub const OSGE: usize = 72; + pub const OSMA: usize = 73; + pub const ROHG: usize = 74; + pub const SAUR: usize = 75; + pub const SHAW: usize = 76; + pub const SINH: usize = 77; + pub const SUND: usize = 78; + pub const TAML: usize = 79; + pub const TAVT: usize = 80; + pub const TELU: usize = 81; + pub const TFNG: usize = 82; + pub const THAI: usize = 83; + pub const VAII: usize = 84; + pub const LIMB: usize = 85; + pub const ORYA: usize = 86; + pub const SYLO: usize = 87; + pub const TIBT: usize = 88; + pub const HANI: usize = 89; +} + +#[rustfmt::skip] +pub(super) const STYLE_RANGES: &[StyleRange] = &[ + base_range(32, 93, 60), + non_base_range(94, 96, 60), + base_range(97, 125, 60), + non_base_range(126, 126, 60), + base_range(127, 127, 60), + base_range(160, 167, 60), + non_base_range(168, 169, 60), + base_range(170, 170, 62), + base_range(171, 173, 60), + non_base_range(174, 176, 60), + base_range(177, 177, 60), + base_range(178, 179, 62), + non_base_range(180, 180, 60), + base_range(181, 183, 60), + non_base_range(184, 184, 60), + base_range(185, 186, 62), + base_range(187, 187, 60), + non_base_range(188, 190, 60), + base_range(191, 687, 60), + base_range(688, 696, 62), + non_base_range(697, 735, 60), + base_range(736, 740, 62), + non_base_range(741, 879, 60), + base_range(880, 889, 41), + non_base_range(890, 890, 41), + base_range(891, 899, 41), + non_base_range(900, 901, 41), + base_range(902, 1023, 41), + base_range(1024, 1154, 23), + non_base_range(1155, 1161, 23), + base_range(1162, 1327, 23), + base_range(1328, 1368, 2), + non_base_range(1369, 1375, 2), + base_range(1376, 1423, 2), + base_range(1424, 1424, 44), + non_base_range(1425, 1471, 44), + base_range(1472, 1472, 44), + non_base_range(1473, 1474, 44), + base_range(1475, 1475, 44), + non_base_range(1476, 1477, 44), + base_range(1478, 1478, 44), + non_base_range(1479, 1479, 44), + base_range(1480, 1535, 44), + non_base_range(1536, 1541, 1), + base_range(1542, 1551, 1), + non_base_range(1552, 1562, 1), + base_range(1563, 1610, 1), + non_base_range(1611, 1631, 1), + base_range(1632, 1647, 1), + non_base_range(1648, 1648, 1), + base_range(1649, 1749, 1), + non_base_range(1750, 1756, 1), + base_range(1757, 1758, 1), + non_base_range(1759, 1764, 1), + base_range(1765, 1766, 1), + non_base_range(1767, 1768, 1), + base_range(1769, 1769, 1), + non_base_range(1770, 1773, 1), + base_range(1774, 1791, 1), + base_range(1872, 2047, 1), + base_range(2208, 2258, 1), + non_base_range(2259, 2303, 1), + non_base_range(2304, 2306, 24), + base_range(2307, 2361, 24), + non_base_range(2362, 2362, 24), + base_range(2363, 2363, 24), + base_range(2365, 2368, 24), + non_base_range(2369, 2376, 24), + base_range(2377, 2380, 24), + non_base_range(2381, 2381, 24), + base_range(2382, 2384, 24), + non_base_range(2387, 2391, 24), + base_range(2392, 2401, 24), + non_base_range(2402, 2403, 24), + base_range(2406, 2431, 24), + base_range(2432, 2432, 5), + non_base_range(2433, 2433, 5), + base_range(2434, 2491, 5), + non_base_range(2492, 2492, 5), + base_range(2493, 2496, 5), + non_base_range(2497, 2500, 5), + base_range(2501, 2508, 5), + non_base_range(2509, 2509, 5), + base_range(2510, 2529, 5), + non_base_range(2530, 2531, 5), + base_range(2532, 2557, 5), + non_base_range(2558, 2558, 5), + base_range(2559, 2559, 5), + base_range(2560, 2560, 43), + non_base_range(2561, 2562, 43), + base_range(2563, 2619, 43), + non_base_range(2620, 2620, 43), + base_range(2621, 2624, 43), + non_base_range(2625, 2641, 43), + base_range(2642, 2671, 43), + non_base_range(2672, 2673, 43), + base_range(2674, 2676, 43), + non_base_range(2677, 2677, 43), + base_range(2678, 2687, 43), + base_range(2688, 2688, 42), + non_base_range(2689, 2690, 42), + base_range(2691, 2747, 42), + non_base_range(2748, 2748, 42), + base_range(2749, 2752, 42), + non_base_range(2753, 2760, 42), + base_range(2761, 2764, 42), + non_base_range(2765, 2765, 42), + base_range(2766, 2785, 42), + non_base_range(2786, 2787, 42), + base_range(2788, 2809, 42), + non_base_range(2810, 2815, 42), + base_range(2816, 2816, 86), + non_base_range(2817, 2818, 86), + base_range(2819, 2875, 86), + non_base_range(2876, 2876, 86), + base_range(2877, 2878, 86), + non_base_range(2879, 2879, 86), + base_range(2880, 2880, 86), + non_base_range(2881, 2884, 86), + base_range(2885, 2892, 86), + non_base_range(2893, 2902, 86), + base_range(2903, 2913, 86), + non_base_range(2914, 2915, 86), + base_range(2916, 2943, 86), + base_range(2944, 2945, 79), + non_base_range(2946, 2946, 79), + base_range(2947, 3007, 79), + non_base_range(3008, 3010, 79), + base_range(3011, 3020, 79), + non_base_range(3021, 3021, 79), + base_range(3022, 3071, 79), + non_base_range(3072, 3072, 81), + base_range(3073, 3075, 81), + non_base_range(3076, 3076, 81), + base_range(3077, 3133, 81), + non_base_range(3134, 3136, 81), + base_range(3137, 3141, 81), + non_base_range(3142, 3158, 81), + base_range(3159, 3169, 81), + non_base_range(3170, 3171, 81), + base_range(3172, 3199, 81), + base_range(3200, 3200, 48), + non_base_range(3201, 3201, 48), + base_range(3202, 3259, 48), + non_base_range(3260, 3260, 48), + base_range(3261, 3262, 48), + non_base_range(3263, 3263, 48), + base_range(3264, 3269, 48), + non_base_range(3270, 3270, 48), + base_range(3271, 3275, 48), + non_base_range(3276, 3277, 48), + base_range(3278, 3297, 48), + non_base_range(3298, 3299, 48), + base_range(3300, 3327, 48), + non_base_range(3328, 3329, 64), + base_range(3330, 3386, 64), + non_base_range(3387, 3388, 64), + base_range(3389, 3404, 64), + non_base_range(3405, 3406, 64), + base_range(3407, 3425, 64), + non_base_range(3426, 3427, 64), + base_range(3428, 3455, 64), + base_range(3456, 3529, 77), + non_base_range(3530, 3530, 77), + base_range(3531, 3537, 77), + non_base_range(3538, 3542, 77), + base_range(3543, 3583, 77), + base_range(3584, 3632, 83), + non_base_range(3633, 3633, 83), + base_range(3634, 3635, 83), + non_base_range(3636, 3642, 83), + base_range(3643, 3654, 83), + non_base_range(3655, 3662, 83), + base_range(3663, 3711, 83), + base_range(3712, 3760, 49), + non_base_range(3761, 3761, 49), + base_range(3762, 3763, 49), + non_base_range(3764, 3772, 49), + base_range(3773, 3783, 49), + non_base_range(3784, 3789, 49), + base_range(3790, 3839, 49), + base_range(3840, 3863, 88), + non_base_range(3864, 3865, 88), + base_range(3866, 3892, 88), + non_base_range(3893, 3893, 88), + base_range(3894, 3894, 88), + non_base_range(3895, 3895, 88), + base_range(3896, 3896, 88), + non_base_range(3897, 3897, 88), + base_range(3898, 3901, 88), + non_base_range(3902, 3903, 88), + base_range(3904, 3952, 88), + non_base_range(3953, 3966, 88), + base_range(3967, 3967, 88), + non_base_range(3968, 3972, 88), + base_range(3973, 3973, 88), + non_base_range(3974, 3975, 88), + base_range(3976, 3980, 88), + non_base_range(3981, 4028, 88), + base_range(4029, 4095, 88), + base_range(4096, 4140, 67), + non_base_range(4141, 4144, 67), + base_range(4145, 4145, 67), + non_base_range(4146, 4151, 67), + base_range(4152, 4153, 67), + non_base_range(4154, 4154, 67), + base_range(4155, 4156, 67), + non_base_range(4157, 4158, 67), + base_range(4159, 4183, 67), + non_base_range(4184, 4185, 67), + base_range(4186, 4189, 67), + non_base_range(4190, 4192, 67), + base_range(4193, 4208, 67), + non_base_range(4209, 4212, 67), + base_range(4213, 4225, 67), + non_base_range(4226, 4226, 67), + base_range(4227, 4228, 67), + non_base_range(4229, 4230, 67), + base_range(4231, 4236, 67), + non_base_range(4237, 4237, 67), + base_range(4238, 4255, 67), + base_range(4256, 4301, 28), + base_range(4304, 4351, 27), + base_range(4352, 4607, 89), + base_range(4608, 4956, 26), + non_base_range(4957, 4959, 26), + base_range(4960, 5023, 26), + base_range(5024, 5119, 10), + base_range(5120, 5759, 8), + base_range(5952, 5969, 6), + non_base_range(5970, 5971, 6), + base_range(5972, 5983, 6), + base_range(6016, 6070, 46), + non_base_range(6071, 6077, 46), + base_range(6078, 6085, 46), + non_base_range(6086, 6086, 46), + base_range(6087, 6088, 46), + non_base_range(6089, 6099, 46), + base_range(6100, 6108, 46), + non_base_range(6109, 6109, 46), + base_range(6110, 6143, 46), + base_range(6144, 6276, 66), + non_base_range(6277, 6278, 66), + base_range(6279, 6312, 66), + non_base_range(6313, 6313, 66), + base_range(6314, 6319, 66), + base_range(6320, 6399, 8), + base_range(6400, 6431, 85), + non_base_range(6432, 6434, 85), + base_range(6435, 6438, 85), + non_base_range(6439, 6452, 85), + base_range(6453, 6454, 85), + non_base_range(6455, 6459, 85), + base_range(6460, 6479, 85), + base_range(6624, 6655, 47), + non_base_range(6832, 6846, 60), + non_base_range(7040, 7042, 78), + base_range(7043, 7072, 78), + non_base_range(7073, 7085, 78), + base_range(7086, 7103, 78), + base_range(7248, 7295, 70), + base_range(7296, 7311, 23), + base_range(7312, 7359, 27), + base_range(7360, 7375, 78), + base_range(7424, 7467, 60), + base_range(7468, 7521, 62), + base_range(7522, 7530, 61), + base_range(7531, 7543, 60), + base_range(7544, 7544, 62), + base_range(7545, 7578, 60), + base_range(7579, 7615, 62), + non_base_range(7616, 7679, 60), + base_range(7680, 7935, 60), + base_range(7936, 8124, 41), + non_base_range(8125, 8129, 41), + base_range(8130, 8140, 41), + non_base_range(8141, 8143, 41), + base_range(8144, 8156, 41), + non_base_range(8157, 8159, 41), + base_range(8160, 8172, 41), + non_base_range(8173, 8175, 41), + base_range(8176, 8188, 41), + non_base_range(8189, 8190, 41), + base_range(8191, 8191, 41), + base_range(8192, 8214, 60), + non_base_range(8215, 8215, 60), + base_range(8216, 8253, 60), + non_base_range(8254, 8254, 60), + base_range(8255, 8303, 60), + base_range(8304, 8319, 62), + base_range(8320, 8348, 61), + base_range(8352, 8376, 60), + base_range(8377, 8377, 24), + base_range(8378, 8399, 60), + base_range(8528, 8591, 60), + base_range(11264, 11359, 29), + base_range(11360, 11387, 60), + base_range(11388, 11388, 61), + base_range(11389, 11389, 62), + base_range(11390, 11391, 60), + base_range(11392, 11502, 11), + non_base_range(11503, 11505, 11), + base_range(11506, 11519, 11), + base_range(11520, 11565, 28), + base_range(11568, 11647, 82), + base_range(11648, 11743, 26), + non_base_range(11744, 11775, 23), + base_range(11776, 11903, 60), + base_range(11904, 12255, 89), + base_range(12272, 12329, 89), + non_base_range(12330, 12335, 89), + base_range(12336, 12687, 89), + non_base_range(12688, 12703, 89), + base_range(12704, 12799, 89), + base_range(13056, 40959, 89), + base_range(42192, 42239, 63), + base_range(42240, 42559, 84), + base_range(42560, 42606, 23), + non_base_range(42607, 42623, 23), + base_range(42624, 42653, 23), + non_base_range(42654, 42655, 23), + base_range(42656, 42735, 4), + non_base_range(42736, 42737, 4), + base_range(42738, 42751, 4), + base_range(42784, 42863, 60), + base_range(42864, 42864, 62), + base_range(42865, 42887, 60), + non_base_range(42888, 42888, 60), + base_range(42889, 42999, 60), + base_range(43000, 43001, 62), + non_base_range(43002, 43002, 60), + base_range(43003, 43007, 60), + base_range(43008, 43009, 87), + non_base_range(43010, 43010, 87), + base_range(43011, 43013, 87), + non_base_range(43014, 43014, 87), + base_range(43015, 43018, 87), + non_base_range(43019, 43019, 87), + base_range(43020, 43044, 87), + non_base_range(43045, 43046, 87), + base_range(43047, 43055, 87), + non_base_range(43136, 43137, 75), + base_range(43138, 43187, 75), + non_base_range(43188, 43205, 75), + base_range(43206, 43231, 75), + non_base_range(43232, 43249, 24), + base_range(43250, 43262, 24), + non_base_range(43263, 43263, 24), + base_range(43264, 43301, 45), + non_base_range(43302, 43309, 45), + base_range(43310, 43311, 45), + base_range(43360, 43391, 89), + base_range(43488, 43492, 67), + non_base_range(43493, 43493, 67), + base_range(43494, 43519, 67), + base_range(43616, 43643, 67), + non_base_range(43644, 43644, 67), + base_range(43645, 43647, 67), + base_range(43648, 43695, 80), + non_base_range(43696, 43696, 80), + base_range(43697, 43697, 80), + non_base_range(43698, 43700, 80), + base_range(43701, 43702, 80), + non_base_range(43703, 43704, 80), + base_range(43705, 43709, 80), + non_base_range(43710, 43711, 80), + base_range(43712, 43712, 80), + non_base_range(43713, 43713, 80), + base_range(43714, 43743, 80), + base_range(43776, 43823, 26), + base_range(43824, 43867, 60), + base_range(43868, 43871, 62), + base_range(43872, 43887, 60), + base_range(43888, 43967, 10), + base_range(44032, 55295, 89), + base_range(63744, 64255, 89), + base_range(64256, 64262, 60), + base_range(64275, 64279, 2), + base_range(64285, 64285, 44), + non_base_range(64286, 64286, 44), + base_range(64287, 64335, 44), + base_range(64336, 64433, 1), + non_base_range(64434, 64449, 1), + base_range(64450, 65023, 1), + base_range(65040, 65055, 89), + base_range(65072, 65103, 89), + non_base_range(65136, 65136, 1), + base_range(65137, 65137, 1), + non_base_range(65138, 65138, 1), + base_range(65139, 65139, 1), + non_base_range(65140, 65140, 1), + base_range(65141, 65141, 1), + non_base_range(65142, 65142, 1), + base_range(65143, 65143, 1), + non_base_range(65144, 65144, 1), + base_range(65145, 65145, 1), + non_base_range(65146, 65146, 1), + base_range(65147, 65147, 1), + non_base_range(65148, 65148, 1), + base_range(65149, 65149, 1), + non_base_range(65150, 65150, 1), + base_range(65151, 65279, 1), + base_range(65280, 65519, 89), + base_range(66208, 66271, 9), + base_range(66352, 66383, 30), + base_range(66560, 66639, 25), + base_range(66640, 66687, 76), + base_range(66688, 66735, 73), + base_range(66736, 66815, 72), + base_range(67584, 67647, 12), + base_range(68352, 68408, 3), + non_base_range(68409, 68415, 3), + base_range(68608, 68687, 71), + base_range(68864, 68927, 74), + non_base_range(69888, 69890, 7), + base_range(69891, 69926, 7), + non_base_range(69927, 69940, 7), + base_range(69941, 69957, 7), + non_base_range(69958, 69958, 7), + base_range(69959, 69967, 7), + base_range(71264, 71295, 66), + base_range(93760, 93855, 65), + base_range(110592, 110895, 89), + base_range(119552, 119647, 89), + base_range(119808, 120831, 60), + non_base_range(122880, 122927, 29), + non_base_range(125184, 125258, 0), + base_range(125259, 125279, 0), + base_range(126464, 126719, 1), + base_range(131072, 173791, 89), + base_range(173824, 191471, 89), + base_range(194560, 195103, 89), +]; + diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/scripts/gen_autohint_styles.py chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/scripts/gen_autohint_styles.py --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/scripts/gen_autohint_styles.py 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/scripts/gen_autohint_styles.py 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1476 @@ +# Generates Rust tables that define Unicode "script classes" for the purposes +# of autohinting. +# +# For performance, we want to link various pieces of data by index. For ease of +# modification and to avoid errors, we want to define those links symbolically +# by name. Thus, this script exists which converts symbolic references to +# indices when generating code. +# +# The bottom of this file contains the Rust generation code. + +# Based on FreeType autofit coverage: +# https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afcover.h +STYLE_FEATURES = [ + { + "name": "petite capitals from capitals", + "tag": "c2cp", + }, + { + "name": "small capitals from capitals", + "tag": "c2sc", + }, + { + "name": "ordinals", + "tag": "ordn", + }, + { + "name": "petite capitals", + "tag": "pcap", + }, + { + "name": "ruby", + "tag": "ruby", + }, + { + "name": "scientific inferiors", + "tag": "sinf", + }, + { + "name": "small capitals", + "tag": "smcp", + }, + { + "name": "subscript", + "tag": "subs", + }, + { + "name": "superscript", + "tag": "sups", + }, + { + "name": "titling", + "tag": "titl", + }, +] + +# Scripts that generate styles with the extended feature set above +# FreeType refers to these as "meta latin" +SCRIPTS_WITH_FEATURES = ["CYRL", "GREK", "LATN"] + +# In relation to FreeType, this combines the AF_ScriptClass, +# AF_Script_UniRangeRec and AF_BlueStringset. +# Script definitions: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afscript.h +# Unicode ranges: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afranges.c +# Blues: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afblue.h +SCRIPT_CLASSES = [ + { + "name": "Adlam", + "tag": "ADLM", + "hint_top_to_bottom": False, + "std_chars": "𞤌 𞤮", # 𞤌 𞤮 + "base_ranges": [ + (0x1E900, 0x1E95F), # Adlam + ], + "non_base_ranges": [ + (0x1D944, 0x1E94A), + ], + "blues": [ + ("𞤌 𞤅 𞤈 𞤏 𞤔 𞤚", "TOP"), + ("𞤂 𞤖", "0"), + ("𞤬 𞤮 𞤻 𞤼 𞤾", "TOP | X_HEIGHT"), + ("𞤤 𞤨 𞤩 𞤭 𞤴 𞤸 𞤺 𞥀", "0"), + ], + }, + { + "name": "Arabic", + "tag": "ARAB", + "hint_top_to_bottom": False, + "std_chars": "ل ح ـ", # ل ح ـ + "base_ranges": [ + (0x0600, 0x06FF), # Arabic + (0x0750, 0x07FF), # Arabic Supplement + (0x08A0, 0x08FF), # Arabic Extended-A + (0xFB50, 0xFDFF), # Arabic Presentation Forms-A + (0xFE70, 0xFEFF), # Arabic Presentation Forms-B + (0x1EE00, 0x1EEFF), # Arabic Mathematical Alphabetic Symbols + ], + "non_base_ranges": [ + (0x0600, 0x0605), + (0x0610, 0x061A), + (0x064B, 0x065F), + (0x0670, 0x0670), + (0x06D6, 0x06DC), + (0x06DF, 0x06E4), + (0x06E7, 0x06E8), + (0x06EA, 0x06ED), + (0x08D4, 0x08E1), + (0x08D3, 0x08FF), + (0xFBB2, 0xFBC1), + (0xFE70, 0xFE70), + (0xFE72, 0xFE72), + (0xFE74, 0xFE74), + (0xFE76, 0xFE76), + (0xFE78, 0xFE78), + (0xFE7A, 0xFE7A), + (0xFE7C, 0xFE7C), + (0xFE7E, 0xFE7E), + ], + "blues": [ + ("ا إ ل ك ط ظ", "TOP"), + ("ت ث ط ظ ك", "0"), + ("ـ", "NEUTRAL"), + ], + }, + { + "name": "Armenian", + "tag": "ARMN", + "hint_top_to_bottom": False, + "std_chars": "ս Ս", # ս Ս + "base_ranges": [ + (0x0530, 0x058F), # Armenian + (0xFB13, 0xFB17), # Alphab. Present. Forms (Armenian) + ], + "non_base_ranges": [ + (0x0559, 0x055F), + ], + "blues": [ + ("Ա Մ Ւ Ս Բ Գ Դ Օ", "TOP"), + ("Ւ Ո Դ Ճ Շ Ս Տ Օ", "0"), + ("ե է ի մ վ ֆ ճ", "TOP"), + ("ա յ ւ ս գ շ ր օ", "TOP | X_HEIGHT"), + ("հ ո ճ ա ե ծ ս օ", "0"), + ("բ ը ի լ ղ պ փ ց", "0"), + ], + }, + { + "name": "Avestan", + "tag": "AVST", + "hint_top_to_bottom": False, + "std_chars": "𐬚", # 𐬚 + "base_ranges": [ + (0x10B00, 0x10B3F), # Avestan + ], + "non_base_ranges": [ + (0x10B39, 0x10B3F), + ], + "blues": [ + ("𐬀 𐬁 𐬐 𐬛", "TOP"), + ("𐬀 𐬁", "0"), + ], + }, + { + "name": "Bamum", + "tag": "BAMU", + "hint_top_to_bottom": False, + "std_chars": "ꛁ ꛯ", # ꛁ ꛯ + "base_ranges": [ + (0xA6A0, 0xA6FF), # Bamum + # This is commented out in FreeType + # (0x16800, 0x16A3F), # Bamum Supplement + ], + "non_base_ranges": [ + (0xA6F0, 0xA6F1), + ], + "blues": [ + ("ꚧ ꚨ ꛛ ꛉ ꛁ ꛈ ꛫ ꛯ", "TOP"), + ("ꚭ ꚳ ꚶ ꛬ ꚢ ꚽ ꛯ ꛲", "0"), + ], + }, + { + "name": "Bengali", + "tag": "BENG", + "hint_top_to_bottom": True, + "std_chars": "০ ৪", # ০ ৪ + "base_ranges": [ + (0x0980, 0x09FF), # Bengali + ], + "non_base_ranges": [ + (0x0981, 0x0981), + (0x09BC, 0x09BC), + (0x09C1, 0x09C4), + (0x09CD, 0x09CD), + (0x09E2, 0x09E3), + (0x09FE, 0x09FE), + ], + "blues": [ + ("ই ট ঠ ি ী ৈ ৗ", "TOP"), + ("ও এ ড ত ন ব ল ক", "TOP"), + ("অ ড ত ন ব ভ ল ক", "TOP | NEUTRAL | X_HEIGHT"), + ("অ ড ত ন ব ভ ল ক", "0"), + ], + }, + { + "name": "Buhid", + "tag": "BUHD", + "hint_top_to_bottom": False, + "std_chars": "ᝋ ᝏ", # ᝋ ᝏ + "base_ranges": [ + (0x1740, 0x175F), # Buhid + ], + "non_base_ranges": [ + (0x1752, 0x1753), + ], + "blues": [ + ("ᝐ ᝈ", "TOP"), + ("ᝅ ᝊ ᝎ", "TOP"), + ("ᝂ ᝃ ᝉ ᝌ", "TOP | X_HEIGHT"), + ("ᝀ ᝃ ᝆ ᝉ ᝋ ᝏ ᝑ", "0"), + ], + }, + { + "name": "Chakma", + "tag": "CAKM", + "hint_top_to_bottom": False, + "std_chars": "𑄤 𑄉 𑄛", # 𑄤 𑄉 𑄛 + "base_ranges": [ + (0x11100, 0x1114F), # Chakma + ], + "non_base_ranges": [ + (0x11100, 0x11102), + (0x11127, 0x11134), + (0x11146, 0x11146), + ], + "blues": [ + ("𑄃 𑄅 𑄉 𑄙 𑄗", "TOP"), + ("𑄅 𑄛 𑄝 𑄗 𑄓", "0"), + ("𑄖𑄳𑄢 𑄘𑄳𑄢 𑄙𑄳𑄢 𑄤𑄳𑄢 𑄥𑄳𑄢", "0"), + ], + }, + { + "name": "Canadian Syllabics", + "tag": "CANS", + "hint_top_to_bottom": False, + "std_chars": "ᑌ ᓚ", # ᑌ ᓚ + "base_ranges": [ + (0x1400, 0x167F), # Unified Canadian Aboriginal Syllabics + (0x18B0, 0x18FF), # Unified Canadian Aboriginal Syllabics Extended + ], + "non_base_ranges": [ + ], + "blues": [ + ("ᗜ ᖴ ᐁ ᒣ ᑫ ᑎ ᔑ ᗰ", "TOP"), + ("ᗶ ᖵ ᒧ ᐃ ᑌ ᒍ ᔑ ᗢ", "0"), + ("ᓓ ᓕ ᓀ ᓂ ᓄ ᕄ ᕆ ᘣ", "TOP | X_HEIGHT"), + ("ᕃ ᓂ ᓀ ᕂ ᓗ ᓚ ᕆ ᘣ", "0"), + ("ᐪ ᙆ ᣘ ᐢ ᒾ ᣗ ᔆ", "TOP"), + ("ᙆ ᗮ ᒻ ᐞ ᔆ ᒡ ᒢ ᓑ", "0"), + ], + }, + { + "name": "Carian", + "tag": "CARI", + "hint_top_to_bottom": False, + "std_chars": "𐊫 𐋉", # 𐊫 𐋉 + "base_ranges": [ + (0x102A0, 0x102DF), # Carian + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐊧 𐊫 𐊬 𐊭 𐊱 𐊺 𐊼 𐊿", "TOP"), + ("𐊣 𐊧 𐊷 𐋀 𐊫 𐊸 𐋉", "0"), + ], + }, + { + "name": "Cherokee", + "tag": "CHER", + "hint_top_to_bottom": False, + "std_chars": "Ꭴ Ꮕ ꮕ", # Ꭴ Ꮕ ꮕ + "base_ranges": [ + (0x13A0, 0x13FF), # Cherokee + (0xAB70, 0xABBF), # Cherokee Supplement + ], + "non_base_ranges": [ + ], + "blues": [ + ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", "TOP"), + ("Ꮖ Ꮋ Ꭼ Ꮓ Ꭴ Ꮳ Ꭶ Ꮥ", "0"), + ("ꮒ ꮤ ꮶ ꭴ ꭾ ꮗ ꮝ ꮿ", "TOP"), + ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", "TOP | X_HEIGHT"), + ("ꮖ ꭼ ꮓ ꮠ ꮳ ꭶ ꮥ ꮻ", "0"), + ("ᏸ ꮐ ꭹ ꭻ", "0"), + ], + }, + { + "name": "Coptic", + "tag": "COPT", + "hint_top_to_bottom": False, + "std_chars": "Ⲟ ⲟ", # Ⲟ ⲟ + "base_ranges": [ + (0x2C80, 0x2CFF), # Coptic + ], + "non_base_ranges": [ + (0x2CEF, 0x2CF1), + ], + "blues": [ + ("Ⲍ Ⲏ Ⲡ Ⳟ Ⲟ Ⲑ Ⲥ Ⳋ", "TOP"), + ("Ⳑ Ⳙ Ⳟ Ⲏ Ⲟ Ⲑ Ⳝ Ⲱ", "0"), + ("ⲍ ⲏ ⲡ ⳟ ⲟ ⲑ ⲥ ⳋ", "TOP | X_HEIGHT"), + ("ⳑ ⳙ ⳟ ⲏ ⲟ ⲑ ⳝ Ⳓ", "0"), + ], + }, + { + "name": "Cypriot", + "tag": "CPRT", + "hint_top_to_bottom": False, + "std_chars": "𐠅 𐠣", # 𐠅 𐠣 + "base_ranges": [ + (0x10800, 0x1083F), # Cypriot + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐠍 𐠙 𐠳 𐠱 𐠅 𐠓 𐠣 𐠦", "TOP"), + ("𐠃 𐠊 𐠛 𐠣 𐠳 𐠵 𐠐", "0"), + ("𐠈 𐠏 𐠖", "TOP"), + ("𐠈 𐠏 𐠖", "0"), + ], + }, + { + "name": "Cyrillic", + "tag": "CYRL", + "hint_top_to_bottom": False, + "std_chars": "о О", # о О + "base_ranges": [ + (0x0400, 0x04FF), # Cyrillic + (0x0500, 0x052F), # Cyrillic Supplement + (0x2DE0, 0x2DFF), # Cyrillic Extended-A + (0xA640, 0xA69F), # Cyrillic Extended-B + (0x1C80, 0x1C8F), # Cyrillic Extended-C + ], + "non_base_ranges": [ + (0x0483, 0x0489), + (0x2DE0, 0x2DFF), + (0xA66F, 0xA67F), + (0xA69E, 0xA69F), + ], + "blues": [ + ("Б В Е П З О С Э", "TOP"), + ("Б В Е Ш З О С Э", "0"), + ("х п н ш е з о с", "TOP | X_HEIGHT"), + ("х п н ш е з о с", "0"), + ("р у ф", "0"), + ], + }, + { + "name": "Devanagari", + "tag": "DEVA", + "hint_top_to_bottom": True, + "std_chars": "ठ व ट", # ठ व ट + "base_ranges": [ + (0x0900, 0x093B), # Devanagari + (0x093D, 0x0950), # ... continued + (0x0953, 0x0963), # ... continued + (0x0966, 0x097F), # ... continued + (0x20B9, 0x20B9), # (new) Rupee sign + (0xA8E0, 0xA8FF), # Devanagari Extended + ], + "non_base_ranges": [ + (0x0900, 0x0902), + (0x093A, 0x093A), + (0x0941, 0x0948), + (0x094D, 0x094D), + (0x0953, 0x0957), + (0x0962, 0x0963), + (0xA8E0, 0xA8F1), + (0xA8FF, 0xA8FF), + ], + "blues": [ + ("ई ऐ ओ औ ि ी ो ौ", "TOP"), + ("क म अ आ थ ध भ श", "TOP"), + ("क न म उ छ ट ठ ड", "TOP | NEUTRAL | X_HEIGHT"), + ("क न म उ छ ट ठ ड", "0"), + ("ु ृ", "0"), + ], + }, + { + "name": "Deseret", + "tag": "DSRT", + "hint_top_to_bottom": False, + "std_chars": "𐐄 𐐬", # 𐐄 𐐬 + "base_ranges": [ + (0x10400, 0x1044F), # Deseret + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐐂 𐐄 𐐋 𐐗 𐐑", "TOP"), + ("𐐀 𐐂 𐐄 𐐗 𐐛", "0"), + ("𐐪 𐐬 𐐳 𐐿 𐐹", "TOP | X_HEIGHT"), + ("𐐨 𐐪 𐐬 𐐿 𐑃", "0"), + ], + }, + { + "name": "Ethiopic", + "tag": "ETHI", + "hint_top_to_bottom": False, + "std_chars": "ዐ", # ዐ + "base_ranges": [ + (0x1200, 0x137F), # Ethiopic + (0x1380, 0x139F), # Ethiopic Supplement + (0x2D80, 0x2DDF), # Ethiopic Extended + (0xAB00, 0xAB2F), # Ethiopic Extended-A + ], + "non_base_ranges": [ + (0x135D, 0x135F), + ], + "blues": [ + ("ሀ ሃ ዘ ፐ ማ በ ዋ ዐ", "TOP"), + ("ለ ሐ በ ዘ ሀ ሪ ዐ ጨ", "0"), + ], + }, + { + "name": "Georgian (Mkhedruli)", + "tag": "GEOR", + "hint_top_to_bottom": False, + "std_chars": "ი ე ა Ჿ", # ი ე ა Ი + "base_ranges": [ + (0x10D0, 0x10FF), # Georgian (Mkhedruli) + (0x1C90, 0x1CBF), # Georgian Extended (Mtavruli) + ], + "non_base_ranges": [ + ], + "blues": [ + ("გ დ ე ვ თ ი ო ღ", "TOP | X_HEIGHT"), + ("ა ზ მ ს შ ძ ხ პ", "0"), + ("ს ხ ქ ზ მ შ ჩ წ", "TOP"), + ("ე ვ ჟ ტ უ ფ ქ ყ", "0"), + ("Ნ Ჟ Ჳ Ჸ Გ Ე Ო Ჴ", "TOP"), + ("Ი Ჲ Ო Ჩ Მ Შ Ჯ Ჽ", "0"), + ], + }, + { + "name": "Georgian (Khutsuri)", + "tag": "GEOK", + "hint_top_to_bottom": False, + "std_chars": "Ⴖ Ⴑ ⴙ", # Ⴖ Ⴑ ⴙ + "base_ranges": [ + (0x10A0, 0x10CD), # Georgian (Asomtavruli) + (0x2D00, 0x2D2D), # Georgian Supplement (Nuskhuri) + ], + "non_base_ranges": [ + ], + "blues": [ + ("Ⴑ Ⴇ Ⴙ Ⴜ Ⴄ Ⴅ Ⴓ Ⴚ", "TOP"), + ("Ⴄ Ⴅ Ⴇ Ⴈ Ⴆ Ⴑ Ⴊ Ⴋ", "0"), + ("ⴁ ⴗ ⴂ ⴄ ⴅ ⴇ ⴔ ⴖ", "TOP | X_HEIGHT"), + ("ⴈ ⴌ ⴖ ⴎ ⴃ ⴆ ⴋ ⴢ", "0"), + ("ⴐ ⴑ ⴓ ⴕ ⴙ ⴛ ⴡ ⴣ", "TOP"), + ("ⴄ ⴅ ⴔ ⴕ ⴁ ⴂ ⴘ ⴝ", "0"), + ], + }, + { + "name": "Glagolitic", + "tag": "GLAG", + "hint_top_to_bottom": False, + "std_chars": "Ⱅ ⱅ", # Ⱅ ⱅ + "base_ranges": [ + (0x2C00, 0x2C5F), # Glagolitic + (0x1E000, 0x1E02F), # Glagolitic Supplement + ], + "non_base_ranges": [ + (0x1E000, 0x1E02F), + ], + "blues": [ + ("Ⰵ Ⱄ Ⱚ Ⰴ Ⰲ Ⰺ Ⱛ Ⰻ", "TOP"), + ("Ⰵ Ⰴ Ⰲ Ⱚ Ⱎ Ⱑ Ⰺ Ⱄ", "0"), + ("ⰵ ⱄ ⱚ ⰴ ⰲ ⰺ ⱛ ⰻ", "TOP | X_HEIGHT"), + ("ⰵ ⰴ ⰲ ⱚ ⱎ ⱑ ⰺ ⱄ", "0"), + ], + }, + { + "name": "Gothic", + "tag": "GOTH", + "hint_top_to_bottom": True, + "std_chars": "𐌴 𐌾 𐍃", # 𐌴 𐌾 𐍃 + "base_ranges": [ + (0x10330, 0x1034F), # Gothic + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐌲 𐌶 𐍀 𐍄 𐌴 𐍃 𐍈 𐌾", "TOP"), + ("𐌶 𐌴 𐍃 𐍈", "0"), + ], + }, + { + "name": "Greek", + "tag": "GREK", + "hint_top_to_bottom": False, + "std_chars": "ο Ο", # ο Ο + "base_ranges": [ + (0x0370, 0x03FF), # Greek and Coptic + (0x1F00, 0x1FFF), # Greek Extended + ], + "non_base_ranges": [ + (0x037A, 0x037A), + (0x0384, 0x0385), + (0x1FBD, 0x1FC1), + (0x1FCD, 0x1FCF), + (0x1FDD, 0x1FDF), + (0x1FED, 0x1FEF), + (0x1FFD, 0x1FFE), + ], + "blues": [ + ("Γ Β Ε Ζ Θ Ο Ω", "TOP"), + ("Β Δ Ζ Ξ Θ Ο", "0"), + ("β θ δ ζ λ ξ", "TOP"), + ("α ε ι ο π σ τ ω", "TOP | X_HEIGHT"), + ("α ε ι ο π σ τ ω", "0"), + ("β γ η μ ρ φ χ ψ", "0"), + ], + }, + { + "name": "Gujarati", + "tag": "GUJR", + "hint_top_to_bottom": False, + "std_chars": "ટ ૦", # ટ ૦ + "base_ranges": [ + (0x0A80, 0x0AFF), # Gujarati + ], + "non_base_ranges": [ + (0x0A81, 0x0A82), + (0x0ABC, 0x0ABC), + (0x0AC1, 0x0AC8), + (0x0ACD, 0x0ACD), + (0x0AE2, 0x0AE3), + (0x0AFA, 0x0AFF), + ], + "blues": [ + ("ત ન ઋ ઌ છ ટ ર ૦", "TOP | X_HEIGHT"), + ("ખ ગ ઘ ઞ ઇ ઈ ઠ જ", "0"), + ("ઈ ઊ િ ી લી શ્ચિ જિ સી", "TOP"), + ("ુ ૃ ૄ ખુ છૃ છૄ", "0"), + ("૦ ૧ ૨ ૩ ૭", "TOP"), + ], + }, + { + "name": "Gurmukhi", + "tag": "GURU", + "hint_top_to_bottom": True, + "std_chars": "ਠ ਰ ੦", # ਠ ਰ ੦ + "base_ranges": [ + (0x0A00, 0x0A7F), # Gurmukhi + ], + "non_base_ranges": [ + (0x0A01, 0x0A02), + (0x0A3C, 0x0A3C), + (0x0A41, 0x0A51), + (0x0A70, 0x0A71), + (0x0A75, 0x0A75), + ], + "blues": [ + ("ਇ ਈ ਉ ਏ ਓ ੳ ਿ ੀ", "TOP"), + ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", "TOP"), + ("ਕ ਗ ਙ ਚ ਜ ਤ ਧ ਸ", "TOP | NEUTRAL | X_HEIGHT"), + ("ਅ ਏ ਓ ਗ ਜ ਠ ਰ ਸ", "0"), + ("੦ ੧ ੨ ੩ ੭", "TOP"), + ], + }, + { + "name": "Hebrew", + "tag": "HEBR", + "hint_top_to_bottom": False, + "std_chars": "ם", # ם + "base_ranges": [ + (0x0590, 0x05FF), # Hebrew + (0xFB1D, 0xFB4F), # Alphab. Present. Forms (Hebrew) + ], + "non_base_ranges": [ + (0x0591, 0x05BF), + (0x05C1, 0x05C2), + (0x05C4, 0x05C5), + (0x05C7, 0x05C7), + (0xFB1E, 0xFB1E), + ], + "blues": [ + ("ב ד ה ח ך כ ם ס", "TOP | LONG"), + ("ב ט כ ם ס צ", "0"), + ("ק ך ן ף ץ", "0"), + ], + }, + { + "name": "Kayah Li", + "tag": "KALI", + "hint_top_to_bottom": False, + "std_chars": "ꤍ ꤀", # ꤍ ꤀ + "base_ranges": [ + (0xA900, 0xA92F), # Kayah Li + ], + "non_base_ranges": [ + (0xA926, 0xA92D), + ], + "blues": [ + ("꤅ ꤏ ꤁ ꤋ ꤀ ꤍ", "TOP | X_HEIGHT"), + ("꤈ ꤘ ꤀ ꤍ ꤢ", "0"), + ("ꤖ ꤡ", "TOP"), + ("ꤑ ꤜ ꤞ", "0"), + ("ꤑ꤬ ꤜ꤭ ꤔ꤬", "0"), + ], + }, + { + "name": "Khmer", + "tag": "KHMR", + "hint_top_to_bottom": False, + "std_chars": "០", # ០ + "base_ranges": [ + (0x1780, 0x17FF), # Khmer + ], + "non_base_ranges": [ + (0x17B7, 0x17BD), + (0x17C6, 0x17C6), + (0x17C9, 0x17D3), + (0x17DD, 0x17DD), + ], + "blues": [ + ("ខ ទ ន ឧ ឩ ា", "TOP | X_HEIGHT"), + ("ក្ក ក្ខ ក្គ ក្ថ", "SUB_TOP"), + ("ខ ឃ ច ឋ ប ម យ ឲ", "0"), + ("ត្រ រៀ ឲ្យ អឿ", "0"), + ("ន្ត្រៃ ង្ខ្យ ក្បៀ ច្រៀ ន្តឿ ល្បឿ", "0"), + ], + }, + { + "name": "Khmer Symbols", + "tag": "KHMS", + "hint_top_to_bottom": False, + "std_chars": "᧡ ᧪", # ᧡ ᧪ + "base_ranges": [ + (0x19E0, 0x19FF), # Khmer Symbols + ], + "non_base_ranges": [ + ], + "blues": [ + ("᧠ ᧡", "TOP | X_HEIGHT"), + ("᧶ ᧹", "0"), + ], + }, + { + "name": "Kannada", + "tag": "KNDA", + "hint_top_to_bottom": False, + "std_chars": "೦ ಬ", # ೦ ಬ + "base_ranges": [ + (0x0C80, 0x0CFF), # Kannada + ], + "non_base_ranges": [ + (0x0C81, 0x0C81), + (0x0CBC, 0x0CBC), + (0x0CBF, 0x0CBF), + (0x0CC6, 0x0CC6), + (0x0CCC, 0x0CCD), + (0x0CE2, 0x0CE3), + ], + "blues": [ + ("ಇ ಊ ಐ ಣ ಸಾ ನಾ ದಾ ರಾ", "TOP"), + ("ಅ ಉ ಎ ಲ ೦ ೨ ೬ ೭", "0"), + ], + }, + { + "name": "Lao", + "tag": "LAOO", + "hint_top_to_bottom": False, + "std_chars": "໐", # ໐ + "base_ranges": [ + (0x0E80, 0x0EFF), # Lao + ], + "non_base_ranges": [ + (0x0EB1, 0x0EB1), + (0x0EB4, 0x0EBC), + (0x0EC8, 0x0ECD), + ], + "blues": [ + ("າ ດ ອ ມ ລ ວ ຣ ງ", "TOP | X_HEIGHT"), + ("າ ອ ບ ຍ ຣ ຮ ວ ຢ", "0"), + ("ປ ຢ ຟ ຝ", "TOP"), + ("ໂ ໄ ໃ", "TOP"), + ("ງ ຊ ຖ ຽ ໆ ຯ", "0"), + ], + }, + { + "name": "Latin", + "tag": "LATN", + "hint_top_to_bottom": False, + "std_chars": "o O 0", + "base_ranges": [ + (0x0020, 0x007F), # Basic Latin (no control chars) + (0x00A0, 0x00A9), # Latin-1 Supplement (no control chars) + (0x00AB, 0x00B1), # ... continued + (0x00B4, 0x00B8), # ... continued + (0x00BB, 0x00FF), # ... continued + (0x0100, 0x017F), # Latin Extended-A + (0x0180, 0x024F), # Latin Extended-B + (0x0250, 0x02AF), # IPA Extensions + (0x02B9, 0x02DF), # Spacing Modifier Letters + (0x02E5, 0x02FF), # ... continued + (0x0300, 0x036F), # Combining Diacritical Marks + (0x1AB0, 0x1ABE), # Combining Diacritical Marks Extended + (0x1D00, 0x1D2B), # Phonetic Extensions + (0x1D6B, 0x1D77), # ... continued + (0x1D79, 0x1D7F), # ... continued + (0x1D80, 0x1D9A), # Phonetic Extensions Supplement + (0x1DC0, 0x1DFF), # Combining Diacritical Marks Supplement + (0x1E00, 0x1EFF), # Latin Extended Additional + (0x2000, 0x206F), # General Punctuation + (0x20A0, 0x20B8), # Currency Symbols ... + (0x20BA, 0x20CF), # ... except new Rupee sign + (0x2150, 0x218F), # Number Forms + (0x2C60, 0x2C7B), # Latin Extended-C + (0x2C7E, 0x2C7F), # ... continued + (0x2E00, 0x2E7F), # Supplemental Punctuation + (0xA720, 0xA76F), # Latin Extended-D + (0xA771, 0xA7F7), # ... continued + (0xA7FA, 0xA7FF), # ... continued + (0xAB30, 0xAB5B), # Latin Extended-E + (0xAB60, 0xAB6F), # ... continued + (0xFB00, 0xFB06), # Alphab. Present. Forms (Latin Ligs) + (0x1D400, 0x1D7FF), # Mathematical Alphanumeric Symbols + ], + "non_base_ranges": [ + (0x005E, 0x0060), + (0x007E, 0x007E), + (0x00A8, 0x00A9), + (0x00AE, 0x00B0), + (0x00B4, 0x00B4), + (0x00B8, 0x00B8), + (0x00BC, 0x00BE), + (0x02B9, 0x02DF), + (0x02E5, 0x02FF), + (0x0300, 0x036F), + (0x1AB0, 0x1ABE), + (0x1DC0, 0x1DFF), + (0x2017, 0x2017), + (0x203E, 0x203E), + (0xA788, 0xA788), + (0xA7F8, 0xA7FA), + ], + "blues": [ + ("T H E Z O C Q S", "TOP"), + ("H E Z L O C U S", "0"), + ("f i j k d b h", "TOP"), + ("u v x z o e s c", "TOP | X_HEIGHT"), + ("n r x z o e s c", "0"), + ("p q g j y", "0"), + ], + }, + { + "name": "Latin Subscript Fallback", + "tag": "LATB", + "hint_top_to_bottom": False, + "std_chars": "ₒ ₀", # ₒ ₀ + "base_ranges": [ + (0x1D62, 0x1D6A), # some small subscript letters + (0x2080, 0x209C), # subscript digits and letters + (0x2C7C, 0x2C7C), # latin subscript small letter j + ], + "non_base_ranges": [ + ], + "blues": [ + ("₀ ₃ ₅ ₇ ₈", "TOP"), + ("₀ ₁ ₂ ₃ ₈", "0"), + ("ᵢ ⱼ ₕ ₖ ₗ", "TOP"), + ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", "TOP | X_HEIGHT"), + ("ₐ ₑ ₒ ₓ ₙ ₛ ᵥ ᵤ ᵣ", "0"), + ("ᵦ ᵧ ᵨ ᵩ ₚ", "0"), + ], + }, + { + "name": "Latin Superscript Fallback", + "tag": "LATP", + "hint_top_to_bottom": False, + "std_chars": "ᵒ ᴼ ⁰", # ᵒ ᴼ ⁰ + "base_ranges": [ + (0x00AA, 0x00AA), # feminine ordinal indicator + (0x00B2, 0x00B3), # superscript two and three + (0x00B9, 0x00BA), # superscript one, masc. ord. indic. + (0x02B0, 0x02B8), # some latin superscript mod. letters + (0x02E0, 0x02E4), # some IPA modifier letters + (0x1D2C, 0x1D61), # latin superscript modifier letters + (0x1D78, 0x1D78), # modifier letter cyrillic en + (0x1D9B, 0x1DBF), # more modifier letters + (0x2070, 0x207F), # superscript digits and letters + (0x2C7D, 0x2C7D), # modifier letter capital v + (0xA770, 0xA770), # modifier letter us + (0xA7F8, 0xA7F9), # more modifier letters + (0xAB5C, 0xAB5F), # more modifier letters + ], + "non_base_ranges": [ + ], + "blues": [ + ("⁰ ³ ⁵ ⁷ ᵀ ᴴ ᴱ ᴼ", "TOP"), + ("⁰ ¹ ² ³ ᴱ ᴸ ᴼ ᵁ", "0"), + ("ᵇ ᵈ ᵏ ʰ ʲ ᶠ ⁱ", "TOP"), + ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", "TOP | X_HEIGHT"), + ("ᵉ ᵒ ʳ ˢ ˣ ᶜ ᶻ", "0"), + ("ᵖ ʸ ᵍ", "0"), + ], + }, + { + "name": "Lisu", + "tag": "LISU", + "hint_top_to_bottom": False, + "std_chars": "ꓳ", # ꓳ + "base_ranges": [ + (0xA4D0, 0xA4FF), # Lisu + ], + "non_base_ranges": [ + ], + "blues": [ + ("ꓡ ꓧ ꓱ ꓶ ꓩ ꓚ ꓵ ꓳ", "TOP"), + ("ꓕ ꓜ ꓞ ꓡ ꓛ ꓢ ꓳ ꓴ", "0"), + ], + }, + { + "name": "Malayalam", + "tag": "MLYM", + "hint_top_to_bottom": False, + "std_chars": "ഠ റ", # ഠ റ + "base_ranges": [ + (0x0D00, 0x0D7F), # Malayalam + ], + "non_base_ranges": [ + (0x0D00, 0x0D01), + (0x0D3B, 0x0D3C), + (0x0D4D, 0x0D4E), + (0x0D62, 0x0D63), + ], + "blues": [ + ("ഒ ട ഠ റ ച പ ച്ച പ്പ", "TOP"), + ("ട ഠ ധ ശ ഘ ച ഥ ല", "0"), + ], + }, + { + "name": "Medefaidrin", + "tag": "MEDF", + "hint_top_to_bottom": False, + "std_chars": "𖹡 𖹛 𖹯", # 𖹡 𖹛 𖹯 + "base_ranges": [ + (0x16E40, 0x16E9F), # Medefaidrin + ], + "non_base_ranges": [ + ], + "blues": [ + ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹟", "TOP"), + ("𖹀 𖹁 𖹂 𖹃 𖹏 𖹚 𖹒 𖹓", "0"), + ("𖹤 𖹬 𖹧 𖹴 𖹶 𖹾", "TOP"), + ("𖹠 𖹡 𖹢 𖹹 𖹳 𖹮", "TOP | X_HEIGHT"), + ("𖹠 𖹡 𖹢 𖹳 𖹭 𖹽", "0"), + ("𖹥 𖹨 𖹩", "0"), + ("𖺀 𖺅 𖺈 𖺄 𖺍", "TOP"), + ], + }, + { + "name": "Mongolian", + "tag": "MONG", + "hint_top_to_bottom": True, + "std_chars": "ᡂ ᠪ", # ᡂ ᠪ + "base_ranges": [ + (0x1800, 0x18AF), # Mongolian + (0x11660, 0x1167F), # Mongolian Supplement + ], + "non_base_ranges": [ + (0x1885, 0x1886), + (0x18A9, 0x18A9), + ], + "blues": [ + ("ᠳ ᠴ ᠶ ᠽ ᡂ ᡊ ‍ᡡ‍ ‍ᡳ‍", "TOP"), + ("ᡃ", "0"), + ], + }, + { + "name": "Myanmar", + "tag": "MYMR", + "hint_top_to_bottom": False, + "std_chars": "ဝ င ဂ", # ဝ င ဂ + "base_ranges": [ + (0x1000, 0x109F), # Myanmar + (0xA9E0, 0xA9FF), # Myanmar Extended-B + (0xAA60, 0xAA7F), # Myanmar Extended-A + ], + "non_base_ranges": [ + (0x102D, 0x1030), + (0x1032, 0x1037), + (0x103A, 0x103A), + (0x103D, 0x103E), + (0x1058, 0x1059), + (0x105E, 0x1060), + (0x1071, 0x1074), + (0x1082, 0x1082), + (0x1085, 0x1086), + (0x108D, 0x108D), + (0xA9E5, 0xA9E5), + (0xAA7C, 0xAA7C), + ], + "blues": [ + ("ခ ဂ င ဒ ဝ ၥ ၊ ။", "TOP | X_HEIGHT"), + ("င ဎ ဒ ပ ဗ ဝ ၊ ။", "0"), + ("ဩ ြ ၍ ၏ ၆ ါ ိ", "TOP"), + ("ဉ ည ဥ ဩ ဨ ၂ ၅ ၉", "0"), + ], + }, + { + "name": "N'Ko", + "tag": "NKOO", + "hint_top_to_bottom": False, + "std_chars": "ߋ ߀", # ߋ ߀ + "base_ranges": [ + (0x07C0, 0x07FF), # N'Ko + ], + "non_base_ranges": [ + (0x07EB, 0x07F5), + (0x07FD, 0x07FD), + ], + "blues": [ + ("ߐ ߉ ߒ ߟ ߖ ߜ ߠ ߥ", "TOP"), + ("߀ ߘ ߡ ߠ ߥ", "0"), + ("ߏ ߛ ߋ", "TOP | X_HEIGHT"), + ("ߎ ߏ ߛ ߋ", "0"), + ], + }, + { + "name": "no script", + "tag": "NONE", + "hint_top_to_bottom": False, + "std_chars": "", + "base_ranges": [ + ], + "non_base_ranges": [ + ], + "blues": [ + ], + }, + { + "name": "Ol Chiki", + "tag": "OLCK", + "hint_top_to_bottom": False, + "std_chars": "ᱛ", # ᱛ + "base_ranges": [ + (0x1C50, 0x1C7F), # Ol Chiki + ], + "non_base_ranges": [ + ], + "blues": [ + ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", "TOP"), + ("ᱛ ᱜ ᱝ ᱡ ᱢ ᱥ", "0"), + ], + }, + { + "name": "Old Turkic", + "tag": "ORKH", + "hint_top_to_bottom": False, + "std_chars": "𐰗", # 𐰗 + "base_ranges": [ + (0x10C00, 0x10C4F), # Old Turkic + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐰗 𐰘 𐰧", "TOP"), + ("𐰉 𐰗 𐰦 𐰧", "0"), + ], + }, + { + "name": "Osage", + "tag": "OSGE", + "hint_top_to_bottom": False, + "std_chars": "𐓂 𐓪", # 𐓂 𐓪 + "base_ranges": [ + (0x104B0, 0x104FF), # Osage + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐒾 𐓍 𐓒 𐓓 𐒻 𐓂 𐒵 𐓆", "TOP"), + ("𐒰 𐓍 𐓂 𐒿 𐓎 𐒹", "0"), + ("𐒼 𐒽 𐒾", "0"), + ("𐓵 𐓶 𐓺 𐓻 𐓝 𐓣 𐓪 𐓮", "TOP | X_HEIGHT"), + ("𐓘 𐓚 𐓣 𐓵 𐓡 𐓧 𐓪 𐓶", "0"), + ("𐓤 𐓦 𐓸 𐓹 𐓛", "TOP"), + ("𐓤 𐓥 𐓦", "0"), + ], + }, + { + "name": "Osmanya", + "tag": "OSMA", + "hint_top_to_bottom": False, + "std_chars": "𐒆 𐒠", # 𐒆 𐒠 + "base_ranges": [ + (0x10480, 0x104AF), # Osmanya + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐒆 𐒉 𐒐 𐒒 𐒘 𐒛 𐒠 𐒣", "TOP"), + ("𐒀 𐒂 𐒆 𐒈 𐒊 𐒒 𐒠 𐒩", "0"), + ], + }, + { + "name": "Hanifi Rohingya", + "tag": "ROHG", + "hint_top_to_bottom": False, + "std_chars": "𐴰", # 𐴰 + "base_ranges": [ + (0x10D00, 0x10D3F), # Hanifi Rohingya + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐴃 𐴀 𐴆 𐴖 𐴕", "TOP"), + ("𐴔 𐴖 𐴕 𐴑 𐴐", "0"), + ("ـ", "NEUTRAL"), + ], + }, + { + "name": "Saurashtra", + "tag": "SAUR", + "hint_top_to_bottom": False, + "std_chars": "ꢝ ꣐", # ꢝ ꣐ + "base_ranges": [ + (0xA880, 0xA8DF), # Saurashtra + ], + "non_base_ranges": [ + (0xA880, 0xA881), + (0xA8B4, 0xA8C5), + ], + "blues": [ + ("ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ꢝ ꢛ", "TOP"), + ("ꢂ ꢨ ꢺ ꢤ ꢎ", "0"), + ], + }, + { + "name": "Shavian", + "tag": "SHAW", + "hint_top_to_bottom": False, + "std_chars": "𐑴", # 𐑴 + "base_ranges": [ + (0x10450, 0x1047F), # Shavian + ], + "non_base_ranges": [ + ], + "blues": [ + ("𐑕 𐑙", "TOP"), + ("𐑔 𐑖 𐑗 𐑹 𐑻", "0"), + ("𐑟 𐑣", "0"), + ("𐑱 𐑲 𐑳 𐑴 𐑸 𐑺 𐑼", "TOP | X_HEIGHT"), + ("𐑴 𐑻 𐑹", "0"), + ], + }, + { + "name": "Sinhala", + "tag": "SINH", + "hint_top_to_bottom": False, + "std_chars": "ට", # ට + "base_ranges": [ + (0x0D80, 0x0DFF), # Sinhala + ], + "non_base_ranges": [ + (0x0DCA, 0x0DCA), + (0x0DD2, 0x0DD6), + ], + "blues": [ + ("ඉ ක ඝ ඳ ප ය ල ෆ", "TOP"), + ("එ ඔ ඝ ජ ට ථ ධ ර", "0"), + ("ද ඳ උ ල තූ තු බු දු", "0"), + ], + }, + { + "name": "Sundanese", + "tag": "SUND", + "hint_top_to_bottom": False, + "std_chars": "᮰", # ᮰ + "base_ranges": [ + (0x1B80, 0x1BBF), # Sundanese + (0x1CC0, 0x1CCF), # Sundanese Supplement + ], + "non_base_ranges": [ + (0x1B80, 0x1B82), + (0x1BA1, 0x1BAD), + ], + "blues": [ + ("ᮋ ᮞ ᮮ ᮽ ᮰ ᮈ", "TOP"), + ("ᮄ ᮔ ᮕ ᮗ ᮰ ᮆ ᮈ ᮉ", "0"), + ("ᮼ ᳄", "0"), + ], + }, + { + "name": "Tamil", + "tag": "TAML", + "hint_top_to_bottom": False, + "std_chars": "௦", # ௦ + "base_ranges": [ + (0x0B80, 0x0BFF), # Tamil + ], + "non_base_ranges": [ + (0x0B82, 0x0B82), + (0x0BC0, 0x0BC2), + (0x0BCD, 0x0BCD), + ], + "blues": [ + ("உ ஒ ஓ ற ஈ க ங ச", "TOP"), + ("க ச ல ஶ உ ங ட ப", "0"), + ], + }, + { + "name": "Tai Viet", + "tag": "TAVT", + "hint_top_to_bottom": False, + "std_chars": "ꪒ ꪫ", # ꪒ ꪫ + "base_ranges": [ + (0xAA80, 0xAADF), # Tai Viet + ], + "non_base_ranges": [ + (0xAAB0, 0xAAB0), + (0xAAB2, 0xAAB4), + (0xAAB7, 0xAAB8), + (0xAABE, 0xAABF), + (0xAAC1, 0xAAC1), + ], + "blues": [ + ("ꪆ ꪔ ꪒ ꪖ ꪫ", "TOP"), + ("ꪉ ꪫ ꪮ", "0"), + ], + }, + { + "name": "Telugu", + "tag": "TELU", + "hint_top_to_bottom": False, + "std_chars": "౦ ౧", # ౦ ౧ + "base_ranges": [ + (0x0C00, 0x0C7F), # Telugu + ], + "non_base_ranges": [ + (0x0C00, 0x0C00), + (0x0C04, 0x0C04), + (0x0C3E, 0x0C40), + (0x0C46, 0x0C56), + (0x0C62, 0x0C63), + ], + "blues": [ + ("ఇ ఌ ఙ ఞ ణ ఱ ౯", "TOP"), + ("అ క చ ర ఽ ౨ ౬", "0"), + ], + }, + { + "name": "Tifinagh", + "tag": "TFNG", + "hint_top_to_bottom": False, + "std_chars": "ⵔ", # ⵔ + "base_ranges": [ + (0x2D30, 0x2D7F), # Tifinagh + ], + "non_base_ranges": [ + ], + "blues": [ + ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", "TOP"), + ("ⵔ ⵙ ⵛ ⵞ ⴵ ⴼ ⴹ ⵎ", "0"), + ], + }, + { + "name": "Thai", + "tag": "THAI", + "hint_top_to_bottom": False, + "std_chars": "า ๅ ๐", # า ๅ ๐ + "base_ranges": [ + (0x0E00, 0x0E7F), # Thai + ], + "non_base_ranges": [ + (0x0E31, 0x0E31), + (0x0E34, 0x0E3A), + (0x0E47, 0x0E4E), + ], + "blues": [ + ("บ เ แ อ ก า", "TOP | X_HEIGHT"), + ("บ ป ษ ฯ อ ย ฮ", "0"), + ("ป ฝ ฟ", "TOP"), + ("โ ใ ไ", "TOP"), + ("ฎ ฏ ฤ ฦ", "0"), + ("ญ ฐ", "0"), + ("๐ ๑ ๓", "0"), + ], + }, + { + "name": "Vai", + "tag": "VAII", + "hint_top_to_bottom": False, + "std_chars": "ꘓ ꖜ ꖴ", # ꘓ ꖜ ꖴ + "base_ranges": [ + (0xA500, 0xA63F), # Vai + ], + "non_base_ranges": [ + ], + "blues": [ + ("ꗍ ꘖ ꘙ ꘜ ꖜ ꖝ ꔅ ꕢ", "TOP"), + ("ꗍ ꘖ ꘙ ꗞ ꔅ ꕢ ꖜ ꔆ", "0"), + ], + }, + { + "name": "Limbu", + "tag": "LIMB", + "hint_top_to_bottom": False, + "std_chars": "o", # XXX + "base_ranges": [ + (0x1900, 0x194F), # Limbu + ], + "non_base_ranges": [ + (0x1920, 0x1922), + (0x1927, 0x1934), + (0x1937, 0x193B), + ], + "blues": [], + }, + { + "name": "Oriya", + "tag": "ORYA", + "hint_top_to_bottom": False, + "std_chars": "o", # XXX + "base_ranges": [ + (0x0B00, 0x0B7F), # Oriya + ], + "non_base_ranges": [ + (0x0B01, 0x0B02), + (0x0B3C, 0x0B3C), + (0x0B3F, 0x0B3F), + (0x0B41, 0x0B44), + (0x0B4D, 0x0B56), + (0x0B62, 0x0B63), + ], + "blues": [], + }, + { + "name": "Syloti Nagri", + "tag": "SYLO", + "hint_top_to_bottom": False, + "std_chars": "o", # XXX + "base_ranges": [ + (0xA800, 0xA82F), # Syloti Nagri + ], + "non_base_ranges": [ + (0xA802, 0xA802), + (0xA806, 0xA806), + (0xA80B, 0xA80B), + (0xA825, 0xA826), + ], + "blues": [], + }, + { + "name": "Tibetan", + "tag": "TIBT", + "hint_top_to_bottom": False, + "std_chars": "o", # XXX + "base_ranges": [ + (0x0F00, 0x0FFF), # Tibetan + ], + "non_base_ranges": [ + (0x0F18, 0x0F19), + (0x0F35, 0x0F35), + (0x0F37, 0x0F37), + (0x0F39, 0x0F39), + (0x0F3E, 0x0F3F), + (0x0F71, 0x0F7E), + (0x0F80, 0x0F84), + (0x0F86, 0x0F87), + (0x0F8D, 0x0FBC), + ], + "blues": [], + }, + { + "name": "CJKV ideographs", + "tag": "HANI", + "hint_top_to_bottom": False, + "std_chars": "田 囗", # 田 囗 + "base_ranges": [ + (0x1100, 0x11FF), # Hangul Jamo + (0x2E80, 0x2EFF), # CJK Radicals Supplement + (0x2F00, 0x2FDF), # Kangxi Radicals + (0x2FF0, 0x2FFF), # Ideographic Description Characters + (0x3000, 0x303F), # CJK Symbols and Punctuation + (0x3040, 0x309F), # Hiragana + (0x30A0, 0x30FF), # Katakana + (0x3100, 0x312F), # Bopomofo + (0x3130, 0x318F), # Hangul Compatibility Jamo + (0x3190, 0x319F), # Kanbun + (0x31A0, 0x31BF), # Bopomofo Extended + (0x31C0, 0x31EF), # CJK Strokes + (0x31F0, 0x31FF), # Katakana Phonetic Extensions + (0x3300, 0x33FF), # CJK Compatibility + (0x3400, 0x4DBF), # CJK Unified Ideographs Extension A + (0x4DC0, 0x4DFF), # Yijing Hexagram Symbols + (0x4E00, 0x9FFF), # CJK Unified Ideographs + (0xA960, 0xA97F), # Hangul Jamo Extended-A + (0xAC00, 0xD7AF), # Hangul Syllables + (0xD7B0, 0xD7FF), # Hangul Jamo Extended-B + (0xF900, 0xFAFF), # CJK Compatibility Ideographs + (0xFE10, 0xFE1F), # Vertical forms + (0xFE30, 0xFE4F), # CJK Compatibility Forms + (0xFF00, 0xFFEF), # Halfwidth and Fullwidth Forms + (0x1B000, 0x1B0FF), # Kana Supplement + (0x1B100, 0x1B12F), # Kana Extended-A + (0x1D300, 0x1D35F), # Tai Xuan Hing Symbols + (0x20000, 0x2A6DF), # CJK Unified Ideographs Extension B + (0x2A700, 0x2B73F), # CJK Unified Ideographs Extension C + (0x2B740, 0x2B81F), # CJK Unified Ideographs Extension D + (0x2B820, 0x2CEAF), # CJK Unified Ideographs Extension E + (0x2CEB0, 0x2EBEF), # CJK Unified Ideographs Extension F + (0x2F800, 0x2FA1F), # CJK Compatibility Ideographs Supplement + ], + "non_base_ranges": [ + (0x302A, 0x302F), + (0x3190, 0x319F), + ], + "blues": [ + ("他 们 你 來 們 到 和 地 对 對 就 席 我 时 時 會 来 為 能 舰 說 说 这 這 齊 | 军 同 已 愿 既 星 是 景 民 照 现 現 理 用 置 要 軍 那 配 里 開 雷 露 面 顾", "TOP"), + ("个 为 人 他 以 们 你 來 個 們 到 和 大 对 對 就 我 时 時 有 来 為 要 說 说 | 主 些 因 它 想 意 理 生 當 看 着 置 者 自 著 裡 过 还 进 進 過 道 還 里 面", "0"), + (" 些 们 你 來 們 到 和 地 她 将 將 就 年 得 情 最 样 樣 理 能 說 说 这 這 通 | 即 吗 吧 听 呢 品 响 嗎 师 師 收 断 斷 明 眼 間 间 际 陈 限 除 陳 随 際 隨", "HORIZONTAL"), + ("事 前 學 将 將 情 想 或 政 斯 新 样 樣 民 沒 没 然 特 现 現 球 第 經 谁 起 | 例 別 别 制 动 動 吗 嗎 增 指 明 朝 期 构 物 确 种 調 调 費 费 那 都 間 间", "HORIZONTAL | RIGHT"), + ], + }, +] + +CJK_GROUP = ["HANI"] +INDIC_GROUP = ["LIMB", "ORYA", "SYLO", "TIBT"] + +def generate() -> str: + buf = "" + buf += "// THIS FILE IS AUTOGENERATED.\n" + buf += "// Any changes to this file will be overwritten.\n" + buf += "// Use ../scripts/gen_autohint_scripts.py to regenerate.\n\n" + + char_map = {} + + buf += "#[rustfmt::skip]\n" + buf += "pub(super) const SCRIPT_CLASSES: &[ScriptClass] = &[\n" + # some scripts generate multiple styles so keep track of the style index + style_index = 0 + for i, script in enumerate(SCRIPT_CLASSES): + std_chars = script["std_chars"] + blues = script["blues"] + tag = script["tag"] + group = "Default" + if tag in CJK_GROUP: + group = "Cjk" + elif tag in INDIC_GROUP: + group = "Indic" + unicode_tag = tag.lower().capitalize() + has_features = tag in SCRIPTS_WITH_FEATURES + buf += " ScriptClass {\n" + buf += " name: \"{}\",\n".format(script["name"]) + buf += " group: ScriptGroup::{},\n".format(group) + buf += " tag: Tag::new(b\"{}\"),\n".format(unicode_tag) + buf += " hint_top_to_bottom: {},\n".format(str(script["hint_top_to_bottom"]).lower()) + # standard characters + buf += " std_chars: \"{}\",\n".format(script["std_chars"]) + # blue characters + buf += " blues: &[" + if len(blues) != 0: + buf += "\n"; + for blue in blues: + blue_zones = "BlueZones::NONE" + if blue[1] != "0": + zones = list("BlueZones::" + zone for zone in blue[1].split(" | ")) + blue_zones = zones[0]; + for flag in zones[1:]: + blue_zones += ".union(" + flag + ")" + buf += " (\"" + blue[0] + "\"" + buf += ", {}),\n".format(blue_zones) + buf += " ],\n" + else: + buf += "],\n" + buf += " },\n" + if has_features: + style_index += len(STYLE_FEATURES) + bases = set() + # build a char -> (script_ix, is_non_base) map for all ranges + for char_range in script["base_ranges"]: + first = char_range[0] + last = char_range[1] + # inclusive range + for ch in range(first, last + 1): + # Note: FT has overlapping ranges but we choose to keep + # the first one to match behavior + if not ch in char_map: + char_map[ch] = (style_index, False) + bases.add(ch) + for char_range in script["non_base_ranges"]: + first = char_range[0] + last = char_range[1] + # inclusive range + for ch in range(first, last + 1): + if ch in bases: + char_map[ch] = (style_index, True) # True for non-base character + style_index += 1 + buf += "];\n\n" + + # Add some symbolic indices for each script so they can be + # referenced by ScriptClass::LATN for example + buf += "#[allow(unused)]" + buf += "impl ScriptClass {\n" + for i, script in enumerate(SCRIPT_CLASSES): + buf += " pub const {}: usize = {};\n".format(script["tag"], i) + buf += "}\n\n" + + # Now run through scripts again and generate style classes + buf += "#[rustfmt::skip]\n" + buf += "pub(super) const STYLE_CLASSES: &[StyleClass] = &[\n" + style_class_tags = [] + style_index = 0 + for i, script in enumerate(SCRIPT_CLASSES): + tag = script["tag"] + has_features = tag in SCRIPTS_WITH_FEATURES + if has_features: + for feature in STYLE_FEATURES: + name = script["name"] + " " + feature["name"] + feature_tag = feature["tag"] + buf += " StyleClass {{ name: \"{}\", index: {}, script: &SCRIPT_CLASSES[{}], feature: Some(Tag::new(b\"{}\")) }},\n".format(name, style_index, i, feature_tag) + style_index += 1 + style_class_tags.append(tag + "_" + feature_tag.upper()) + name = script["name"] + buf += " StyleClass {{ name: \"{}\", index: {}, script: &SCRIPT_CLASSES[{}], feature: None }},\n".format(name, style_index, i) + style_index += 1 + style_class_tags.append(tag) + buf += "];\n\n"; + + # Symbolic indices for style classes + buf += "#[allow(unused)]" + buf += "impl StyleClass {\n" + for (i, tag) in enumerate(style_class_tags): + buf += " pub const {}: usize = {};\n".format(tag, i) + buf += "}\n\n" + + # build a sorted list from the map + char_list = [] + for ch in char_map: + char_list.append((ch, char_map[ch])) + char_list.sort(key=lambda entry: entry[0]) + + # and merge into ranges + ranges = [] + for entry in char_list: + ch = entry[0] + props = entry[1] + if len(ranges) != 0: + last = ranges[-1]; + # we can merge if same props and this character extends the range + # by 1 + if ch == last[1] + 1 and last[2] == props: + ranges[-1] = (last[0], ch, props) + continue + ranges.append((ch, ch, props)) + + # and finally output the ranges + buf += "#[rustfmt::skip]\n" + buf += "pub(super) const STYLE_RANGES: &[StyleRange] = &[\n" + for char_range in ranges: + first = char_range[0] + last = char_range[1] + props = char_range[2] + kind = "base_range" + if props[1]: + kind = "non_base_range" + buf += " {}({}, {}, {}),\n".format(kind, first, last, props[0]) + buf += "];\n\n" + return buf + +if __name__ == "__main__": + data = generate() + with open("../generated/generated_autohint_styles.rs", "w", encoding="utf-8") as f: + f.write(data) diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,277 @@ +//! Primary attributes typically used for font classification and selection. + +use read_fonts::{ + tables::{ + head::{Head, MacStyle}, + os2::{Os2, SelectionFlags}, + post::Post, + }, + TableProvider, +}; + +/// Stretch, style and weight attributes of a font. +/// +/// Variable fonts may contain axes that modify these attributes. The +/// [new](Self::new) method on this type returns values for the default +/// instance. +/// +/// These are derived from values in the +/// [OS/2](https://learn.microsoft.com/en-us/typography/opentype/spec/os2) if +/// available. Otherwise, they are retrieved from the +/// [head](https://learn.microsoft.com/en-us/typography/opentype/spec/head) +/// table. +#[derive(Copy, Clone, PartialEq, Debug, Default)] +pub struct Attributes { + pub stretch: Stretch, + pub style: Style, + pub weight: Weight, +} + +impl Attributes { + /// Extracts the stretch, style and weight attributes for the default + /// instance of the given font. + pub fn new<'a>(font: &impl TableProvider<'a>) -> Self { + if let Ok(os2) = font.os2() { + // Prefer values from the OS/2 table if it exists. We also use + // the post table to extract the angle for oblique styles. + Self::from_os2_post(os2, font.post().ok()) + } else if let Ok(head) = font.head() { + // Otherwise, fall back to the macStyle field of the head table. + Self::from_head(head) + } else { + Self::default() + } + } + + fn from_os2_post(os2: Os2, post: Option) -> Self { + let stretch = Stretch::from_width_class(os2.us_width_class()); + // Bits 1 and 9 of the fsSelection field signify italic and + // oblique, respectively. + // See: + let fs_selection = os2.fs_selection(); + let style = if fs_selection.contains(SelectionFlags::ITALIC) { + Style::Italic + } else if fs_selection.contains(SelectionFlags::OBLIQUE) { + let angle = post.map(|post| post.italic_angle().to_f64() as f32); + Style::Oblique(angle) + } else { + Style::Normal + }; + // The usWeightClass field is specified with a 1-1000 range, but + // we don't clamp here because variable fonts could potentially + // have a value outside of that range. + // See + let weight = Weight(os2.us_weight_class() as f32); + Self { + stretch, + style, + weight, + } + } + + fn from_head(head: Head) -> Self { + let mac_style = head.mac_style(); + let style = mac_style + .contains(MacStyle::ITALIC) + .then_some(Style::Italic) + .unwrap_or_default(); + let weight = mac_style + .contains(MacStyle::BOLD) + .then_some(Weight::BOLD) + .unwrap_or_default(); + Self { + stretch: Stretch::default(), + style, + weight, + } + } +} + +/// Visual width of a font-- a relative change from the normal aspect +/// ratio, typically in the range 0.5 to 2.0. +/// +/// In variable fonts, this can be controlled with the `wdth` axis. +/// +/// See +#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] +pub struct Stretch(f32); + +impl Stretch { + /// Width that is 50% of normal. + pub const ULTRA_CONDENSED: Self = Self(0.5); + + /// Width that is 62.5% of normal. + pub const EXTRA_CONDENSED: Self = Self(0.625); + + /// Width that is 75% of normal. + pub const CONDENSED: Self = Self(0.75); + + /// Width that is 87.5% of normal. + pub const SEMI_CONDENSED: Self = Self(0.875); + + /// Width that is 100% of normal. + pub const NORMAL: Self = Self(1.0); + + /// Width that is 112.5% of normal. + pub const SEMI_EXPANDED: Self = Self(1.125); + + /// Width that is 125% of normal. + pub const EXPANDED: Self = Self(1.25); + + /// Width that is 150% of normal. + pub const EXTRA_EXPANDED: Self = Self(1.5); + + /// Width that is 200% of normal. + pub const ULTRA_EXPANDED: Self = Self(2.0); +} + +impl Stretch { + /// Creates a new stretch attribute with the given ratio. + pub const fn new(ratio: f32) -> Self { + Self(ratio) + } + + /// Creates a new stretch attribute from the + /// [usWidthClass]() + /// field of the OS/2 table. + fn from_width_class(width_class: u16) -> Self { + // The specified range is 1-9 and Skia simply clamps out of range + // values. We follow. + // See + match width_class { + 0..=1 => Stretch::ULTRA_CONDENSED, + 2 => Stretch::EXTRA_CONDENSED, + 3 => Stretch::CONDENSED, + 4 => Stretch::SEMI_CONDENSED, + 5 => Stretch::NORMAL, + 6 => Stretch::SEMI_EXPANDED, + 7 => Stretch::EXPANDED, + 8 => Stretch::EXTRA_EXPANDED, + _ => Stretch::ULTRA_EXPANDED, + } + } + + /// Returns the stretch attribute as a ratio. + /// + /// This is a linear scaling factor with 1.0 being "normal" width. + pub const fn ratio(self) -> f32 { + self.0 + } + + /// Returns the stretch attribute as a percentage value. + /// + /// This is generally the value associated with the `wdth` axis. + pub fn percentage(self) -> f32 { + self.0 * 100.0 + } +} + +impl Default for Stretch { + fn default() -> Self { + Self::NORMAL + } +} + +/// Visual style or 'slope' of a font. +/// +/// In variable fonts, this can be controlled with the `ital` +/// and `slnt` axes for italic and oblique styles, respectively. +/// +/// See +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub enum Style { + /// An upright or "roman" style. + #[default] + Normal, + /// Generally a slanted style, originally based on semi-cursive forms. + /// This often has a different structure from the normal style. + Italic, + /// Oblique (or slanted) style with an optional angle in degrees, + /// counter-clockwise from the vertical. + Oblique(Option), +} + +/// Visual weight class of a font, typically on a scale from 1.0 to 1000.0. +/// +/// In variable fonts, this can be controlled with the `wght` axis. +/// +/// See +#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] +pub struct Weight(f32); + +impl Weight { + /// Weight value of 100. + pub const THIN: Self = Self(100.0); + + /// Weight value of 200. + pub const EXTRA_LIGHT: Self = Self(200.0); + + /// Weight value of 300. + pub const LIGHT: Self = Self(300.0); + + /// Weight value of 350. + pub const SEMI_LIGHT: Self = Self(350.0); + + /// Weight value of 400. + pub const NORMAL: Self = Self(400.0); + + /// Weight value of 500. + pub const MEDIUM: Self = Self(500.0); + + /// Weight value of 600. + pub const SEMI_BOLD: Self = Self(600.0); + + /// Weight value of 700. + pub const BOLD: Self = Self(700.0); + + /// Weight value of 800. + pub const EXTRA_BOLD: Self = Self(800.0); + + /// Weight value of 900. + pub const BLACK: Self = Self(900.0); + + /// Weight value of 950. + pub const EXTRA_BLACK: Self = Self(950.0); +} + +impl Weight { + /// Creates a new weight attribute with the given value. + pub const fn new(weight: f32) -> Self { + Self(weight) + } + + /// Returns the underlying weight value. + pub const fn value(self) -> f32 { + self.0 + } +} + +impl Default for Weight { + fn default() -> Self { + Self::NORMAL + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::prelude::*; + + #[test] + fn missing_os2() { + let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); + let attrs = font.attributes(); + assert_eq!(attrs.stretch, Stretch::NORMAL); + assert_eq!(attrs.style, Style::Italic); + assert_eq!(attrs.weight, Weight::BOLD); + } + + #[test] + fn so_stylish() { + let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); + let attrs = font.attributes(); + assert_eq!(attrs.stretch, Stretch::SEMI_CONDENSED); + assert_eq!(attrs.style, Style::Oblique(Some(-14.0))); + assert_eq!(attrs.weight, Weight::EXTRA_BOLD); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,510 @@ +//! Mapping of characters (codepoints, not graphemes) to nominal glyph identifiers. +//! +//! If you have never run into character to glyph mapping before +//! [Glyph IDs and the 'cmap' table](https://rsheeter.github.io/font101/#glyph-ids-and-the-cmap-table) +//! might be informative. +//! +//! The functionality in this module provides a 1-to-1 mapping from Unicode +//! characters (or [Unicode variation sequences](http://unicode.org/faq/vs.html)) to +//! nominal or "default" internal glyph identifiers for a given font. +//! This is a necessary first step, but generally insufficient for proper layout of +//! [complex text](https://en.wikipedia.org/wiki/Complex_text_layout) or even +//! simple text containing diacritics and ligatures. +//! +//! Comprehensive mapping of characters to positioned glyphs requires a process called +//! shaping. For more detail, see: [Why do I need a shaping engine?](https://harfbuzz.github.io/why-do-i-need-a-shaping-engine.html) + +use read_fonts::{ + tables::cmap::{ + self, Cmap, Cmap12, Cmap12Iter, Cmap14, Cmap14Iter, Cmap4, Cmap4Iter, CmapSubtable, + EncodingRecord, PlatformId, + }, + types::GlyphId, + FontData, TableProvider, +}; + +pub use read_fonts::tables::cmap::MapVariant; + +/// Mapping of characters to nominal glyph identifiers. +/// +/// The mappings are derived from the [cmap](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap) +/// table. +/// +/// ## Obtaining a Charmap +/// +/// Typically a Charmap is acquired by calling [charmap](crate::MetadataProvider::charmap) on a [FontRef](crate::FontRef). +/// +/// ## Selection strategy +/// +/// Fonts may contain multiple subtables in various formats supporting different encodings. The selection +/// strategy implemented here is designed to choose mappings that capture the broadest available Unicode +/// coverage: +/// +/// * Unicode characters: a symbol mapping subtable is selected if available. Otherwise, subtables supporting +/// the Unicode full repertoire or Basic Multilingual Plane (BMP) are preferred, in that order. Formats +/// [4](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values) +/// and [12](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage) are +/// supported. +/// +/// * Unicode variation sequences: these are provided by a format +/// [14](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences) +/// subtable. +/// +#[derive(Clone, Default)] +pub struct Charmap<'a> { + codepoint_subtable: Option>, + variant_subtable: Option>, +} + +impl<'a> Charmap<'a> { + /// Creates a new character map from the given font. + pub fn new(font: &impl TableProvider<'a>) -> Self { + let Ok(cmap) = font.cmap() else { + return Default::default(); + }; + let selection = MappingSelection::new(&cmap); + Self { + codepoint_subtable: selection + .codepoint_subtable + .map(|subtable| CodepointSubtable { + subtable, + is_symbol: selection.mapping_index.codepoint_subtable_is_symbol, + }), + variant_subtable: selection.variant_subtable, + } + } + + /// Returns true if a suitable Unicode character mapping is available. + pub fn has_map(&self) -> bool { + self.codepoint_subtable.is_some() + } + + /// Returns true if a symbol mapping was selected. + pub fn is_symbol(&self) -> bool { + self.codepoint_subtable + .as_ref() + .map(|x| x.is_symbol) + .unwrap_or(false) + } + + /// Returns true if a Unicode variation sequence mapping is available. + pub fn has_variant_map(&self) -> bool { + self.variant_subtable.is_some() + } + + /// Maps a character to a nominal glyph identifier. + /// + /// Returns `None` if a mapping does not exist. + pub fn map(&self, ch: impl Into) -> Option { + self.codepoint_subtable.as_ref()?.map(ch.into()) + } + + /// Returns an iterator over all mappings of codepoint to nominal glyph + /// identifiers in the character map. + pub fn mappings(&self) -> Mappings<'a> { + self.codepoint_subtable + .as_ref() + .map(|subtable| { + Mappings(match &subtable.subtable { + SupportedSubtable::Format4(cmap4) => MappingsInner::Format4(cmap4.iter()), + SupportedSubtable::Format12(cmap12) => MappingsInner::Format12(cmap12.iter()), + }) + }) + .unwrap_or(Mappings(MappingsInner::None)) + } + + /// Maps a character and variation selector to a nominal glyph identifier. + /// + /// Returns `None` if a mapping does not exist. + pub fn map_variant(&self, ch: impl Into, selector: impl Into) -> Option { + self.variant_subtable.as_ref()?.map_variant(ch, selector) + } + + /// Returns an iterator over all mappings of character and variation + /// selector to nominal glyph identifier in the character map. + pub fn variant_mappings(&self) -> VariantMappings<'a> { + VariantMappings(self.variant_subtable.clone().map(|cmap14| cmap14.iter())) + } +} + +/// Cacheable indices of selected mapping tables for materializing a character +/// map. +/// +/// Since [`Charmap`] carries a lifetime, it is difficult to store in a cache. +/// This type serves as an acceleration structure that allows for construction +/// of a character map while skipping the search for the most suitable Unicode +/// mappings. +#[derive(Copy, Clone, Default, Debug)] +pub struct MappingIndex { + /// Index of Unicode or symbol mapping subtable. + codepoint_subtable: Option, + /// True if the above is a symbol mapping. + codepoint_subtable_is_symbol: bool, + /// Index of Unicode variation selector subtable. + variant_subtable: Option, +} + +impl MappingIndex { + /// Finds the indices of the most suitable Unicode mapping tables in the + /// given font. + pub fn new<'a>(font: &impl TableProvider<'a>) -> Self { + let Ok(cmap) = font.cmap() else { + return Default::default(); + }; + MappingSelection::new(&cmap).mapping_index + } + + /// Creates a new character map for the given font using the tables referenced by + /// the precomputed indices. + /// + /// The font should be the same as the one used to construct this object. + pub fn charmap<'a>(&self, font: &impl TableProvider<'a>) -> Charmap<'a> { + let Ok(cmap) = font.cmap() else { + return Default::default(); + }; + let records = cmap.encoding_records(); + let data = cmap.offset_data(); + Charmap { + codepoint_subtable: self + .codepoint_subtable + .and_then(|index| get_subtable(data, records, index)) + .and_then(SupportedSubtable::new) + .map(|subtable| CodepointSubtable { + subtable, + is_symbol: self.codepoint_subtable_is_symbol, + }), + variant_subtable: self + .variant_subtable + .and_then(|index| get_subtable(data, records, index)) + .and_then(|subtable| match subtable { + CmapSubtable::Format14(cmap14) => Some(cmap14), + _ => None, + }), + } + } +} + +/// Iterator over all mappings of character to nominal glyph identifier +/// in a character map. +/// +/// This is created with the [`Charmap::mappings`] method. +#[derive(Clone)] +pub struct Mappings<'a>(MappingsInner<'a>); + +impl Iterator for Mappings<'_> { + type Item = (u32, GlyphId); + + fn next(&mut self) -> Option { + match &mut self.0 { + MappingsInner::None => None, + MappingsInner::Format4(iter) => iter.next(), + MappingsInner::Format12(iter) => iter.next(), + } + } +} + +#[derive(Clone)] +enum MappingsInner<'a> { + None, + Format4(Cmap4Iter<'a>), + Format12(Cmap12Iter<'a>), +} + +/// Iterator over all mappings of character and variation selector to +/// nominal glyph identifier in a character map. +/// +/// This is created with the [`Charmap::variant_mappings`] method. +#[derive(Clone)] +pub struct VariantMappings<'a>(Option>); + +impl Iterator for VariantMappings<'_> { + type Item = (u32, u32, MapVariant); + + fn next(&mut self) -> Option { + self.0.as_mut()?.next() + } +} + +fn get_subtable<'a>( + data: FontData<'a>, + records: &[EncodingRecord], + index: u16, +) -> Option> { + records + .get(index as usize) + .and_then(|record| record.subtable(data).ok()) +} + +#[derive(Clone)] +struct CodepointSubtable<'a> { + subtable: SupportedSubtable<'a>, + /// True if the subtable is a symbol mapping. + is_symbol: bool, +} + +impl CodepointSubtable<'_> { + fn map(&self, codepoint: u32) -> Option { + self.map_impl(codepoint).or_else(|| { + if self.is_symbol && codepoint <= 0x00FF { + // From HarfBuzz: + // For symbol-encoded OpenType fonts, we duplicate the + // U+F000..F0FF range at U+0000..U+00FF. That's what + // Windows seems to do, and that's hinted about at: + // https://docs.microsoft.com/en-us/typography/opentype/spec/recom + // under "Non-Standard (Symbol) Fonts". + // See + self.map_impl(codepoint + 0xF000) + } else { + None + } + }) + } + + fn map_impl(&self, codepoint: u32) -> Option { + match &self.subtable { + SupportedSubtable::Format4(subtable) => subtable.map_codepoint(codepoint), + SupportedSubtable::Format12(subtable) => subtable.map_codepoint(codepoint), + } + } +} + +#[derive(Clone)] +enum SupportedSubtable<'a> { + Format4(Cmap4<'a>), + Format12(Cmap12<'a>), +} + +impl<'a> SupportedSubtable<'a> { + fn new(subtable: CmapSubtable<'a>) -> Option { + Some(match subtable { + CmapSubtable::Format4(cmap4) => Self::Format4(cmap4), + CmapSubtable::Format12(cmap12) => Self::Format12(cmap12), + _ => return None, + }) + } + + fn from_cmap_record(cmap: &Cmap<'a>, record: &cmap::EncodingRecord) -> Option { + Self::new(record.subtable(cmap.offset_data()).ok()?) + } +} + +/// The mapping kind of a cmap subtable. +/// +/// The ordering is significant and determines the priority of subtable +/// selection (greater is better). +#[derive(Copy, Clone, PartialEq, PartialOrd)] +enum MappingKind { + None = 0, + UnicodeBmp = 1, + UnicodeFull = 2, + Symbol = 3, +} + +/// The result of searching the cmap table for the "best" available +/// subtables. +/// +/// For `codepoint_subtable`, best means either symbol (which is preferred) +/// or a Unicode subtable with the greatest coverage. +/// +/// For `variant_subtable`, best means a format 14 subtable. +struct MappingSelection<'a> { + /// The mapping index accelerator that holds indices of the following + /// subtables. + mapping_index: MappingIndex, + /// Either a symbol subtable or the Unicode subtable with the + /// greatest coverage. + codepoint_subtable: Option>, + /// Subtable that supports mapping Unicode variation sequences. + variant_subtable: Option>, +} + +impl<'a> MappingSelection<'a> { + fn new(cmap: &Cmap<'a>) -> Self { + const ENCODING_MS_SYMBOL: u16 = 0; + const ENCODING_MS_UNICODE_CS: u16 = 1; + const ENCODING_APPLE_ID_UNICODE_32: u16 = 4; + const ENCODING_APPLE_ID_VARIANT_SELECTOR: u16 = 5; + const ENCODING_MS_ID_UCS_4: u16 = 10; + let mut mapping_index = MappingIndex::default(); + let mut mapping_kind = MappingKind::None; + let mut codepoint_subtable = None; + let mut variant_subtable = None; + let mut maybe_choose_subtable = |kind, index, subtable| { + if kind > mapping_kind { + mapping_kind = kind; + mapping_index.codepoint_subtable_is_symbol = kind == MappingKind::Symbol; + mapping_index.codepoint_subtable = Some(index as u16); + codepoint_subtable = Some(subtable); + } + }; + // This generally follows the same strategy as FreeType, searching the encoding + // records in reverse and prioritizing UCS-4 subtables over UCS-2. + // See + // The exception is that we prefer a symbol subtable over all others which matches the behavior + // of HarfBuzz. + // See + for (i, record) in cmap.encoding_records().iter().enumerate().rev() { + match (record.platform_id(), record.encoding_id()) { + (PlatformId::Unicode, ENCODING_APPLE_ID_VARIANT_SELECTOR) => { + // Unicode variation sequences + if let Ok(CmapSubtable::Format14(subtable)) = + record.subtable(cmap.offset_data()) + { + if variant_subtable.is_none() { + mapping_index.variant_subtable = Some(i as u16); + variant_subtable = Some(subtable); + } + } + } + (PlatformId::Windows, ENCODING_MS_SYMBOL) => { + // Symbol + if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { + maybe_choose_subtable(MappingKind::Symbol, i, subtable); + } + } + (PlatformId::Windows, ENCODING_MS_ID_UCS_4) + | (PlatformId::Unicode, ENCODING_APPLE_ID_UNICODE_32) => { + // Unicode full repertoire + if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { + maybe_choose_subtable(MappingKind::UnicodeFull, i, subtable); + } + } + (PlatformId::ISO, _) + | (PlatformId::Unicode, _) + | (PlatformId::Windows, ENCODING_MS_UNICODE_CS) => { + // Unicode BMP only + if let Some(subtable) = SupportedSubtable::from_cmap_record(cmap, record) { + maybe_choose_subtable(MappingKind::UnicodeBmp, i, subtable); + } + } + _ => {} + } + } + Self { + mapping_index, + codepoint_subtable, + variant_subtable, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::MetadataProvider; + use read_fonts::FontRef; + + #[test] + fn choose_format_12_over_4() { + let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); + let charmap = font.charmap(); + assert!(matches!( + charmap.codepoint_subtable.unwrap().subtable, + SupportedSubtable::Format12(..) + )); + } + + #[test] + fn choose_format_4() { + let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); + let charmap = font.charmap(); + assert!(matches!( + charmap.codepoint_subtable.unwrap().subtable, + SupportedSubtable::Format4(..) + )); + } + + #[test] + fn choose_symbol() { + let font = FontRef::new(font_test_data::CMAP4_SYMBOL_PUA).unwrap(); + let charmap = font.charmap(); + assert!(charmap.is_symbol()); + assert!(matches!( + charmap.codepoint_subtable.unwrap().subtable, + SupportedSubtable::Format4(..) + )); + } + + #[test] + fn map_format_4() { + let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); + let charmap = font.charmap(); + assert_eq!(charmap.map('A'), Some(GlyphId::new(1))); + assert_eq!(charmap.map('À'), Some(GlyphId::new(2))); + assert_eq!(charmap.map('`'), Some(GlyphId::new(3))); + assert_eq!(charmap.map('B'), None); + } + + #[test] + fn map_format_12() { + let font = FontRef::new(font_test_data::CMAP12_FONT1).unwrap(); + let charmap = font.charmap(); + assert_eq!(charmap.map(' '), None); + assert_eq!(charmap.map(0x101723_u32), Some(GlyphId::new(1))); + assert_eq!(charmap.map(0x101725_u32), Some(GlyphId::new(3))); + assert_eq!(charmap.map(0x102523_u32), Some(GlyphId::new(6))); + assert_eq!(charmap.map(0x102526_u32), Some(GlyphId::new(9))); + assert_eq!(charmap.map(0x102527_u32), Some(GlyphId::new(10))); + } + + #[test] + fn map_symbol_pua() { + let font = FontRef::new(font_test_data::CMAP4_SYMBOL_PUA).unwrap(); + let charmap = font.charmap(); + assert!(charmap.codepoint_subtable.as_ref().unwrap().is_symbol); + assert_eq!(charmap.map(0xF001_u32), Some(GlyphId::new(1))); + assert_eq!(charmap.map(0xF002_u32), Some(GlyphId::new(2))); + assert_eq!(charmap.map(0xF003_u32), Some(GlyphId::new(3))); + assert_eq!(charmap.map(0xF0FE_u32), Some(GlyphId::new(4))); + // The following don't exist in the cmap table and are remapped into the U+F000..F0FF range + // due to the selection of a symbol mapping subtable. + assert_eq!(charmap.map(0x1_u32), Some(GlyphId::new(1))); + assert_eq!(charmap.map(0x2_u32), Some(GlyphId::new(2))); + assert_eq!(charmap.map(0x3_u32), Some(GlyphId::new(3))); + assert_eq!(charmap.map(0xFE_u32), Some(GlyphId::new(4))); + } + + #[test] + fn map_variants() { + use super::MapVariant::*; + let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); + let charmap = font.charmap(); + let selector = '\u{e0100}'; + assert_eq!(charmap.map_variant('a', selector), None); + assert_eq!(charmap.map_variant('\u{4e00}', selector), Some(UseDefault)); + assert_eq!(charmap.map_variant('\u{4e06}', selector), Some(UseDefault)); + assert_eq!( + charmap.map_variant('\u{4e08}', selector), + Some(Variant(GlyphId::new(25))) + ); + assert_eq!( + charmap.map_variant('\u{4e09}', selector), + Some(Variant(GlyphId::new(26))) + ); + } + + #[test] + fn mappings() { + for font_data in [ + font_test_data::VAZIRMATN_VAR, + font_test_data::CMAP12_FONT1, + font_test_data::SIMPLE_GLYF, + font_test_data::CMAP4_SYMBOL_PUA, + ] { + let font = FontRef::new(font_data).unwrap(); + let charmap = font.charmap(); + for (codepoint, glyph_id) in charmap.mappings() { + assert_eq!(charmap.map(codepoint), Some(glyph_id)); + } + } + } + + #[test] + fn variant_mappings() { + let font = FontRef::new(font_test_data::CMAP14_FONT1).unwrap(); + let charmap = font.charmap(); + for (codepoint, selector, variant) in charmap.variant_mappings() { + assert_eq!(charmap.map_variant(codepoint, selector), Some(variant)); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,352 @@ +//! Internal "small" style collection types. + +use alloc::vec::Vec; +use core::hash::{Hash, Hasher}; + +/// A growable vector type with inline storage optimization. +/// +/// Note that unlike the real `SmallVec`, this only works with types that +/// are `Copy + Default` to simplify our implementation. +#[derive(Clone)] +pub(crate) struct SmallVec(Storage); + +impl SmallVec +where + T: Copy + Default, +{ + /// Creates a new, empty `SmallVec`. + pub fn new() -> Self { + Self(Storage::Inline([T::default(); N], 0)) + } + + /// Creates a new `SmallVec` of the given length with each element + /// containing a copy of `value`. + pub fn with_len(len: usize, value: T) -> Self { + if len <= N { + Self(Storage::Inline([value; N], len)) + } else { + let mut vec = Vec::new(); + vec.resize(len, value); + Self(Storage::Heap(vec)) + } + } + + /// Clears the vector, removing all values. + pub fn clear(&mut self) { + match &mut self.0 { + Storage::Inline(_buf, len) => *len = 0, + Storage::Heap(vec) => vec.clear(), + } + } + + /// Tries to reserve capacity for at least `additional` more elements. + pub fn try_reserve(&mut self, additional: usize) -> bool { + match &mut self.0 { + Storage::Inline(buf, len) => { + let new_cap = *len + additional; + if new_cap > N { + let mut vec = Vec::new(); + if vec.try_reserve(new_cap).is_err() { + return false; + } + vec.extend_from_slice(&buf[..*len]); + self.0 = Storage::Heap(vec); + } + } + Storage::Heap(vec) => { + if vec.try_reserve(additional).is_err() { + return false; + } + } + } + true + } + + /// Appends an element to the back of the collection. + pub fn push(&mut self, value: T) { + match &mut self.0 { + Storage::Inline(buf, len) => { + if *len + 1 > N { + let mut vec = Vec::with_capacity(*len + 1); + vec.extend_from_slice(&buf[..*len]); + vec.push(value); + self.0 = Storage::Heap(vec); + } else { + buf[*len] = value; + *len += 1; + } + } + Storage::Heap(vec) => vec.push(value), + } + } + + /// Removes and returns the value at the back of the collection. + pub fn pop(&mut self) -> Option { + match &mut self.0 { + Storage::Inline(buf, len) => { + if *len > 0 { + *len -= 1; + Some(buf[*len]) + } else { + None + } + } + Storage::Heap(vec) => vec.pop(), + } + } + + /// Shortens the vector, keeping the first `len` elements. + pub fn truncate(&mut self, len: usize) { + match &mut self.0 { + Storage::Inline(_buf, inline_len) => { + *inline_len = len.min(*inline_len); + } + Storage::Heap(vec) => vec.truncate(len), + } + } +} + +impl SmallVec { + /// Extracts a slice containing the entire vector. + pub fn as_slice(&self) -> &[T] { + match &self.0 { + Storage::Inline(buf, len) => &buf[..*len], + Storage::Heap(vec) => vec.as_slice(), + } + } + + /// Extracts a mutable slice containing the entire vector. + pub fn as_mut_slice(&mut self) -> &mut [T] { + match &mut self.0 { + Storage::Inline(buf, len) => &mut buf[..*len], + Storage::Heap(vec) => vec.as_mut_slice(), + } + } +} + +impl Default for SmallVec +where + T: Copy + Default, +{ + fn default() -> Self { + Self::new() + } +} + +impl core::ops::Deref for SmallVec { + type Target = [T]; + + fn deref(&self) -> &Self::Target { + self.as_slice() + } +} + +impl core::ops::DerefMut for SmallVec { + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() + } +} + +impl Hash for SmallVec +where + T: Hash, +{ + fn hash(&self, state: &mut H) { + self.as_slice().hash(state); + } +} + +impl PartialEq for SmallVec +where + T: PartialEq, +{ + fn eq(&self, other: &Self) -> bool { + self.as_slice() == other.as_slice() + } +} + +impl PartialEq<[T]> for SmallVec +where + T: PartialEq, +{ + fn eq(&self, other: &[T]) -> bool { + self.as_slice() == other + } +} + +impl Eq for SmallVec where T: Eq {} + +impl core::fmt::Debug for SmallVec +where + T: core::fmt::Debug, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_list().entries(self.as_slice().iter()).finish() + } +} + +impl<'a, T, const N: usize> IntoIterator for &'a SmallVec { + type IntoIter = core::slice::Iter<'a, T>; + type Item = &'a T; + + fn into_iter(self) -> Self::IntoIter { + self.as_slice().iter() + } +} + +impl<'a, T, const N: usize> IntoIterator for &'a mut SmallVec { + type IntoIter = core::slice::IterMut<'a, T>; + type Item = &'a mut T; + + fn into_iter(self) -> Self::IntoIter { + self.as_mut_slice().iter_mut() + } +} + +impl IntoIterator for SmallVec +where + T: Copy, +{ + type IntoIter = IntoIter; + type Item = T; + + fn into_iter(self) -> Self::IntoIter { + IntoIter { vec: self, pos: 0 } + } +} + +#[derive(Clone)] +pub(crate) struct IntoIter { + vec: SmallVec, + pos: usize, +} + +impl Iterator for IntoIter +where + T: Copy, +{ + type Item = T; + + fn next(&mut self) -> Option { + let value = self.vec.get(self.pos)?; + self.pos += 1; + Some(*value) + } +} + +#[derive(Clone)] +enum Storage { + Inline([T; N], usize), + Heap(Vec), +} + +#[cfg(test)] +mod test { + use super::{SmallVec, Storage}; + + #[test] + fn choose_inline() { + let vec = SmallVec::<_, 4>::with_len(4, 0); + assert!(matches!(vec.0, Storage::Inline(..))); + assert_eq!(vec.len(), 4); + } + + #[test] + fn choose_heap() { + let vec = SmallVec::<_, 4>::with_len(5, 0); + assert!(matches!(vec.0, Storage::Heap(..))); + assert_eq!(vec.len(), 5); + } + + #[test] + fn store_and_read_inline() { + let mut vec = SmallVec::<_, 8>::with_len(8, 0); + for (i, value) in vec.iter_mut().enumerate() { + *value = i * 2; + } + let expected = [0, 2, 4, 6, 8, 10, 12, 14]; + assert_eq!(vec.as_slice(), &expected); + assert_eq!(format!("{vec:?}"), format!("{expected:?}")); + } + + #[test] + fn store_and_read_heap() { + let mut vec = SmallVec::<_, 4>::with_len(8, 0); + for (i, value) in vec.iter_mut().enumerate() { + *value = i * 2; + } + let expected = [0, 2, 4, 6, 8, 10, 12, 14]; + assert_eq!(vec.as_slice(), &expected); + assert_eq!(format!("{vec:?}"), format!("{expected:?}")); + } + + #[test] + fn spill_to_heap() { + let mut vec = SmallVec::<_, 4>::new(); + for i in 0..4 { + vec.push(i); + } + assert!(matches!(vec.0, Storage::Inline(..))); + vec.push(4); + assert!(matches!(vec.0, Storage::Heap(..))); + let expected = [0, 1, 2, 3, 4]; + assert_eq!(vec.as_slice(), &expected); + } + + #[test] + fn clear_inline() { + let mut vec = SmallVec::<_, 4>::new(); + for i in 0..4 { + vec.push(i); + } + assert!(matches!(vec.0, Storage::Inline(..))); + assert_eq!(vec.len(), 4); + vec.clear(); + assert_eq!(vec.len(), 0); + } + + #[test] + fn clear_heap() { + let mut vec = SmallVec::<_, 3>::new(); + for i in 0..4 { + vec.push(i); + } + assert!(matches!(vec.0, Storage::Heap(..))); + assert_eq!(vec.len(), 4); + vec.clear(); + assert_eq!(vec.len(), 0); + } + + #[test] + fn reserve() { + let mut vec = SmallVec::<_, 3>::new(); + for i in 0..2 { + vec.push(i); + } + assert!(matches!(vec.0, Storage::Inline(..))); + assert!(vec.try_reserve(1)); + // still inline after reserving 1 + assert!(matches!(vec.0, Storage::Inline(..))); + assert!(vec.try_reserve(2)); + // reserving 2 spills to heap + assert!(matches!(vec.0, Storage::Heap(..))); + } + + #[test] + fn iter() { + let mut vec = SmallVec::<_, 3>::new(); + for i in 0..3 { + vec.push(i); + } + assert!(&[0, 1, 2].iter().eq(vec.iter())); + } + + #[test] + fn into_iter() { + let mut vec = SmallVec::<_, 3>::new(); + for i in 0..3 { + vec.push(i); + } + assert!([0, 1, 2].into_iter().eq(vec.into_iter())); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,597 @@ +//! COLR table instance. + +use read_fonts::{ + tables::{ + colr::*, + variations::{ + DeltaSetIndex, DeltaSetIndexMap, FloatItemDelta, FloatItemDeltaTarget, + ItemVariationStore, + }, + }, + types::{BoundingBox, F2Dot14, GlyphId16, Point}, + ReadError, +}; + +use core::ops::{Deref, Range}; + +/// Unique paint identifier used for detecting cycles in the paint graph. +pub type PaintId = usize; + +/// Combination of a `COLR` table and a location in variation space for +/// resolving paints. +/// +/// See [`resolve_paint`], [`ColorStops::resolve`] and [`resolve_clip_box`]. +#[derive(Clone)] +pub struct ColrInstance<'a> { + colr: Colr<'a>, + index_map: Option>, + var_store: Option>, + coords: &'a [F2Dot14], +} + +impl<'a> ColrInstance<'a> { + /// Creates a new instance for the given `COLR` table and normalized variation + /// coordinates. + pub fn new(colr: Colr<'a>, coords: &'a [F2Dot14]) -> Self { + let index_map = colr.var_index_map().and_then(|res| res.ok()); + let var_store = colr.item_variation_store().and_then(|res| res.ok()); + Self { + colr, + coords, + index_map, + var_store, + } + } + + /// Computes a sequence of N variation deltas starting at the given + /// `var_base` index. + fn var_deltas(&self, var_index_base: u32) -> [FloatItemDelta; N] { + // Magic value that indicates deltas should not be applied. + const NO_VARIATION_DELTAS: u32 = 0xFFFFFFFF; + // Note: FreeType never returns an error for these lookups, so + // we do the same and just `unwrap_or_default` on var store + // errors. + // See + let mut deltas = [FloatItemDelta::ZERO; N]; + if self.coords.is_empty() + || self.var_store.is_none() + || var_index_base == NO_VARIATION_DELTAS + { + return deltas; + } + let var_store = self.var_store.as_ref().unwrap(); + if let Some(index_map) = self.index_map.as_ref() { + for (i, delta) in deltas.iter_mut().enumerate() { + let var_index = var_index_base + i as u32; + if let Ok(delta_ix) = index_map.get(var_index) { + *delta = var_store + .compute_float_delta(delta_ix, self.coords) + .unwrap_or_default(); + } + } + } else { + for (i, delta) in deltas.iter_mut().enumerate() { + let var_index = var_index_base + i as u32; + // If we don't have a var index map, use our index as the inner + // component and set the outer to 0. + let delta_ix = DeltaSetIndex { + outer: 0, + inner: var_index as u16, + }; + *delta = var_store + .compute_float_delta(delta_ix, self.coords) + .unwrap_or_default(); + } + } + deltas + } +} + +impl<'a> Deref for ColrInstance<'a> { + type Target = Colr<'a>; + + fn deref(&self) -> &Self::Target { + &self.colr + } +} + +/// Resolves a clip box, applying variation deltas using the given +/// instance. +pub fn resolve_clip_box(instance: &ColrInstance, clip_box: &ClipBox) -> BoundingBox { + match clip_box { + ClipBox::Format1(cbox) => BoundingBox { + x_min: cbox.x_min().to_i16() as f32, + y_min: cbox.y_min().to_i16() as f32, + x_max: cbox.x_max().to_i16() as f32, + y_max: cbox.y_max().to_i16() as f32, + }, + ClipBox::Format2(cbox) => { + let deltas = instance.var_deltas::<4>(cbox.var_index_base()); + BoundingBox { + x_min: cbox.x_min().apply_float_delta(deltas[0]), + y_min: cbox.y_min().apply_float_delta(deltas[1]), + x_max: cbox.x_max().apply_float_delta(deltas[2]), + y_max: cbox.y_max().apply_float_delta(deltas[3]), + } + } + } +} + +/// Simplified version of a [`ColorStop`] or [`VarColorStop`] with applied +/// variation deltas. +#[derive(Clone, Debug)] +pub struct ResolvedColorStop { + pub offset: f32, + pub palette_index: u16, + pub alpha: f32, +} + +/// Collection of [`ColorStop`] or [`VarColorStop`]. +// Note: only one of these fields is used at any given time, but this structure +// was chosen over the obvious enum approach for simplicity in generating a +// single concrete type for the `impl Iterator` return type of the `resolve` +// method. +#[derive(Clone)] +pub struct ColorStops<'a> { + stops: &'a [ColorStop], + var_stops: &'a [VarColorStop], +} + +impl ColorStops<'_> { + pub fn len(&self) -> usize { + self.stops.len() + self.var_stops.len() + } + + pub fn is_empty(&self) -> bool { + self.stops.is_empty() && self.var_stops.is_empty() + } +} + +impl<'a> From> for ColorStops<'a> { + fn from(value: ColorLine<'a>) -> Self { + Self { + stops: value.color_stops(), + var_stops: &[], + } + } +} + +impl<'a> From> for ColorStops<'a> { + fn from(value: VarColorLine<'a>) -> Self { + Self { + stops: &[], + var_stops: value.color_stops(), + } + } +} + +impl<'a> ColorStops<'a> { + /// Returns an iterator yielding resolved color stops with variation deltas + /// applied. + pub fn resolve( + &self, + instance: &'a ColrInstance<'a>, + ) -> impl Iterator + 'a { + self.stops + .iter() + .map(|stop| ResolvedColorStop { + offset: stop.stop_offset().to_f32(), + palette_index: stop.palette_index(), + alpha: stop.alpha().to_f32(), + }) + .chain(self.var_stops.iter().map(|stop| { + let deltas = instance.var_deltas::<2>(stop.var_index_base()); + ResolvedColorStop { + offset: stop.stop_offset().apply_float_delta(deltas[0]), + palette_index: stop.palette_index(), + alpha: stop.alpha().apply_float_delta(deltas[1]), + } + })) + } +} + +/// Simplified version of `Paint` with applied variation deltas. +/// +/// These are constructed with the [`resolve_paint`] function. +/// +/// This is roughly equivalent to FreeType's +/// [`FT_COLR_Paint`](https://freetype.org/freetype2/docs/reference/ft2-layer_management.html#ft_colr_paint) +/// type. +pub enum ResolvedPaint<'a> { + ColrLayers { + range: Range, + }, + Solid { + palette_index: u16, + alpha: f32, + }, + LinearGradient { + x0: f32, + y0: f32, + x1: f32, + y1: f32, + x2: f32, + y2: f32, + color_stops: ColorStops<'a>, + extend: Extend, + }, + RadialGradient { + x0: f32, + y0: f32, + radius0: f32, + x1: f32, + y1: f32, + radius1: f32, + color_stops: ColorStops<'a>, + extend: Extend, + }, + SweepGradient { + center_x: f32, + center_y: f32, + start_angle: f32, + end_angle: f32, + color_stops: ColorStops<'a>, + extend: Extend, + }, + Glyph { + glyph_id: GlyphId16, + paint: Paint<'a>, + }, + ColrGlyph { + glyph_id: GlyphId16, + }, + Transform { + xx: f32, + yx: f32, + xy: f32, + yy: f32, + dx: f32, + dy: f32, + paint: Paint<'a>, + }, + Translate { + dx: f32, + dy: f32, + paint: Paint<'a>, + }, + Scale { + scale_x: f32, + scale_y: f32, + around_center: Option>, + paint: Paint<'a>, + }, + Rotate { + angle: f32, + around_center: Option>, + paint: Paint<'a>, + }, + Skew { + x_skew_angle: f32, + y_skew_angle: f32, + around_center: Option>, + paint: Paint<'a>, + }, + Composite { + source_paint: Paint<'a>, + mode: CompositeMode, + backdrop_paint: Paint<'a>, + }, +} + +/// Resolves this paint with the given instance. +/// +/// Resolving means that all numeric values are converted to 32-bit floating +/// point, variation deltas are applied (also computed fully in floating +/// point), and the various transform paints are collapsed into a single value +/// for their category (transform, translate, scale, rotate and skew). +/// +/// This provides a simpler type for consumers that are more interested +/// in extracting the semantics of the graph rather than working with the +/// raw encoded structures. +pub fn resolve_paint<'a>( + instance: &ColrInstance<'a>, + paint: &Paint<'a>, +) -> Result, ReadError> { + Ok(match paint { + Paint::ColrLayers(layers) => { + let start = layers.first_layer_index() as usize; + ResolvedPaint::ColrLayers { + range: start..start + layers.num_layers() as usize, + } + } + Paint::Solid(solid) => ResolvedPaint::Solid { + palette_index: solid.palette_index(), + alpha: solid.alpha().to_f32(), + }, + Paint::VarSolid(solid) => { + let deltas = instance.var_deltas::<1>(solid.var_index_base()); + ResolvedPaint::Solid { + palette_index: solid.palette_index(), + alpha: solid.alpha().apply_float_delta(deltas[0]), + } + } + Paint::LinearGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + ResolvedPaint::LinearGradient { + x0: gradient.x0().to_i16() as f32, + y0: gradient.y0().to_i16() as f32, + x1: gradient.x1().to_i16() as f32, + y1: gradient.y1().to_i16() as f32, + x2: gradient.x2().to_i16() as f32, + y2: gradient.y2().to_i16() as f32, + color_stops: color_line.into(), + extend, + } + } + Paint::VarLinearGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + let deltas = instance.var_deltas::<6>(gradient.var_index_base()); + ResolvedPaint::LinearGradient { + x0: gradient.x0().apply_float_delta(deltas[0]), + y0: gradient.y0().apply_float_delta(deltas[1]), + x1: gradient.x1().apply_float_delta(deltas[2]), + y1: gradient.y1().apply_float_delta(deltas[3]), + x2: gradient.x2().apply_float_delta(deltas[4]), + y2: gradient.y2().apply_float_delta(deltas[5]), + color_stops: color_line.into(), + extend, + } + } + Paint::RadialGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + ResolvedPaint::RadialGradient { + x0: gradient.x0().to_i16() as f32, + y0: gradient.y0().to_i16() as f32, + radius0: gradient.radius0().to_u16() as f32, + x1: gradient.x1().to_i16() as f32, + y1: gradient.y1().to_i16() as f32, + radius1: gradient.radius1().to_u16() as f32, + color_stops: color_line.into(), + extend, + } + } + Paint::VarRadialGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + let deltas = instance.var_deltas::<6>(gradient.var_index_base()); + ResolvedPaint::RadialGradient { + x0: gradient.x0().apply_float_delta(deltas[0]), + y0: gradient.y0().apply_float_delta(deltas[1]), + radius0: gradient.radius0().apply_float_delta(deltas[2]), + x1: gradient.x1().apply_float_delta(deltas[3]), + y1: gradient.y1().apply_float_delta(deltas[4]), + radius1: gradient.radius1().apply_float_delta(deltas[5]), + color_stops: color_line.into(), + extend, + } + } + Paint::SweepGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + ResolvedPaint::SweepGradient { + center_x: gradient.center_x().to_i16() as f32, + center_y: gradient.center_y().to_i16() as f32, + start_angle: gradient.start_angle().to_f32(), + end_angle: gradient.end_angle().to_f32(), + color_stops: color_line.into(), + extend, + } + } + Paint::VarSweepGradient(gradient) => { + let color_line = gradient.color_line()?; + let extend = color_line.extend(); + let deltas = instance.var_deltas::<4>(gradient.var_index_base()); + ResolvedPaint::SweepGradient { + center_x: gradient.center_x().apply_float_delta(deltas[0]), + center_y: gradient.center_y().apply_float_delta(deltas[1]), + start_angle: gradient.start_angle().apply_float_delta(deltas[2]), + end_angle: gradient.end_angle().apply_float_delta(deltas[3]), + color_stops: color_line.into(), + extend, + } + } + Paint::Glyph(glyph) => ResolvedPaint::Glyph { + glyph_id: glyph.glyph_id(), + paint: glyph.paint()?, + }, + Paint::ColrGlyph(glyph) => ResolvedPaint::ColrGlyph { + glyph_id: glyph.glyph_id(), + }, + Paint::Transform(transform) => { + let affine = transform.transform()?; + let paint = transform.paint()?; + ResolvedPaint::Transform { + xx: affine.xx().to_f32(), + yx: affine.yx().to_f32(), + xy: affine.xy().to_f32(), + yy: affine.yy().to_f32(), + dx: affine.dx().to_f32(), + dy: affine.dy().to_f32(), + paint, + } + } + Paint::VarTransform(transform) => { + let affine = transform.transform()?; + let paint = transform.paint()?; + let deltas = instance.var_deltas::<6>(affine.var_index_base()); + ResolvedPaint::Transform { + xx: affine.xx().apply_float_delta(deltas[0]), + yx: affine.yx().apply_float_delta(deltas[1]), + xy: affine.xy().apply_float_delta(deltas[2]), + yy: affine.yy().apply_float_delta(deltas[3]), + dx: affine.dx().apply_float_delta(deltas[4]), + dy: affine.dy().apply_float_delta(deltas[5]), + paint, + } + } + Paint::Translate(transform) => ResolvedPaint::Translate { + dx: transform.dx().to_i16() as f32, + dy: transform.dy().to_i16() as f32, + paint: transform.paint()?, + }, + Paint::VarTranslate(transform) => { + let deltas = instance.var_deltas::<2>(transform.var_index_base()); + ResolvedPaint::Translate { + dx: transform.dx().apply_float_delta(deltas[0]), + dy: transform.dy().apply_float_delta(deltas[1]), + paint: transform.paint()?, + } + } + Paint::Scale(transform) => ResolvedPaint::Scale { + scale_x: transform.scale_x().to_f32(), + scale_y: transform.scale_y().to_f32(), + around_center: None, + paint: transform.paint()?, + }, + Paint::VarScale(transform) => { + let deltas = instance.var_deltas::<2>(transform.var_index_base()); + ResolvedPaint::Scale { + scale_x: transform.scale_x().apply_float_delta(deltas[0]), + scale_y: transform.scale_y().apply_float_delta(deltas[1]), + around_center: None, + paint: transform.paint()?, + } + } + Paint::ScaleAroundCenter(transform) => ResolvedPaint::Scale { + scale_x: transform.scale_x().to_f32(), + scale_y: transform.scale_y().to_f32(), + around_center: Some(Point::new( + transform.center_x().to_i16() as f32, + transform.center_y().to_i16() as f32, + )), + paint: transform.paint()?, + }, + Paint::VarScaleAroundCenter(transform) => { + let deltas = instance.var_deltas::<4>(transform.var_index_base()); + ResolvedPaint::Scale { + scale_x: transform.scale_x().apply_float_delta(deltas[0]), + scale_y: transform.scale_y().apply_float_delta(deltas[1]), + around_center: Some(Point::new( + transform.center_x().apply_float_delta(deltas[2]), + transform.center_y().apply_float_delta(deltas[3]), + )), + paint: transform.paint()?, + } + } + Paint::ScaleUniform(transform) => { + let scale = transform.scale().to_f32(); + ResolvedPaint::Scale { + scale_x: scale, + scale_y: scale, + around_center: None, + paint: transform.paint()?, + } + } + Paint::VarScaleUniform(transform) => { + let deltas = instance.var_deltas::<1>(transform.var_index_base()); + let scale = transform.scale().apply_float_delta(deltas[0]); + ResolvedPaint::Scale { + scale_x: scale, + scale_y: scale, + around_center: None, + paint: transform.paint()?, + } + } + Paint::ScaleUniformAroundCenter(transform) => { + let scale = transform.scale().to_f32(); + ResolvedPaint::Scale { + scale_x: scale, + scale_y: scale, + around_center: Some(Point::new( + transform.center_x().to_i16() as f32, + transform.center_y().to_i16() as f32, + )), + paint: transform.paint()?, + } + } + Paint::VarScaleUniformAroundCenter(transform) => { + let deltas = instance.var_deltas::<3>(transform.var_index_base()); + let scale = transform.scale().apply_float_delta(deltas[0]); + ResolvedPaint::Scale { + scale_x: scale, + scale_y: scale, + around_center: Some(Point::new( + transform.center_x().apply_float_delta(deltas[1]), + transform.center_y().apply_float_delta(deltas[2]), + )), + paint: transform.paint()?, + } + } + Paint::Rotate(transform) => ResolvedPaint::Rotate { + angle: transform.angle().to_f32(), + around_center: None, + paint: transform.paint()?, + }, + Paint::VarRotate(transform) => { + let deltas = instance.var_deltas::<1>(transform.var_index_base()); + ResolvedPaint::Rotate { + angle: transform.angle().apply_float_delta(deltas[0]), + around_center: None, + paint: transform.paint()?, + } + } + Paint::RotateAroundCenter(transform) => ResolvedPaint::Rotate { + angle: transform.angle().to_f32(), + around_center: Some(Point::new( + transform.center_x().to_i16() as f32, + transform.center_y().to_i16() as f32, + )), + paint: transform.paint()?, + }, + Paint::VarRotateAroundCenter(transform) => { + let deltas = instance.var_deltas::<3>(transform.var_index_base()); + ResolvedPaint::Rotate { + angle: transform.angle().apply_float_delta(deltas[0]), + around_center: Some(Point::new( + transform.center_x().apply_float_delta(deltas[1]), + transform.center_y().apply_float_delta(deltas[2]), + )), + paint: transform.paint()?, + } + } + Paint::Skew(transform) => ResolvedPaint::Skew { + x_skew_angle: transform.x_skew_angle().to_f32(), + y_skew_angle: transform.y_skew_angle().to_f32(), + around_center: None, + paint: transform.paint()?, + }, + Paint::VarSkew(transform) => { + let deltas = instance.var_deltas::<2>(transform.var_index_base()); + ResolvedPaint::Skew { + x_skew_angle: transform.x_skew_angle().apply_float_delta(deltas[0]), + y_skew_angle: transform.y_skew_angle().apply_float_delta(deltas[1]), + around_center: None, + paint: transform.paint()?, + } + } + Paint::SkewAroundCenter(transform) => ResolvedPaint::Skew { + x_skew_angle: transform.x_skew_angle().to_f32(), + y_skew_angle: transform.y_skew_angle().to_f32(), + around_center: Some(Point::new( + transform.center_x().to_i16() as f32, + transform.center_y().to_i16() as f32, + )), + paint: transform.paint()?, + }, + Paint::VarSkewAroundCenter(transform) => { + let deltas = instance.var_deltas::<4>(transform.var_index_base()); + ResolvedPaint::Skew { + x_skew_angle: transform.x_skew_angle().apply_float_delta(deltas[0]), + y_skew_angle: transform.y_skew_angle().apply_float_delta(deltas[1]), + around_center: Some(Point::new( + transform.center_x().apply_float_delta(deltas[2]), + transform.center_y().apply_float_delta(deltas[3]), + )), + paint: transform.paint()?, + } + } + Paint::Composite(composite) => ResolvedPaint::Composite { + source_paint: composite.source_paint()?, + mode: composite.composite_mode(), + backdrop_paint: composite.backdrop_paint()?, + }, + }) +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,535 @@ +//! Drawing color glyphs. +//! +//! # Examples +//! ## Retrieve the clip box of a COLRv1 glyph if it has one: +//! +//! ``` +//! # use core::result::Result; +//! # use skrifa::{instance::{Size, Location}, color::{ColorGlyphFormat, ColorPainter, PaintError}, GlyphId, MetadataProvider}; +//! # fn get_colr_bb(font: read_fonts::FontRef, color_painter_impl : &mut impl ColorPainter, glyph_id : GlyphId, size: Size) -> Result<(), PaintError> { +//! match font.color_glyphs() +//! .get_with_format(glyph_id, ColorGlyphFormat::ColrV1) +//! .expect("Glyph not found.") +//! .bounding_box(&Location::default(), size) +//! { +//! Some(bounding_box) => { +//! println!("Bounding box is {:?}", bounding_box); +//! } +//! None => { +//! println!("Glyph has no clip box."); +//! } +//! } +//! # Ok(()) +//! # } +//! ``` +//! +//! ## Paint a COLRv1 glyph given a font, and a glyph id and a [`ColorPainter`] implementation: +//! ``` +//! # use core::result::Result; +//! # use skrifa::{instance::{Size, Location}, color::{ColorGlyphFormat, ColorPainter, PaintError}, GlyphId, MetadataProvider}; +//! # fn paint_colr(font: read_fonts::FontRef, color_painter_impl : &mut impl ColorPainter, glyph_id : GlyphId) -> Result<(), PaintError> { +//! let color_glyph = font.color_glyphs() +//! .get_with_format(glyph_id, ColorGlyphFormat::ColrV1) +//! .expect("Glyph not found"); +//! color_glyph.paint(&Location::default(), color_painter_impl) +//! # } +//! ``` +//! +mod instance; +mod transform; +mod traversal; + +#[cfg(test)] +mod traversal_tests; + +use raw::tables::colr; +#[cfg(test)] +use serde::{Deserialize, Serialize}; + +pub use read_fonts::tables::colr::{CompositeMode, Extend}; + +use read_fonts::{ + types::{BoundingBox, GlyphId, Point}, + ReadError, TableProvider, +}; + +use std::{fmt::Debug, ops::Range}; + +use traversal::{get_clipbox_font_units, traverse_v0_range, traverse_with_callbacks, VisitedSet}; + +pub use transform::Transform; + +use crate::prelude::{LocationRef, Size}; + +use self::instance::{resolve_paint, PaintId}; + +/// An error during drawing a COLR glyph. +/// +/// This covers inconsistencies in the COLRv1 paint graph as well as downstream +/// parse errors from read-fonts. +#[derive(Debug, Clone)] +pub enum PaintError { + ParseError(ReadError), + GlyphNotFound(GlyphId), + PaintCycleDetected, + DepthLimitExceeded, +} + +impl std::fmt::Display for PaintError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + PaintError::ParseError(read_error) => { + write!(f, "Error parsing font data: {read_error}") + } + PaintError::GlyphNotFound(glyph_id) => { + write!(f, "No COLRv1 glyph found for glyph id: {glyph_id}") + } + PaintError::PaintCycleDetected => write!(f, "Paint cycle detected in COLRv1 glyph."), + PaintError::DepthLimitExceeded => write!(f, "Depth limit exceeded in COLRv1 glyph."), + } + } +} + +impl From for PaintError { + fn from(value: ReadError) -> Self { + PaintError::ParseError(value) + } +} + +/// A color stop of a gradient. +/// +/// All gradient callbacks of [`ColorPainter`] normalize color stops to be in the range of 0 +/// to 1. +#[derive(Clone, PartialEq, Debug, Default)] +#[cfg_attr(test, derive(Serialize, Deserialize))] +// This repr(C) is required so that C-side FFI's +// are able to cast the ColorStop slice to a C-side array pointer. +#[repr(C)] +pub struct ColorStop { + pub offset: f32, + /// Specifies a color from the `CPAL` table. + pub palette_index: u16, + /// Additional alpha value, to be multiplied with the color above before use. + pub alpha: f32, +} + +// Design considerations for choosing a slice of ColorStops as `color_stop` +// type: In principle, a local `Vec` allocation would not required if +// we're willing to walk the `ResolvedColorStop` iterator to find the minimum +// and maximum color stops. Then we could scale the color stops based on the +// minimum and maximum. But performing the min/max search would require +// re-applying the deltas at least once, after which we would pass the scaled +// stops to client side and have the client sort the collected items once +// again. If we do want to pre-ort them, and still use use an +// `Iterator` instead as the `color_stops` field, then we would +// need a Fontations-side allocations to sort, and an extra allocation on the +// client side to `.collect()` from the provided iterator before passing it to +// drawing API. +// +/// A fill type of a COLRv1 glyph (solid fill or various gradient types). +/// +/// The client receives the information about the fill type in the +/// [`fill`](ColorPainter::fill) callback of the [`ColorPainter`] trait. +#[derive(Debug, PartialEq)] +pub enum Brush<'a> { + /// A solid fill with the color specified by `palette_index`. The respective + /// color from the CPAL table then needs to be multiplied with `alpha`. + Solid { palette_index: u16, alpha: f32 }, + /// A linear gradient, normalized from the P0, P1 and P2 representation in + /// the COLRv1 table to a linear gradient between two points `p0` and + /// `p1`. If there is only one color stop, the client should draw a solid + /// fill with that color. The `color_stops` are normalized to the range from + /// 0 to 1. + LinearGradient { + p0: Point, + p1: Point, + color_stops: &'a [ColorStop], + extend: Extend, + }, + /// A radial gradient, with color stops normalized to the range of 0 to 1. + /// Caution: This normalization can mean that negative radii occur. It is + /// the client's responsibility to truncate the color line at the 0 + /// position, interpolating between `r0` and `r1` and compute an + /// interpolated color at that position. + RadialGradient { + c0: Point, + r0: f32, + c1: Point, + r1: f32, + color_stops: &'a [ColorStop], + extend: Extend, + }, + /// A sweep gradient, also called conical gradient. The color stops are + /// normalized to the range from 0 to 1 and the returned angles are to be + /// interpreted in _clockwise_ direction (swapped from the meaning in the + /// font file). The stop normalization may mean that the angles may be + /// larger or smaller than the range of 0 to 360. Note that only the range + /// from 0 to 360 degrees is to be drawn, see + /// . + SweepGradient { + c0: Point, + start_angle: f32, + end_angle: f32, + color_stops: &'a [ColorStop], + extend: Extend, + }, +} + +/// Signals success of request to draw a COLRv1 sub glyph from cache. +/// +/// Result of [`paint_cached_color_glyph`](ColorPainter::paint_cached_color_glyph) +/// through which the client signals whether a COLRv1 glyph referenced by +/// another COLRv1 glyph was drawn from cache or whether the glyph's subgraph +/// should be traversed by the skria side COLRv1 implementation. +pub enum PaintCachedColorGlyph { + /// The specified COLRv1 glyph has been successfully painted client side. + Ok, + /// The client does not implement drawing COLRv1 glyphs from cache and the + /// Fontations side COLRv1 implementation is asked to traverse the + /// respective PaintColorGlyph sub graph. + Unimplemented, +} + +/// A group of required painting callbacks to be provided by the client. +/// +/// Each callback is executing a particular drawing or canvas transformation +/// operation. The trait's callback functions are invoked when +/// [`paint`](ColorGlyph::paint) is called with a [`ColorPainter`] trait +/// object. The documentation for each function describes what actions are to be +/// executed using the client side 2D graphics API, usually by performing some +/// kind of canvas operation. +pub trait ColorPainter { + /// Push the specified transform by concatenating it to the current + /// transformation matrix. + fn push_transform(&mut self, transform: Transform); + + /// Restore the transformation matrix to the state before the previous + /// [`push_transform`](ColorPainter::push_transform) call. + fn pop_transform(&mut self); + + /// Apply a clip path in the shape of glyph specified by `glyph_id`. + fn push_clip_glyph(&mut self, glyph_id: GlyphId); + + /// Apply a clip rectangle specified by `clip_rect`. + fn push_clip_box(&mut self, clip_box: BoundingBox); + + /// Restore the clip state to the state before a previous + /// [`push_clip_glyph`](ColorPainter::push_clip_glyph) or + /// [`push_clip_box`](ColorPainter::push_clip_box) call. + fn pop_clip(&mut self); + + /// Fill the current clip area with the specified gradient fill. + fn fill(&mut self, brush: Brush<'_>); + + /// Combined clip and fill operation. + /// + /// Apply the clip path determined by the specified `glyph_id`, then fill it + /// with the specified [`brush`](Brush), applying the `_brush_transform` + /// transformation matrix to the brush. The default implementation works + /// based on existing methods in this trait. It is recommended for clients + /// to override the default implementaition with a custom combined clip and + /// fill operation. In this way overriding likely results in performance + /// gains depending on performance characteristics of the 2D graphics stack + /// that these calls are mapped to. + fn fill_glyph( + &mut self, + glyph_id: GlyphId, + brush_transform: Option, + brush: Brush<'_>, + ) { + self.push_clip_glyph(glyph_id); + if let Some(wrap_in_transform) = brush_transform { + self.push_transform(wrap_in_transform); + self.fill(brush); + self.pop_transform(); + } else { + self.fill(brush); + } + self.pop_clip(); + } + + /// Optionally implement this method: Draw an unscaled COLRv1 glyph given + /// the current transformation matrix (as accumulated by + /// [`push_transform`](ColorPainter::push_transform) calls). + fn paint_cached_color_glyph( + &mut self, + _glyph: GlyphId, + ) -> Result { + Ok(PaintCachedColorGlyph::Unimplemented) + } + + /// Open a new layer, and merge the layer down using `composite_mode` when + /// [`pop_layer`](ColorPainter::pop_layer) is called, signalling that this layer is done drawing. + fn push_layer(&mut self, composite_mode: CompositeMode); + fn pop_layer(&mut self); +} + +/// Distinguishes available color glyph formats. +#[derive(Clone, Copy)] +pub enum ColorGlyphFormat { + ColrV0, + ColrV1, +} + +/// A representation of a color glyph that can be painted through a sequence of [`ColorPainter`] callbacks. +#[derive(Clone)] +pub struct ColorGlyph<'a> { + colr: colr::Colr<'a>, + root_paint_ref: ColorGlyphRoot<'a>, +} + +#[derive(Clone)] +enum ColorGlyphRoot<'a> { + V0Range(Range), + V1Paint(colr::Paint<'a>, PaintId, GlyphId, Result), +} + +impl<'a> ColorGlyph<'a> { + /// Returns the version of the color table from which this outline was + /// selected. + pub fn format(&self) -> ColorGlyphFormat { + match &self.root_paint_ref { + ColorGlyphRoot::V0Range(_) => ColorGlyphFormat::ColrV0, + ColorGlyphRoot::V1Paint(..) => ColorGlyphFormat::ColrV1, + } + } + + /// Returns the bounding box. + /// + /// For COLRv1 glyphs, this is the clip box of the specified COLRv1 glyph, + /// or `None` if clip boxes are not present or if there is none for the + /// particular glyph. + /// + /// Always returns `None` for COLRv0 glyphs because precomputed clip boxes + /// are never available. + /// + /// The `size` argument can optionally be used to scale the bounding box + /// to a particular font size and `location` allows specifying a variation + /// instance. + pub fn bounding_box( + &self, + location: impl Into>, + size: Size, + ) -> Option> { + match &self.root_paint_ref { + ColorGlyphRoot::V1Paint(_paint, _paint_id, glyph_id, upem) => { + let instance = + instance::ColrInstance::new(self.colr.clone(), location.into().coords()); + let resolved_bounding_box = get_clipbox_font_units(&instance, *glyph_id); + resolved_bounding_box.map(|bounding_box| { + let scale_factor = size.linear_scale((*upem).clone().unwrap_or(0)); + bounding_box.scale(scale_factor) + }) + } + _ => None, + } + } + + /// Evaluates the paint graph at the specified location in variation space + /// and emits the results to the given painter. + /// + /// + /// For a COLRv1 glyph, traverses the COLRv1 paint graph and invokes drawing callbacks on a + /// specified [`ColorPainter`] trait object. The traversal operates in font + /// units and will call `ColorPainter` methods with font unit values. This + /// means, if you want to draw a COLRv1 glyph at a particular font size, the + /// canvas needs to have a transformation matrix applied so that it scales down + /// the drawing operations to `font_size / upem`. + /// + /// # Arguments + /// + /// * `glyph_id` the `GlyphId` to be drawn. + /// * `location` coordinates for specifying a variation instance. This can be empty. + /// * `painter` a client-provided [`ColorPainter`] implementation receiving drawing callbacks. + /// + pub fn paint( + &self, + location: impl Into>, + painter: &mut impl ColorPainter, + ) -> Result<(), PaintError> { + let instance = instance::ColrInstance::new(self.colr.clone(), location.into().coords()); + match &self.root_paint_ref { + ColorGlyphRoot::V1Paint(paint, paint_id, glyph_id, _) => { + let clipbox = get_clipbox_font_units(&instance, *glyph_id); + + if let Some(rect) = clipbox { + painter.push_clip_box(rect); + } + + let mut visited_set = VisitedSet::default(); + visited_set.insert(*paint_id); + traverse_with_callbacks( + &resolve_paint(&instance, paint)?, + &instance, + painter, + &mut visited_set, + 0, + )?; + + if clipbox.is_some() { + painter.pop_clip(); + } + Ok(()) + } + ColorGlyphRoot::V0Range(range) => { + traverse_v0_range(range, &instance, painter)?; + Ok(()) + } + } + } +} + +/// Collection of color glyphs. +#[derive(Clone)] +pub struct ColorGlyphCollection<'a> { + colr: Option>, + upem: Result, +} + +impl<'a> ColorGlyphCollection<'a> { + /// Creates a new collection of paintable color glyphs for the given font. + pub fn new(font: &impl TableProvider<'a>) -> Self { + let colr = font.colr().ok(); + let upem = font.head().map(|h| h.units_per_em()); + + Self { colr, upem } + } + + /// Returns the color glyph representation for the given glyph identifier, + /// given a specific format. + pub fn get_with_format( + &self, + glyph_id: GlyphId, + glyph_format: ColorGlyphFormat, + ) -> Option> { + let colr = self.colr.clone()?; + + let root_paint_ref = match glyph_format { + ColorGlyphFormat::ColrV0 => { + let layer_range = colr.v0_base_glyph(glyph_id).ok()??; + ColorGlyphRoot::V0Range(layer_range) + } + ColorGlyphFormat::ColrV1 => { + let (paint, paint_id) = colr.v1_base_glyph(glyph_id).ok()??; + ColorGlyphRoot::V1Paint(paint, paint_id, glyph_id, self.upem.clone()) + } + }; + Some(ColorGlyph { + colr, + root_paint_ref, + }) + } + + /// Returns a color glyph representation for the given glyph identifier if + /// available, preferring a COLRv1 representation over a COLRv0 + /// representation. + pub fn get(&self, glyph_id: GlyphId) -> Option> { + self.get_with_format(glyph_id, ColorGlyphFormat::ColrV1) + .or_else(|| self.get_with_format(glyph_id, ColorGlyphFormat::ColrV0)) + } +} + +#[cfg(test)] +mod tests { + + use crate::{ + color::traversal_tests::test_glyph_defs::PAINTCOLRGLYPH_CYCLE, + prelude::{LocationRef, Size}, + MetadataProvider, + }; + + use read_fonts::{types::BoundingBox, FontRef}; + + use super::{Brush, ColorPainter, CompositeMode, GlyphId, Transform}; + use crate::color::traversal_tests::test_glyph_defs::{COLORED_CIRCLES_V0, COLORED_CIRCLES_V1}; + + #[test] + fn has_colrv1_glyph_test() { + let colr_font = font_test_data::COLRV0V1_VARIABLE; + let font = FontRef::new(colr_font).unwrap(); + let get_colrv1_glyph = |codepoint: &[char]| { + font.charmap().map(codepoint[0]).and_then(|glyph_id| { + font.color_glyphs() + .get_with_format(glyph_id, crate::color::ColorGlyphFormat::ColrV1) + }) + }; + + assert!(get_colrv1_glyph(COLORED_CIRCLES_V0).is_none()); + assert!(get_colrv1_glyph(COLORED_CIRCLES_V1).is_some()); + } + struct DummyColorPainter {} + + impl DummyColorPainter { + pub fn new() -> Self { + Self {} + } + } + + impl Default for DummyColorPainter { + fn default() -> Self { + Self::new() + } + } + + impl ColorPainter for DummyColorPainter { + fn push_transform(&mut self, _transform: Transform) {} + fn pop_transform(&mut self) {} + fn push_clip_glyph(&mut self, _glyph: GlyphId) {} + fn push_clip_box(&mut self, _clip_box: BoundingBox) {} + fn pop_clip(&mut self) {} + fn fill(&mut self, _brush: Brush) {} + fn push_layer(&mut self, _composite_mode: CompositeMode) {} + fn pop_layer(&mut self) {} + } + + #[test] + fn paintcolrglyph_cycle_test() { + let colr_font = font_test_data::COLRV0V1_VARIABLE; + let font = FontRef::new(colr_font).unwrap(); + let cycle_glyph_id = font.charmap().map(PAINTCOLRGLYPH_CYCLE[0]).unwrap(); + let colrv1_glyph = font + .color_glyphs() + .get_with_format(cycle_glyph_id, crate::color::ColorGlyphFormat::ColrV1); + + assert!(colrv1_glyph.is_some()); + let mut color_painter = DummyColorPainter::new(); + + let result = colrv1_glyph + .unwrap() + .paint(LocationRef::default(), &mut color_painter); + // Expected to fail with an error as the glyph contains a paint cycle. + assert!(result.is_err()); + } + + #[test] + fn no_cliplist_test() { + let colr_font = font_test_data::COLRV1_NO_CLIPLIST; + let font = FontRef::new(colr_font).unwrap(); + let cycle_glyph_id = GlyphId::new(1); + let colrv1_glyph = font + .color_glyphs() + .get_with_format(cycle_glyph_id, crate::color::ColorGlyphFormat::ColrV1); + + assert!(colrv1_glyph.is_some()); + let mut color_painter = DummyColorPainter::new(); + + let result = colrv1_glyph + .unwrap() + .paint(LocationRef::default(), &mut color_painter); + assert!(result.is_ok()); + } + + #[test] + fn colrv0_no_bbox_test() { + let colr_font = font_test_data::COLRV0V1; + let font = FontRef::new(colr_font).unwrap(); + let colrv0_glyph_id = GlyphId::new(168); + let colrv0_glyph = font + .color_glyphs() + .get_with_format(colrv0_glyph_id, super::ColorGlyphFormat::ColrV0) + .unwrap(); + assert!(colrv0_glyph + .bounding_box(LocationRef::default(), Size::unscaled()) + .is_none()); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,166 @@ +//! Contains a [`Transform`] object holding values of an affine transformation matrix. +use std::ops::{Mul, MulAssign}; + +use read_fonts::ReadError; + +use super::instance::ResolvedPaint; + +#[cfg(feature = "libm")] +#[allow(unused_imports)] +use core_maths::*; + +#[cfg(test)] +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(test, derive(Serialize, Deserialize))] +/// A transformation matrix to be applied to the drawing canvas. +/// +/// Factors are specified in column-order, meaning that +/// for a vector `(x,y)` the transformed position `x'` of the vector +/// is calculated by +/// `x' = xx * x + xy * y + dx`, +/// and the transformed position y' is calculated by +/// `y' = yx * x + yy * y + dy`. +#[derive(Copy)] +pub struct Transform { + pub xx: f32, + pub yx: f32, + pub xy: f32, + pub yy: f32, + pub dx: f32, + pub dy: f32, +} + +impl MulAssign for Transform { + fn mul_assign(&mut self, rhs: Self) { + *self = *self * rhs; + } +} + +impl Mul for Transform { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + fn muladdmul(a: f32, b: f32, c: f32, d: f32) -> f32 { + a * b + c * d + } + Self { + xx: muladdmul(self.xx, rhs.xx, self.xy, rhs.yx), + xy: muladdmul(self.xx, rhs.xy, self.xy, rhs.yy), + dx: muladdmul(self.xx, rhs.dx, self.xy, rhs.dy) + self.dx, + yx: muladdmul(self.yx, rhs.xx, self.yy, rhs.yx), + yy: muladdmul(self.yx, rhs.xy, self.yy, rhs.yy), + dy: muladdmul(self.yx, rhs.dx, self.yy, rhs.dy) + self.dy, + } + } +} + +impl Default for Transform { + fn default() -> Self { + Transform { + xx: 1.0, + yx: 0.0, + xy: 0.0, + yy: 1.0, + dx: 0.0, + dy: 0.0, + } + } +} + +impl TryFrom<&ResolvedPaint<'_>> for Transform { + type Error = ReadError; + + fn try_from(paint: &ResolvedPaint<'_>) -> Result { + match paint { + ResolvedPaint::Rotate { + angle, + around_center, + .. + } => { + let sin_v = (angle * 180.0).to_radians().sin(); + let cos_v = (angle * 180.0).to_radians().cos(); + let mut out_transform = Transform { + xx: cos_v, + xy: -sin_v, + yx: sin_v, + yy: cos_v, + ..Default::default() + }; + + fn scalar_dot_product(a: f32, b: f32, c: f32, d: f32) -> f32 { + a * b + c * d + } + + if let Some(center) = around_center { + out_transform.dx = scalar_dot_product(sin_v, center.y, 1.0 - cos_v, center.x); + out_transform.dy = scalar_dot_product(-sin_v, center.x, 1.0 - cos_v, center.y); + } + Ok(out_transform) + } + ResolvedPaint::Scale { + scale_x, + scale_y, + around_center, + paint: _, + } => { + let mut out_transform = Transform { + xx: *scale_x, + yy: *scale_y, + ..Transform::default() + }; + + if let Some(center) = around_center { + out_transform.dx = center.x - scale_x * center.x; + out_transform.dy = center.y - scale_y * center.y; + } + Ok(out_transform) + } + ResolvedPaint::Skew { + x_skew_angle, + y_skew_angle, + around_center, + paint: _, + } => { + let tan_x = (x_skew_angle * 180.0).to_radians().tan(); + let tan_y = (y_skew_angle * 180.0).to_radians().tan(); + let mut out_transform = Transform { + xy: -tan_x, + yx: tan_y, + ..Transform::default() + }; + + if let Some(center) = around_center { + out_transform.dx = tan_x * center.y; + out_transform.dy = -tan_y * center.x; + } + Ok(out_transform) + } + ResolvedPaint::Transform { + xx, + yx, + xy, + yy, + dx, + dy, + paint: _, + } => Ok(Transform { + xx: *xx, + yx: *yx, + xy: *xy, + yy: *yy, + dx: *dx, + dy: *dy, + }), + ResolvedPaint::Translate { dx, dy, .. } => Ok(Transform { + dx: *dx, + dy: *dy, + ..Default::default() + }), + _ => Err(ReadError::MalformedData( + "ResolvedPaint cannot be converted into a transform.", + )), + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,753 @@ +use std::{cmp::Ordering, ops::Range}; + +use read_fonts::{ + tables::colr::{CompositeMode, Extend}, + types::{BoundingBox, GlyphId, Point}, +}; + +use super::{ + instance::{ + resolve_clip_box, resolve_paint, ColorStops, ColrInstance, ResolvedColorStop, ResolvedPaint, + }, + Brush, ColorPainter, ColorStop, PaintCachedColorGlyph, PaintError, Transform, +}; + +use alloc::vec::Vec; + +#[cfg(feature = "libm")] +#[allow(unused_imports)] +use core_maths::*; + +#[cfg(any(test, feature = "std"))] +mod visited_set { + pub type VisitedSet = std::collections::HashSet; +} + +#[cfg(not(any(test, feature = "std")))] +mod visited_set { + /// A subset of the HashSet type that pretends every insertion is + /// new. + /// + /// This is used in `no_std` builds to represent a visited set that never + /// detects cycles. We rely only on a traversal depth check to avoid + /// infinite recursion instead. + #[derive(Default)] + pub struct VisitedSet {} + + impl VisitedSet { + /// Like HashSet, returns true if the value doesn't already exist in + /// the set. In our case, that's always. + pub fn insert(&mut self, _value: usize) -> bool { + true + } + + pub fn remove(&mut self, _value: &usize) {} + } +} + +pub use visited_set::VisitedSet; + +/// Depth at which we will stop traversing and return an error. +/// +/// Used to prevent stack overflows. Also allows us to avoid using a HashSet +/// in no_std builds. +/// +/// This limit matches the one used in HarfBuzz: +/// HB_MAX_NESTING_LEVEL: +/// hb_paint_context_t: +const MAX_TRAVERSAL_DEPTH: u32 = 64; + +pub(crate) fn get_clipbox_font_units( + colr_instance: &ColrInstance, + glyph_id: GlyphId, +) -> Option> { + let maybe_clipbox = (*colr_instance).v1_clip_box(glyph_id).ok().flatten()?; + Some(resolve_clip_box(colr_instance, &maybe_clipbox)) +} + +impl From for ColorStop { + fn from(resolved_stop: ResolvedColorStop) -> Self { + ColorStop { + offset: resolved_stop.offset, + alpha: resolved_stop.alpha, + palette_index: resolved_stop.palette_index, + } + } +} + +fn make_sorted_resolved_stops(stops: &ColorStops, instance: &ColrInstance) -> Vec { + let color_stop_iter = stops.resolve(instance).map(|stop| stop.into()); + let mut collected: Vec = color_stop_iter.collect(); + collected.sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap_or(Ordering::Equal)); + collected +} + +struct CollectFillGlyphPainter<'a> { + brush_transform: Option, + glyph_id: GlyphId, + parent_painter: &'a mut dyn ColorPainter, + pub optimization_success: bool, +} + +impl<'a> CollectFillGlyphPainter<'a> { + fn new(parent_painter: &'a mut dyn ColorPainter, glyph_id: GlyphId) -> Self { + Self { + brush_transform: None, + glyph_id, + parent_painter, + optimization_success: true, + } + } +} + +impl ColorPainter for CollectFillGlyphPainter<'_> { + fn push_transform(&mut self, transform: Transform) { + if self.optimization_success { + match self.brush_transform { + None => { + self.brush_transform = Some(transform); + } + Some(ref mut existing_transform) => { + *existing_transform *= transform; + } + } + } + } + + fn pop_transform(&mut self) { + // Since we only support fill and and transform operations, we need to + // ignore a popped transform, as this would be called after traversing + // the graph backup after a fill was performed, but we want to preserve + // the transform in order to be able to return it. + } + + fn fill(&mut self, brush: Brush<'_>) { + if self.optimization_success { + self.parent_painter + .fill_glyph(self.glyph_id, self.brush_transform, brush); + } + } + + fn push_clip_glyph(&mut self, _: GlyphId) { + self.optimization_success = false; + } + + fn push_clip_box(&mut self, _: BoundingBox) { + self.optimization_success = false; + } + + fn pop_clip(&mut self) { + self.optimization_success = false; + } + + fn push_layer(&mut self, _: CompositeMode) { + self.optimization_success = false; + } + + fn pop_layer(&mut self) { + self.optimization_success = false; + } +} + +pub(crate) fn traverse_with_callbacks( + paint: &ResolvedPaint, + instance: &ColrInstance, + painter: &mut impl ColorPainter, + visited_set: &mut VisitedSet, + recurse_depth: u32, +) -> Result<(), PaintError> { + if recurse_depth >= MAX_TRAVERSAL_DEPTH { + return Err(PaintError::DepthLimitExceeded); + } + match paint { + ResolvedPaint::ColrLayers { range } => { + for layer_index in range.clone() { + // Perform cycle detection with paint id here, second part of the tuple. + let (layer_paint, paint_id) = (*instance).v1_layer(layer_index)?; + if !visited_set.insert(paint_id) { + return Err(PaintError::PaintCycleDetected); + } + traverse_with_callbacks( + &resolve_paint(instance, &layer_paint)?, + instance, + painter, + visited_set, + recurse_depth + 1, + )?; + visited_set.remove(&paint_id); + } + Ok(()) + } + ResolvedPaint::Solid { + palette_index, + alpha, + } => { + painter.fill(Brush::Solid { + palette_index: *palette_index, + alpha: *alpha, + }); + Ok(()) + } + ResolvedPaint::LinearGradient { + x0, + y0, + x1, + y1, + x2, + y2, + color_stops, + extend, + } => { + let mut p0 = Point::new(*x0, *y0); + let p1 = Point::new(*x1, *y1); + let p2 = Point::new(*x2, *y2); + + let dot_product = |a: Point, b: Point| -> f32 { a.x * b.x + a.y * b.y }; + let cross_product = |a: Point, b: Point| -> f32 { a.x * b.y - a.y * b.x }; + let project_onto = |vector: Point, point: Point| -> Point { + let length = (point.x * point.x + point.y * point.y).sqrt(); + if length == 0.0 { + return Point::default(); + } + let mut point_normalized = point / length; + point_normalized *= dot_product(vector, point) / length; + point_normalized + }; + + let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); + + // If p0p1 or p0p2 are degenerate probably nothing should be drawn. + // If p0p1 and p0p2 are parallel then one side is the first color and the other side is + // the last color, depending on the direction. + // For now, just use the first color. + if p1 == p0 || p2 == p0 || cross_product(p1 - p0, p2 - p0) == 0.0 { + if let Some(stop) = resolved_stops.first() { + painter.fill(Brush::Solid { + palette_index: stop.palette_index, + alpha: stop.alpha, + }); + }; + return Ok(()); + } + + // Follow implementation note in nanoemoji: + // https://github.com/googlefonts/nanoemoji/blob/0ac6e7bb4d8202db692574d8530a9b643f1b3b3c/src/nanoemoji/svg.py#L188 + // to compute a new gradient end point P3 as the orthogonal + // projection of the vector from p0 to p1 onto a line perpendicular + // to line p0p2 and passing through p0. + let mut perpendicular_to_p2 = p2 - p0; + perpendicular_to_p2 = Point::new(perpendicular_to_p2.y, -perpendicular_to_p2.x); + let mut p3 = p0 + project_onto(p1 - p0, perpendicular_to_p2); + + match ( + resolved_stops.first().cloned(), + resolved_stops.last().cloned(), + ) { + (None, _) | (_, None) => {} + (Some(first_stop), Some(last_stop)) => { + let mut color_stop_range = last_stop.offset - first_stop.offset; + + // Nothing can be drawn for this situation. + if color_stop_range == 0.0 && extend != &Extend::Pad { + return Ok(()); + } + + // In the Pad case, for providing normalized stops in the 0 to 1 range to the client, + // insert a color stop at the end. Adding this stop will paint the equivalent gradient, + // because: All font-specified color stops are in the same spot, mode is pad, so + // everything before this spot is painted with the first color, everything after this spot + // is painted with the last color. Not adding this stop would skip the projection below along + // the p0-p3 axis and result in specifying non-normalized color stops to the shader. + + if color_stop_range == 0.0 && extend == &Extend::Pad { + let mut extra_stop = last_stop.clone(); + extra_stop.offset += 1.0; + resolved_stops.push(extra_stop); + + color_stop_range = 1.0; + } + + debug_assert!(color_stop_range != 0.0); + + if color_stop_range != 1.0 || first_stop.offset != 0.0 { + let p0_p3 = p3 - p0; + let p0_offset = p0_p3 * first_stop.offset; + let p3_offset = p0_p3 * last_stop.offset; + + p3 = p0 + p3_offset; + p0 += p0_offset; + + let scale_factor = 1.0 / color_stop_range; + let start_offset = first_stop.offset; + + for stop in &mut resolved_stops { + stop.offset = (stop.offset - start_offset) * scale_factor; + } + } + + painter.fill(Brush::LinearGradient { + p0, + p1: p3, + color_stops: resolved_stops.as_slice(), + extend: *extend, + }); + } + } + + Ok(()) + } + ResolvedPaint::RadialGradient { + x0, + y0, + radius0, + x1, + y1, + radius1, + color_stops, + extend, + } => { + let mut c0 = Point::new(*x0, *y0); + let mut c1 = Point::new(*x1, *y1); + let mut radius0 = *radius0; + let mut radius1 = *radius1; + + let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); + + match ( + resolved_stops.first().cloned(), + resolved_stops.last().cloned(), + ) { + (None, _) | (_, None) => {} + (Some(first_stop), Some(last_stop)) => { + let mut color_stop_range = last_stop.offset - first_stop.offset; + // Nothing can be drawn for this situation. + if color_stop_range == 0.0 && extend != &Extend::Pad { + return Ok(()); + } + + // In the Pad case, for providing normalized stops in the 0 to 1 range to the client, + // insert a color stop at the end. See LinearGradient for more details. + + if color_stop_range == 0.0 && extend == &Extend::Pad { + let mut extra_stop = last_stop.clone(); + extra_stop.offset += 1.0; + resolved_stops.push(extra_stop); + color_stop_range = 1.0; + } + + debug_assert!(color_stop_range != 0.0); + + // If the colorStopRange is 0 at this point, the default behavior of the shader is to + // clamp to 1 color stops that are above 1, clamp to 0 for color stops that are below 0, + // and repeat the outer color stops at 0 and 1 if the color stops are inside the + // range. That will result in the correct rendering. + if color_stop_range != 1.0 || first_stop.offset != 0.0 { + let c0_to_c1 = c1 - c0; + let radius_diff = radius1 - radius0; + let scale_factor = 1.0 / color_stop_range; + + let c0_offset = c0_to_c1 * first_stop.offset; + let c1_offset = c0_to_c1 * last_stop.offset; + let stops_start_offset = first_stop.offset; + + // Order of reassignments is important to avoid shadowing variables. + c1 = c0 + c1_offset; + c0 += c0_offset; + radius1 = radius0 + radius_diff * last_stop.offset; + radius0 += radius_diff * first_stop.offset; + + for stop in &mut resolved_stops { + stop.offset = (stop.offset - stops_start_offset) * scale_factor; + } + } + + painter.fill(Brush::RadialGradient { + c0, + r0: radius0, + c1, + r1: radius1, + color_stops: resolved_stops.as_slice(), + extend: *extend, + }); + } + } + Ok(()) + } + ResolvedPaint::SweepGradient { + center_x, + center_y, + start_angle, + end_angle, + color_stops, + extend, + } => { + // OpenType 1.9.1 adds a shift to the angle to ease specification of a 0 to 360 + // degree sweep. + let sweep_angle_to_degrees = |angle| angle * 180.0 + 180.0; + + let start_angle = sweep_angle_to_degrees(start_angle); + let end_angle = sweep_angle_to_degrees(end_angle); + + // Stop normalization for sweep: + + let sector_angle = end_angle - start_angle; + + let mut resolved_stops = make_sorted_resolved_stops(color_stops, instance); + if resolved_stops.is_empty() { + return Ok(()); + } + + match ( + resolved_stops.first().cloned(), + resolved_stops.last().cloned(), + ) { + (None, _) | (_, None) => {} + (Some(first_stop), Some(last_stop)) => { + let mut color_stop_range = last_stop.offset - first_stop.offset; + + let mut start_angle_scaled = start_angle + sector_angle * first_stop.offset; + let mut end_angle_scaled = start_angle + sector_angle * last_stop.offset; + + let start_offset = first_stop.offset; + + // Nothing can be drawn for this situation. + if color_stop_range == 0.0 && extend != &Extend::Pad { + return Ok(()); + } + + // In the Pad case, if the color_stop_range is 0 insert a color stop at the end before + // normalizing. Adding this stop will paint the equivalent gradient, because: All font + // specified color stops are in the same spot, mode is pad, so everything before this + // spot is painted with the first color, everything after this spot is painted with + // the last color. Not adding this stop will skip the projection and result in + // specifying non-normalized color stops to the shader. + if color_stop_range == 0.0 && extend == &Extend::Pad { + let mut offset_last = last_stop.clone(); + offset_last.offset += 1.0; + resolved_stops.push(offset_last); + color_stop_range = 1.0; + } + + debug_assert!(color_stop_range != 0.0); + + let scale_factor = 1.0 / color_stop_range; + + for shift_stop in &mut resolved_stops { + shift_stop.offset = (shift_stop.offset - start_offset) * scale_factor; + } + + // /* https://docs.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients + // * "The angles are expressed in counter-clockwise degrees from + // * the direction of the positive x-axis on the design + // * grid. [...] The color line progresses from the start angle + // * to the end angle in the counter-clockwise direction;" - + // * Convert angles and stops from counter-clockwise to clockwise + // * for the shader if the gradient is not already reversed due to + // * start angle being larger than end angle. */ + start_angle_scaled = 360.0 - start_angle_scaled; + end_angle_scaled = 360.0 - end_angle_scaled; + + if start_angle_scaled >= end_angle_scaled { + (start_angle_scaled, end_angle_scaled) = + (end_angle_scaled, start_angle_scaled); + resolved_stops.reverse(); + for stop in &mut resolved_stops { + stop.offset = 1.0 - stop.offset; + } + } + + // https://learn.microsoft.com/en-us/typography/opentype/spec/colr#sweep-gradients + // "If the color line's extend mode is reflect or repeat + // and start and end angle are equal, nothing shall be drawn." + if start_angle_scaled == end_angle_scaled && extend != &Extend::Pad { + return Ok(()); + } + + painter.fill(Brush::SweepGradient { + c0: Point::new(*center_x, *center_y), + start_angle: start_angle_scaled, + end_angle: end_angle_scaled, + color_stops: resolved_stops.as_slice(), + extend: *extend, + }); + } + } + Ok(()) + } + + ResolvedPaint::Glyph { glyph_id, paint } => { + let glyph_id = (*glyph_id).into(); + let mut optimizer = CollectFillGlyphPainter::new(painter, glyph_id); + let mut result = traverse_with_callbacks( + &resolve_paint(instance, paint)?, + instance, + &mut optimizer, + visited_set, + recurse_depth + 1, + ); + + // In case the optimization was not successful, just push a clip, and continue unoptimized traversal. + if !optimizer.optimization_success { + painter.push_clip_glyph(glyph_id); + result = traverse_with_callbacks( + &resolve_paint(instance, paint)?, + instance, + painter, + visited_set, + recurse_depth + 1, + ); + painter.pop_clip(); + } + + result + } + ResolvedPaint::ColrGlyph { glyph_id } => { + let glyph_id = (*glyph_id).into(); + match (*instance).v1_base_glyph(glyph_id)? { + Some((base_glyph, base_glyph_paint_id)) => { + if !visited_set.insert(base_glyph_paint_id) { + return Err(PaintError::PaintCycleDetected); + } + + let draw_result = painter.paint_cached_color_glyph(glyph_id)?; + let result = match draw_result { + PaintCachedColorGlyph::Ok => Ok(()), + PaintCachedColorGlyph::Unimplemented => { + let clipbox = get_clipbox_font_units(instance, glyph_id); + + if let Some(rect) = clipbox { + painter.push_clip_box(rect); + } + + let result = traverse_with_callbacks( + &resolve_paint(instance, &base_glyph)?, + instance, + painter, + visited_set, + recurse_depth + 1, + ); + if clipbox.is_some() { + painter.pop_clip(); + } + result + } + }; + visited_set.remove(&base_glyph_paint_id); + result + } + None => Err(PaintError::GlyphNotFound(glyph_id)), + } + } + ResolvedPaint::Transform { + paint: next_paint, .. + } + | ResolvedPaint::Translate { + paint: next_paint, .. + } + | ResolvedPaint::Scale { + paint: next_paint, .. + } + | ResolvedPaint::Rotate { + paint: next_paint, .. + } + | ResolvedPaint::Skew { + paint: next_paint, .. + } => { + painter.push_transform(paint.try_into()?); + let result = traverse_with_callbacks( + &resolve_paint(instance, next_paint)?, + instance, + painter, + visited_set, + recurse_depth + 1, + ); + painter.pop_transform(); + result + } + ResolvedPaint::Composite { + source_paint, + mode, + backdrop_paint, + } => { + painter.push_layer(CompositeMode::SrcOver); + let mut result = traverse_with_callbacks( + &resolve_paint(instance, backdrop_paint)?, + instance, + painter, + visited_set, + recurse_depth + 1, + ); + result?; + painter.push_layer(*mode); + result = traverse_with_callbacks( + &resolve_paint(instance, source_paint)?, + instance, + painter, + visited_set, + recurse_depth + 1, + ); + painter.pop_layer(); + painter.pop_layer(); + result + } + } +} + +pub(crate) fn traverse_v0_range( + range: &Range, + instance: &ColrInstance, + painter: &mut impl ColorPainter, +) -> Result<(), PaintError> { + for layer_index in range.clone() { + let (layer_glyph, palette_index) = (*instance).v0_layer(layer_index)?; + painter.fill_glyph( + layer_glyph.into(), + None, + Brush::Solid { + palette_index, + alpha: 1.0, + }, + ); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use raw::types::GlyphId; + use read_fonts::{types::BoundingBox, FontRef, TableProvider}; + + use crate::{ + color::{ + instance::ColrInstance, traversal::get_clipbox_font_units, + traversal_tests::test_glyph_defs::CLIPBOX, Brush, ColorGlyphFormat, ColorPainter, + CompositeMode, Transform, + }, + prelude::LocationRef, + MetadataProvider, + }; + + #[test] + fn clipbox_test() { + let colr_font = font_test_data::COLRV0V1_VARIABLE; + let font = FontRef::new(colr_font).unwrap(); + let test_glyph_id = font.charmap().map(CLIPBOX[0]).unwrap(); + let upem = font.head().unwrap().units_per_em(); + + let base_bounding_box = BoundingBox { + x_min: 0.0, + x_max: upem as f32 / 2.0, + y_min: upem as f32 / 2.0, + y_max: upem as f32, + }; + // Fractional value needed to match variation scaling of clipbox. + const CLIPBOX_SHIFT: f32 = 200.0122; + + macro_rules! test_entry { + ($axis:literal, $shift:expr, $field:ident) => { + ( + $axis, + $shift, + BoundingBox { + $field: base_bounding_box.$field + ($shift), + ..base_bounding_box + }, + ) + }; + } + + let test_data_expectations = [ + ("", 0.0, base_bounding_box), + test_entry!("CLXI", CLIPBOX_SHIFT, x_min), + test_entry!("CLXA", -CLIPBOX_SHIFT, x_max), + test_entry!("CLYI", CLIPBOX_SHIFT, y_min), + test_entry!("CLYA", -CLIPBOX_SHIFT, y_max), + ]; + + for axis_test in test_data_expectations { + let axis_coordinate = (axis_test.0, axis_test.1); + let location = font.axes().location([axis_coordinate]); + let color_instance = ColrInstance::new(font.colr().unwrap(), location.coords()); + let clip_box = get_clipbox_font_units(&color_instance, test_glyph_id); + assert!(clip_box.is_some()); + assert!( + clip_box.unwrap() == axis_test.2, + "Clip boxes do not match. Actual: {:?}, expected: {:?}", + clip_box.unwrap(), + axis_test.2 + ); + } + } + + struct NopPainter; + + impl ColorPainter for NopPainter { + fn push_transform(&mut self, _transform: Transform) { + // nop + } + + fn pop_transform(&mut self) { + // nop + } + + fn push_clip_glyph(&mut self, _glyph_id: GlyphId) { + // nop + } + + fn push_clip_box(&mut self, _clip_box: BoundingBox) { + // nop + } + + fn pop_clip(&mut self) { + // nop + } + + fn fill(&mut self, _brush: Brush<'_>) { + // nop + } + + fn push_layer(&mut self, _composite_mode: CompositeMode) { + // nop + } + + fn pop_layer(&mut self) { + // nop + } + } + + #[test] + fn no_panic_on_empty_colorline() { + // Minimized test case from . + let test_case = &[ + 0, 1, 0, 0, 0, 3, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, + 32, 32, 32, 32, 32, 67, 79, 76, 82, 32, 32, 32, 32, 0, 0, 0, 229, 0, 0, 0, 178, 99, + 109, 97, 112, 32, 32, 32, 32, 0, 0, 0, 10, 0, 0, 1, 32, 32, 32, 32, 255, 32, 32, 32, 0, + 4, 32, 255, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 32, 0, 0, + 32, 32, 0, 0, 0, 57, 32, 32, 32, 32, 32, 32, 32, 255, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 0, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 4, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 0, 0, 0, 1, 32, 32, 32, 32, 32, 32, 255, 0, 0, 0, 40, 32, 32, 32, 32, 32, 32, + 32, 255, 255, 32, 32, 32, 4, 0, 0, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 32, 32, 32, 255, 255, + 255, 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 255, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + ]; + + let font = FontRef::new(test_case).unwrap(); + font.cmap().unwrap(); + font.colr().unwrap(); + + let color_glyph = font + .color_glyphs() + .get_with_format(GlyphId::new(8447), ColorGlyphFormat::ColrV1) + .unwrap(); + let _ = color_glyph.paint(LocationRef::default(), &mut NopPainter); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,403 @@ +#[cfg(test)] +pub mod test_glyph_defs; + +use read_fonts::{ + tables::colr::{CompositeMode, Extend}, + types::{BoundingBox, GlyphId, Point}, + FontRef, +}; +use serde::{Deserialize, Serialize}; + +use std::{ + env, + fs::OpenOptions, + io::{self, BufRead, Write}, + string::String, +}; + +use crate::{ + alloc::vec::Vec, + color::{ + transform::Transform, traversal_tests::test_glyph_defs::*, Brush, ColorPainter, ColorStop, + }, + setting::VariationSetting, + MetadataProvider, +}; + +#[derive(Serialize, Deserialize, Default, PartialEq)] +struct PaintDump { + glyph_id: u32, + ops: Vec, +} + +impl From> for BrushParams { + fn from(brush: Brush) -> Self { + match brush { + Brush::Solid { + palette_index, + alpha, + } => BrushParams::Solid { + palette_index, + alpha, + }, + Brush::LinearGradient { + p0, + p1, + color_stops, + extend, + } => BrushParams::LinearGradient { + p0, + p1, + color_stops: color_stops.to_vec(), + extend, + }, + Brush::RadialGradient { + c0, + r0, + c1, + r1, + color_stops, + extend, + } => BrushParams::RadialGradient { + c0, + r0, + c1, + r1, + color_stops: color_stops.to_vec(), + extend, + }, + Brush::SweepGradient { + c0, + start_angle, + end_angle, + color_stops, + extend, + } => BrushParams::SweepGradient { + c0, + start_angle, + end_angle, + color_stops: color_stops.to_vec(), + extend, + }, + } + } +} + +// Needed as a mirror struct with owned ColorStops for serialization, deserialization. +#[derive(Serialize, Deserialize, PartialEq)] +pub enum BrushParams { + Solid { + palette_index: u16, + alpha: f32, + }, + // Normalized to a straight line between points p0 and p1, + // color stops normalized to align with both points. + LinearGradient { + p0: Point, + p1: Point, + color_stops: Vec, + extend: Extend, + }, + RadialGradient { + c0: Point, + r0: f32, + c1: Point, + r1: f32, + color_stops: Vec, + extend: Extend, + }, + SweepGradient { + c0: Point, + start_angle: f32, + end_angle: f32, + color_stops: Vec, + extend: Extend, + }, +} + +// Wrapping Transform for tests, as the results of trigonometric functions, in +// particular the tan() cases in PaintSkew need floating point PartialEq +// comparisons with an epsilon because the result of the tan() function differs +// on different platforms/archictectures. +#[derive(Serialize, Deserialize)] +struct DumpTransform(Transform); + +// Using the same value as in SK_ScalarNearlyZero from Skia (see SkScalar.h). +const NEARLY_EQUAL_TOLERANCE: f32 = 1.0 / (1 << 12) as f32; + +fn nearly_equal(a: f32, b: f32) -> bool { + (a - b).abs() < NEARLY_EQUAL_TOLERANCE +} + +impl PartialEq for DumpTransform { + fn eq(&self, other: &DumpTransform) -> bool { + nearly_equal(self.0.xx, other.0.xx) + && nearly_equal(self.0.xy, other.0.xy) + && nearly_equal(self.0.yx, other.0.yx) + && nearly_equal(self.0.yy, other.0.yy) + && nearly_equal(self.0.dx, other.0.dx) + && nearly_equal(self.0.dy, other.0.dy) + } +} + +impl From for DumpTransform { + fn from(value: Transform) -> Self { + Self(value) + } +} + +#[derive(Serialize, Deserialize, PartialEq)] +enum PaintOps { + PushTransform { + transform: DumpTransform, + }, + PopTransform, + PushClipGlyph { + gid: u32, + }, + PushClipBox { + clip_box: BoundingBox, + }, + PopClip, + FillBrush { + brush: BrushParams, + }, + FillGlyph { + gid: u32, + transform: DumpTransform, + brush: BrushParams, + }, + PushLayer { + composite_mode: u8, + }, + PopLayer, +} + +impl ColorPainter for PaintDump { + fn push_transform(&mut self, transform: Transform) { + self.ops.push(PaintOps::PushTransform { + transform: transform.into(), + }); + } + fn pop_transform(&mut self) { + self.ops.push(PaintOps::PopTransform); + } + + fn push_clip_glyph(&mut self, glyph: GlyphId) { + self.ops.push(PaintOps::PushClipGlyph { + gid: glyph.to_u32(), + }); + } + + fn push_clip_box(&mut self, clip_box: BoundingBox) { + self.ops.push(PaintOps::PushClipBox { clip_box }); + } + + fn pop_clip(&mut self) { + self.ops.push(PaintOps::PopClip); + } + + fn fill(&mut self, brush: Brush) { + self.ops.push(PaintOps::FillBrush { + brush: brush.into(), + }); + } + + fn fill_glyph(&mut self, glyph_id: GlyphId, transform: Option, brush: Brush) { + self.ops.push(PaintOps::FillGlyph { + gid: glyph_id.to_u32(), + transform: transform.unwrap_or_default().into(), + brush: brush.into(), + }); + } + + fn push_layer(&mut self, composite_mode: CompositeMode) { + self.ops.push(PaintOps::PushLayer { + composite_mode: composite_mode as u8, + }); + } + fn pop_layer(&mut self) { + self.ops.push(PaintOps::PopLayer); + } +} + +impl PaintDump { + pub fn new(gid: u32) -> Self { + Self { + glyph_id: gid, + ..Default::default() + } + } +} + +fn location_to_filename(set_name: &str, settings: I) -> String +where + I: IntoIterator, + I::Item: Into, +{ + let formatted_settings: Vec = settings + .into_iter() + .map(|entry| { + let entry_setting = entry.into(); + format!("{:}_{:}", entry_setting.selector, entry_setting.value) + }) + .collect(); + let suffix = match formatted_settings.len() { + 0 => String::new(), + _ => format!("_{}", formatted_settings.join("_")), + }; + format!("colrv1_{}{}", set_name.to_lowercase(), suffix) +} + +fn should_rebaseline() -> bool { + env::var("REBASELINE_COLRV1_TESTS").is_ok() +} + +// To regenerate the baselines, set the environment variable `REBASELINE_COLRV1_TESTS` +// when running tests, for example like this: +// $ REBASELINE_COLRV1_TESTS=1 cargo test color::traversal +fn colrv1_traversal_test( + set_name: &str, + test_chars: &[char], + settings: &[(&str, f32)], + required_format: crate::color::ColorGlyphFormat, +) { + let colr_font = font_test_data::COLRV0V1_VARIABLE; + let font = FontRef::new(colr_font).unwrap(); + + let location = font.axes().location(settings); + + let dumpfile_path = format!( + "../font-test-data/test_data/colrv1_json/{}", + location_to_filename(set_name, settings) + ); + + let test_gids = test_chars + .iter() + .map(|codepoint| font.charmap().map(*codepoint).unwrap()); + + let paint_dumps_iter = test_gids.map(|gid| { + let mut color_painter = PaintDump::new(gid.to_u32()); + + let color_glyph = font.color_glyphs().get_with_format(gid, required_format); + + assert!(color_glyph.is_some()); + + let result = color_glyph + .unwrap() + .paint(location.coords(), &mut color_painter); + + assert!(result.is_ok()); + + color_painter + }); + + if should_rebaseline() { + let mut file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(dumpfile_path) + .unwrap(); + + paint_dumps_iter.for_each(|dump| { + writeln!(file, "{}", serde_json::to_string(&dump).unwrap()) + .expect("Writing to file failed.") + }); + } else { + let expected = font_test_data::colrv1_json::expected(set_name, settings); + let mut lines = io::BufReader::new(expected.as_bytes()).lines(); + for dump in paint_dumps_iter { + match lines.next() { + Some(line) => { + assert!( + dump == serde_json::from_str( + line.as_ref().expect("Failed to read expectations line from file.") + ) + .expect("Failed to parse expectations line."), + "Result did not match expectation for glyph id: {}\nActual: {}\nExpected: {}\n", + dump.glyph_id, serde_json::to_string(&dump).unwrap(), &line.unwrap() + ) + } + None => panic!("Expectation not found for glyph id: {}", dump.glyph_id), + } + } + } +} + +macro_rules! colrv1_traversal_tests { + ($($test_name:ident: $glyph_set:ident, $settings:expr,)*) => { + $( + #[test] + fn $test_name() { + colrv1_traversal_test(stringify!($glyph_set), $glyph_set, $settings, crate::color::ColorGlyphFormat::ColrV1); + } + )* + } +} + +colrv1_traversal_tests!( +clipbox_default:CLIPBOX,&[], +clipbox_var_1:CLIPBOX, &[("CLIO", 200.0)], +comp_mode_default:COMPOSITE_MODE,&[], +extend_mode_default:EXTEND_MODE,&[], +extend_mode_var1:EXTEND_MODE,&[("COL1", -0.25), ("COL3", 0.25)], +extend_mode_var2:EXTEND_MODE,&[("COL1", 0.5), ("COL3", -0.5)], +extend_mode_var3:EXTEND_MODE,&[("COL3", 0.5)], +extend_mode_var4:EXTEND_MODE,&[("COL3", 1.0)], +extend_mode_var5:EXTEND_MODE,&[("COL1", -1.5)], +extend_mode_var6:EXTEND_MODE,&[("GRR0", -200.0), ("GRR1", -300.0)], +extend_mode_var7:EXTEND_MODE,&[("GRX0", -1000.0), ("GRX1", -1000.0), ("GRR0", -1000.0), ("GRR1", -900.0)], +extend_mode_var8:EXTEND_MODE,&[("GRX0", 1000.0), ("GRX1", -1000.0), ("GRR0", -1000.0), ("GRR1", 200.0)], +extend_mode_var9:EXTEND_MODE,&[("GRR0", -50.0), ("COL3", -2.0), ("COL2", -2.0), ("COL1", -0.9)], +extend_mode_var10:EXTEND_MODE,&[("GRR0", -50.0), ("COL3", -2.0), ("COL2", -2.0), ("COL1", -1.1)], +extend_mode_var11:EXTEND_MODE,&[("COL3", 1.0), ("COL2", 1.5), ("COL1", 2.0)], +extend_mode_var12:EXTEND_MODE,&[("COL2", -0.3)], +extend_mode_var13:EXTEND_MODE,&[("GRR0", 430.0), ("GRR1", 40.0)], +foreground_color_default:FOREGROUND_COLOR,&[], +gradient_skewed:GRADIENT_P2_SKEWED,&[], +gradient_stops_repeat:GRADIENT_STOPS_REPEAT,&[], +paint_rotate_default:PAINT_ROTATE,&[], +paint_rotate_var1:PAINT_ROTATE,&[("ROTA", 40.0)], +paint_rotate_var2:PAINT_ROTATE,&[("ROTX", -250.0), ("ROTY", -250.0)], +paint_scale_default:PAINT_SCALE,&[], +paint_scale_var1:PAINT_SCALE,&[("SCOX", 200.0), ("SCOY", 200.0)], +paint_scale_var2:PAINT_SCALE,&[("SCSX", 0.25), ("SCOY", 0.25)], +paint_scale_var3:PAINT_SCALE,&[("SCSX", -1.0), ("SCOY", -1.0)], +paint_skew_default:PAINT_SKEW,&[], +paint_skew_var1:PAINT_SKEW,&[("SKXA", 20.0)], +paint_skew_var2:PAINT_SKEW,&[("SKYA", 20.0)], +paint_skew_var3:PAINT_SKEW,&[("SKCX", 200.0),("SKCY", 200.0)], +paint_transform_default:PAINT_TRANSFORM,&[], +paint_translate_default:PAINT_TRANSLATE,&[], +paint_translate_var_1:PAINT_TRANSLATE,&[("TLDX", 100.0), ("TLDY", 100.0)], +paint_sweep_default:SWEEP_VARSWEEP,&[], +paint_sweep_var1:SWEEP_VARSWEEP,&[("SWPS", 0.0)], +paint_sweep_var2:SWEEP_VARSWEEP,&[("SWPS", 90.0)], +paint_sweep_var3:SWEEP_VARSWEEP,&[("SWPE", -90.0)], +paint_sweep_var4:SWEEP_VARSWEEP,&[("SWPE", -45.0)], +paint_sweep_var5:SWEEP_VARSWEEP,&[("SWPS", -45.0),("SWPE", 45.0)], +paint_sweep_var6:SWEEP_VARSWEEP,&[("SWC1", -0.25), ("SWC2", 0.083333333), ("SWC3", 0.083333333), ("SWC4", 0.25)], +paint_sweep_var7:SWEEP_VARSWEEP,&[("SWPS", 45.0), ("SWPE", -45.0), ("SWC1", -0.25), ("SWC2", -0.416687), ("SWC3", -0.583313), ("SWC4", -0.75)], +variable_alpha_default:VARIABLE_ALPHA,&[], +variable_alpha_var1:VARIABLE_ALPHA,&[("APH1", -0.7)], +variable_alpha_var2:VARIABLE_ALPHA,&[("APH2", -0.7), ("APH3", -0.2)], +nocycle_multi_colrglyph:NO_CYCLE_MULTI_COLRGLYPH,&[], +sweep_coincident:SWEEP_COINCIDENT,&[], +paint_glyph_nested:PAINT_GLYPH_NESTED,&[], +); + +macro_rules! colrv0_traversal_tests { + ($($test_name:ident: $glyph_set:ident,)*) => { + $( + #[test] + fn $test_name() { + colrv1_traversal_test(stringify!($glyph_set), $glyph_set, &[], crate::color::ColorGlyphFormat::ColrV0); + } + )* +} +} + +colrv0_traversal_tests!( + colored_circles:COLORED_CIRCLES_V0, +); diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,214 @@ +pub(crate) const GRADIENT_STOPS_REPEAT: &[char] = + &['\u{f0100}', '\u{f0101}', '\u{f0102}', '\u{f0103}']; +pub(crate) const SWEEP_VARSWEEP: &[char] = &[ + '\u{f0200}', + '\u{f0201}', + '\u{f0202}', + '\u{f0203}', + '\u{f0204}', + '\u{f0205}', + '\u{f0206}', + '\u{f0207}', + '\u{f0208}', + '\u{f0209}', + '\u{f020a}', + '\u{f020b}', + '\u{f020c}', + '\u{f020d}', + '\u{f020e}', + '\u{f020f}', + '\u{f0210}', + '\u{f0211}', + '\u{f0212}', + '\u{f0213}', + '\u{f0214}', + '\u{f0215}', + '\u{f0216}', + '\u{f0217}', + '\u{f0218}', + '\u{f0219}', + '\u{f021a}', + '\u{f021b}', + '\u{f021c}', + '\u{f021d}', + '\u{f021e}', + '\u{f021f}', + '\u{f0220}', + '\u{f0221}', + '\u{f0222}', + '\u{f0223}', + '\u{f0224}', + '\u{f0225}', + '\u{f0226}', + '\u{f0227}', + '\u{f0228}', + '\u{f0229}', + '\u{f022a}', + '\u{f022b}', + '\u{f022c}', + '\u{f022d}', + '\u{f022e}', + '\u{f022f}', + '\u{f0230}', + '\u{f0231}', + '\u{f0232}', + '\u{f0233}', + '\u{f0234}', + '\u{f0235}', + '\u{f0236}', + '\u{f0237}', + '\u{f0238}', + '\u{f0239}', + '\u{f023a}', + '\u{f023b}', + '\u{f023c}', + '\u{f023d}', + '\u{f023e}', + '\u{f023f}', + '\u{f0240}', + '\u{f0241}', + '\u{f0242}', + '\u{f0243}', + '\u{f0244}', + '\u{f0245}', + '\u{f0246}', + '\u{f0247}', +]; +pub(crate) const PAINT_SCALE: &[char] = &[ + '\u{f0300}', + '\u{f0301}', + '\u{f0302}', + '\u{f0303}', + '\u{f0304}', + '\u{f0305}', +]; +pub(crate) const EXTEND_MODE: &[char] = &[ + '\u{f0500}', + '\u{f0501}', + '\u{f0502}', + '\u{f0503}', + '\u{f0504}', + '\u{f0505}', + '\u{f0506}', + '\u{f0507}', + '\u{f0508}', +]; +pub(crate) const PAINT_ROTATE: &[char] = &['\u{f0600}', '\u{f0601}', '\u{f0602}', '\u{f0603}']; +pub(crate) const PAINT_SKEW: &[char] = &[ + '\u{f0700}', + '\u{f0701}', + '\u{f0702}', + '\u{f0703}', + '\u{f0704}', + '\u{f0705}', +]; +pub(crate) const PAINT_TRANSFORM: &[char] = &['\u{f0800}', '\u{f0801}', '\u{f0802}', '\u{f0803}']; +pub(crate) const PAINT_TRANSLATE: &[char] = &[ + '\u{f0900}', + '\u{f0901}', + '\u{f0902}', + '\u{f0903}', + '\u{f0904}', + '\u{f0905}', + '\u{f0906}', +]; +pub(crate) const COMPOSITE_MODE: &[char] = &[ + '\u{f0a00}', + '\u{f0a01}', + '\u{f0a02}', + '\u{f0a03}', + '\u{f0a04}', + '\u{f0a05}', + '\u{f0a06}', + '\u{f0a07}', + '\u{f0a08}', + '\u{f0a09}', + '\u{f0a0a}', + '\u{f0a0b}', + '\u{f0a0c}', + '\u{f0a0d}', + '\u{f0a0e}', + '\u{f0a0f}', + '\u{f0a10}', + '\u{f0a11}', + '\u{f0a12}', + '\u{f0a13}', + '\u{f0a14}', + '\u{f0a15}', + '\u{f0a16}', + '\u{f0a17}', + '\u{f0a18}', + '\u{f0a19}', + '\u{f0a1a}', + '\u{f0a1b}', +]; +pub(crate) const FOREGROUND_COLOR: &[char] = &[ + '\u{f0b00}', + '\u{f0b01}', + '\u{f0b02}', + '\u{f0b03}', + '\u{f0b04}', + '\u{f0b05}', + '\u{f0b06}', + '\u{f0b07}', +]; +pub(crate) const CLIPBOX: &[char] = &[ + '\u{f0c00}', + '\u{f0c01}', + '\u{f0c02}', + '\u{f0c03}', + '\u{f0c04}', +]; +pub(crate) const GRADIENT_P2_SKEWED: &[char] = &['\u{f0d00}']; +pub(crate) const VARIABLE_ALPHA: &[char] = &['\u{f1000}']; +pub(crate) const NO_CYCLE_MULTI_COLRGLYPH: &[char] = &['\u{f1200}']; +pub(crate) const SWEEP_COINCIDENT: &[char] = &[ + '\u{f1300}', + '\u{f1301}', + '\u{f1302}', + '\u{f1303}', + '\u{f1304}', + '\u{f1305}', + '\u{f1306}', + '\u{f1307}', + '\u{f1308}', + '\u{f1309}', + '\u{f130a}', + '\u{f130b}', + '\u{f130c}', + '\u{f130d}', + '\u{f130e}', + '\u{f130f}', + '\u{f1310}', + '\u{f1311}', + '\u{f1312}', + '\u{f1313}', + '\u{f1314}', + '\u{f1315}', + '\u{f1316}', + '\u{f1317}', +]; +pub(crate) const COLORED_CIRCLES_V0: &[char] = &['\u{F0E00}']; + +pub(crate) const COLORED_CIRCLES_V1: &[char] = &['\u{F0E01}']; + +pub(crate) const PAINTCOLRGLYPH_CYCLE: &[char] = &['\u{f1100}', '\u{f1101}', '\u{f1200}']; + +pub(crate) const PAINT_GLYPH_NESTED: &[char] = &[ + '\u{f1400}', + '\u{f1401}', + '\u{f1402}', + '\u{f1403}', + '\u{f1404}', + '\u{f1405}', + '\u{f1406}', + '\u{f1407}', + '\u{f1408}', + '\u{f1409}', + '\u{f140a}', + '\u{f140b}', + '\u{f140c}', + '\u{f140d}', + '\u{f140e}', + '\u{f140f}', +]; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,3 @@ +//! Basic representation of an in-memory font resource. + +pub use read_fonts::FontRef; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,201 @@ +//! Helpers for selecting a font size and location in variation space. + +use read_fonts::types::Fixed; + +use crate::collections::SmallVec; + +/// Type for a normalized variation coordinate. +pub type NormalizedCoord = read_fonts::types::F2Dot14; + +/// Font size in pixels per em units. +/// +/// Sizes in this crate are represented as a ratio of pixels to the size of +/// the em square defined by the font. This is equivalent to the `px` unit +/// in CSS (assuming a DPI scale factor of 1.0). +/// +/// To retrieve metrics and outlines in font units, use the [unscaled](Self::unscaled) +/// constructor on this type. +#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] +pub struct Size(Option); + +impl Size { + /// Creates a new font size from the given value in pixels per em units. + pub fn new(ppem: f32) -> Self { + Self(Some(ppem)) + } + + /// Creates a new font size for generating unscaled metrics or outlines in + /// font units. + pub fn unscaled() -> Self { + Self(None) + } + + /// Returns the raw size in pixels per em units. + /// + /// Results in `None` if the size is unscaled. + pub fn ppem(self) -> Option { + self.0 + } + + /// Computes a linear scale factor for this font size and the given units + /// per em value which can be retrieved from the [Metrics](crate::metrics::Metrics) + /// type or from the [head](read_fonts::tables::head::Head) table. + /// + /// Returns 1.0 for an unscaled size or when `units_per_em` is 0. + pub fn linear_scale(self, units_per_em: u16) -> f32 { + match self.0 { + Some(ppem) if units_per_em != 0 => ppem / units_per_em as f32, + _ => 1.0, + } + } + + /// Computes a fixed point linear scale factor that matches FreeType. + pub(crate) fn fixed_linear_scale(self, units_per_em: u16) -> Fixed { + // FreeType computes a 16.16 scale factor that converts to 26.6. + // This is done in two steps, assuming use of FT_Set_Pixel_Size: + // 1) height is multiplied by 64: + // + // 2) this value is divided by UPEM: + // (here, scaled_h=height and h=upem) + // + match self.0 { + Some(ppem) if units_per_em > 0 => { + Fixed::from_bits((ppem * 64.) as i32) / Fixed::from_bits(units_per_em as i32) + } + _ => { + // This is an identity scale for the pattern + // `mul_div(value, scale, 64)` + Fixed::from_bits(0x10000 * 64) + } + } + } +} + +/// Reference to an ordered sequence of normalized variation coordinates. +/// +/// To convert from user coordinates see [`crate::AxisCollection::location`]. +/// +/// This type represents a position in the variation space where each +/// coordinate corresponds to an axis (in the same order as the `fvar` table) +/// and is a normalized value in the range `[-1..1]`. +/// +/// See [Coordinate Scales and Normalization](https://learn.microsoft.com/en-us/typography/opentype/spec/otvaroverview#coordinate-scales-and-normalization) +/// for further details. +/// +/// If the array is larger in length than the number of axes, extraneous +/// values are ignored. If it is smaller, unrepresented axes are assumed to be +/// at their default positions (i.e. 0). +/// +/// A value of this type constructed with `default()` represents the default +/// position for each axis. +/// +/// Normalized coordinates are ignored for non-variable fonts. +#[derive(Copy, Clone, Default, Debug)] +pub struct LocationRef<'a>(&'a [NormalizedCoord]); + +impl<'a> LocationRef<'a> { + /// Creates a new sequence of normalized coordinates from the given array. + pub fn new(coords: &'a [NormalizedCoord]) -> Self { + Self(coords) + } + + /// Returns the underlying array of normalized coordinates. + pub fn coords(&self) -> &'a [NormalizedCoord] { + self.0 + } +} + +impl<'a> From<&'a [NormalizedCoord]> for LocationRef<'a> { + fn from(value: &'a [NormalizedCoord]) -> Self { + Self(value) + } +} + +impl<'a> IntoIterator for LocationRef<'a> { + type IntoIter = core::slice::Iter<'a, NormalizedCoord>; + type Item = &'a NormalizedCoord; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +impl<'a> IntoIterator for &'_ LocationRef<'a> { + type IntoIter = core::slice::Iter<'a, NormalizedCoord>; + type Item = &'a NormalizedCoord; + + fn into_iter(self) -> Self::IntoIter { + self.0.iter() + } +} + +/// Maximum number of coords to store inline in a `Location` object. +/// +/// This value was chosen to maximize use of space in the underlying +/// `SmallVec` storage. +const MAX_INLINE_COORDS: usize = 8; + +/// Ordered sequence of normalized variation coordinates. +/// +/// To produce from user coordinates see [`crate::AxisCollection::location`]. +/// +/// This is an owned version of [`LocationRef`]. See the documentation on that +/// type for more detail. +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct Location { + coords: SmallVec, +} + +impl Location { + /// Creates a new location with the given number of normalized coordinates. + /// + /// Each element will be initialized to the default value (0.0). + pub fn new(len: usize) -> Self { + Self { + coords: SmallVec::with_len(len, NormalizedCoord::default()), + } + } + + /// Returns the underlying slice of normalized coordinates. + pub fn coords(&self) -> &[NormalizedCoord] { + self.coords.as_slice() + } + + /// Returns a mutable reference to the underlying slice of normalized + /// coordinates. + pub fn coords_mut(&mut self) -> &mut [NormalizedCoord] { + self.coords.as_mut_slice() + } +} + +impl Default for Location { + fn default() -> Self { + Self { + coords: SmallVec::new(), + } + } +} + +impl<'a> From<&'a Location> for LocationRef<'a> { + fn from(value: &'a Location) -> Self { + LocationRef(value.coords()) + } +} + +impl<'a> IntoIterator for &'a Location { + type IntoIter = core::slice::Iter<'a, NormalizedCoord>; + type Item = &'a NormalizedCoord; + + fn into_iter(self) -> Self::IntoIter { + self.coords().iter() + } +} + +impl<'a> IntoIterator for &'a mut Location { + type IntoIter = core::slice::IterMut<'a, NormalizedCoord>; + type Item = &'a mut NormalizedCoord; + + fn into_iter(self) -> Self::IntoIter { + self.coords_mut().iter_mut() + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,69 @@ +//! A robust, ergonomic, high performance crate for OpenType fonts. +//! +//! Skrifa is a mid level library that provides access to various types +//! of [`metadata`](MetadataProvider) contained in a font as well as support +//! for loading glyph [`outlines`](outline). +//! +//! It is described as "mid level" because the library is designed to sit +//! above low level font parsing (provided by [`read-fonts`](https://crates.io/crates/read-fonts)) +//! and below a higher level text layout engine. +//! +//! See the [readme](https://github.com/googlefonts/fontations/blob/main/skrifa/README.md) +//! for additional details. + +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![forbid(unsafe_code)] +#![cfg_attr(not(any(test, feature = "std")), no_std)] + +#[cfg(not(any(feature = "libm", feature = "std")))] +compile_error!("Either feature \"std\" or \"libm\" must be enabled for this crate."); + +#[cfg(not(any(test, feature = "std")))] +#[macro_use] +extern crate core as std; + +#[macro_use] +extern crate alloc; + +/// Expose our "raw" underlying parser crate. +pub extern crate read_fonts as raw; + +pub mod attribute; +pub mod charmap; +pub mod color; +pub mod font; +pub mod instance; +pub mod metrics; +pub mod outline; + +pub mod setting; +pub mod string; + +mod collections; +mod provider; +mod variation; + +#[doc(inline)] +pub use outline::{OutlineGlyph, OutlineGlyphCollection}; +pub use variation::{Axis, AxisCollection, NamedInstance, NamedInstanceCollection}; + +/// Useful collection of common types suitable for glob importing. +pub mod prelude { + #[doc(no_inline)] + pub use super::{ + font::FontRef, + instance::{LocationRef, NormalizedCoord, Size}, + GlyphId, MetadataProvider, Tag, + }; +} + +pub use read_fonts::{ + types::{GlyphId, GlyphId16, Tag}, + FontRef, +}; + +#[doc(inline)] +pub use provider::MetadataProvider; + +/// Limit for recursion when loading TrueType composite glyphs. +const GLYF_COMPOSITE_RECURSION_LIMIT: usize = 32; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,584 @@ +//! Global font and glyph specific metrics. +//! +//! Metrics are various measurements that define positioning and layout +//! characteristics for a font. They come in two flavors: +//! +//! * Global metrics: these are applicable to all glyphs in a font and generally +//! define values that are used for the layout of a collection of glyphs. For example, +//! the ascent, descent and leading values determine the position of the baseline where +//! a glyph should be rendered as well as the suggested spacing above and below it. +//! +//! * Glyph metrics: these apply to single glyphs. For example, the advance +//! width value describes the distance between two consecutive glyphs on a line. +//! +//! ### Selecting an "instance" +//! Both global and glyph specific metrics accept two additional pieces of information +//! to select the desired instance of a font: +//! * Size: represented by the [Size] type, this determines the scaling factor that is +//! applied to all metrics. +//! * Normalized variation coordinates: represented by the [LocationRef] type, +//! these define the position in design space for a variable font. For a non-variable +//! font, these coordinates are ignored and you can pass [LocationRef::default()] +//! as an argument for this parameter. +//! + +use read_fonts::{ + tables::{ + glyf::Glyf, gvar::Gvar, hmtx::LongMetric, hvar::Hvar, loca::Loca, os2::SelectionFlags, + }, + types::{BigEndian, Fixed, GlyphId}, + TableProvider, +}; + +use super::instance::{LocationRef, NormalizedCoord, Size}; + +/// Type for a bounding box with single precision floating point coordinates. +pub type BoundingBox = read_fonts::types::BoundingBox; + +/// Metrics for a text decoration. +/// +/// This represents the suggested offset and thickness of an underline +/// or strikeout text decoration. +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub struct Decoration { + /// Offset to the top of the decoration from the baseline. + pub offset: f32, + /// Thickness of the decoration. + pub thickness: f32, +} + +/// Metrics that apply to all glyphs in a font. +/// +/// These are retrieved for a specific position in the design space. +/// +/// This metrics here are derived from the following tables: +/// * [head](https://learn.microsoft.com/en-us/typography/opentype/spec/head): `units_per_em`, `bounds` +/// * [maxp](https://learn.microsoft.com/en-us/typography/opentype/spec/maxp): `glyph_count` +/// * [post](https://learn.microsoft.com/en-us/typography/opentype/spec/post): `is_monospace`, `italic_angle`, `underline` +/// * [OS/2](https://learn.microsoft.com/en-us/typography/opentype/spec/os2): `average_width`, `cap_height`, +/// `x_height`, `strikeout`, as well as the line metrics: `ascent`, `descent`, `leading` if the `USE_TYPOGRAPHIC_METRICS` +/// flag is set or the `hhea` line metrics are zero (the Windows metrics are used as a last resort). +/// * [hhea](https://learn.microsoft.com/en-us/typography/opentype/spec/hhea): `max_width`, as well as the line metrics: +/// `ascent`, `descent`, `leading` if they are non-zero and the `USE_TYPOGRAPHIC_METRICS` flag is not set in the OS/2 table +/// +/// For variable fonts, deltas are computed using the [MVAR](https://learn.microsoft.com/en-us/typography/opentype/spec/MVAR) +/// table. +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub struct Metrics { + /// Number of font design units per em unit. + pub units_per_em: u16, + /// Number of glyphs in the font. + pub glyph_count: u16, + /// True if the font is not proportionally spaced. + pub is_monospace: bool, + /// Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, + /// negative for text that leans to the right. + pub italic_angle: f32, + /// Distance from the baseline to the top of the alignment box. + pub ascent: f32, + /// Distance from the baseline to the bottom of the alignment box. + pub descent: f32, + /// Recommended additional spacing between lines. + pub leading: f32, + /// Distance from the baseline to the top of a typical English capital. + pub cap_height: Option, + /// Distance from the baseline to the top of the lowercase "x" or + /// similar character. + pub x_height: Option, + /// Average width of all non-zero width characters in the font. + pub average_width: Option, + /// Maximum advance width of all characters in the font. + pub max_width: Option, + /// Metrics for an underline decoration. + pub underline: Option, + /// Metrics for a strikeout decoration. + pub strikeout: Option, + /// Union of minimum and maximum extents for all glyphs in the font. + pub bounds: Option, +} + +impl Metrics { + /// Creates new metrics for the given font, size, and location in + /// normalized variation space. + pub fn new<'a>( + font: &impl TableProvider<'a>, + size: Size, + location: impl Into>, + ) -> Self { + let head = font.head(); + let mut metrics = Metrics { + units_per_em: head.map(|head| head.units_per_em()).unwrap_or_default(), + ..Default::default() + }; + let coords = location.into().coords(); + let scale = size.linear_scale(metrics.units_per_em); + if let Ok(head) = font.head() { + metrics.bounds = Some(BoundingBox { + x_min: head.x_min() as f32 * scale, + y_min: head.y_min() as f32 * scale, + x_max: head.x_max() as f32 * scale, + y_max: head.y_max() as f32 * scale, + }); + } + if let Ok(maxp) = font.maxp() { + metrics.glyph_count = maxp.num_glyphs(); + } + if let Ok(post) = font.post() { + metrics.is_monospace = post.is_fixed_pitch() != 0; + metrics.italic_angle = post.italic_angle().to_f64() as f32; + metrics.underline = Some(Decoration { + offset: post.underline_position().to_i16() as f32 * scale, + thickness: post.underline_thickness().to_i16() as f32 * scale, + }); + } + let hhea = font.hhea(); + if let Ok(hhea) = &hhea { + metrics.max_width = Some(hhea.advance_width_max().to_u16() as f32 * scale); + } + // Choosing proper line metrics is a challenge due to the changing + // spec, backward compatibility and broken fonts. + // + // We use the same strategy as FreeType: + // 1. Use the OS/2 metrics if the table exists and the USE_TYPO_METRICS + // flag is set. + // 2. Otherwise, use the hhea metrics. + // 3. If hhea metrics are zero and the OS/2 table exists: + // 3a. Use the typo metrics if they are non-zero + // 3b. Otherwise, use the win metrics + // + // See: https://github.com/freetype/freetype/blob/5c37b6406258ec0d7ab64b8619c5ea2c19e3c69a/src/sfnt/sfobjs.c#L1311 + let os2 = font.os2().ok(); + let mut used_typo_metrics = false; + if let Some(os2) = &os2 { + if os2 + .fs_selection() + .contains(SelectionFlags::USE_TYPO_METRICS) + { + metrics.ascent = os2.s_typo_ascender() as f32 * scale; + metrics.descent = os2.s_typo_descender() as f32 * scale; + metrics.leading = os2.s_typo_line_gap() as f32 * scale; + used_typo_metrics = true; + } + metrics.average_width = Some(os2.x_avg_char_width() as f32 * scale); + metrics.cap_height = os2.s_cap_height().map(|v| v as f32 * scale); + metrics.x_height = os2.sx_height().map(|v| v as f32 * scale); + metrics.strikeout = Some(Decoration { + offset: os2.y_strikeout_position() as f32 * scale, + thickness: os2.y_strikeout_size() as f32 * scale, + }); + } + if !used_typo_metrics { + if let Ok(hhea) = font.hhea() { + metrics.ascent = hhea.ascender().to_i16() as f32 * scale; + metrics.descent = hhea.descender().to_i16() as f32 * scale; + metrics.leading = hhea.line_gap().to_i16() as f32 * scale; + } + if metrics.ascent == 0.0 && metrics.descent == 0.0 { + if let Some(os2) = &os2 { + if os2.s_typo_ascender() != 0 || os2.s_typo_descender() != 0 { + metrics.ascent = os2.s_typo_ascender() as f32 * scale; + metrics.descent = os2.s_typo_descender() as f32 * scale; + metrics.leading = os2.s_typo_line_gap() as f32 * scale; + } else { + metrics.ascent = os2.us_win_ascent() as f32 * scale; + // Win descent is always positive while other descent values are negative. Negate it + // to ensure we return consistent metrics. + metrics.descent = -(os2.us_win_descent() as f32 * scale); + } + } + } + } + if let (Ok(mvar), true) = (font.mvar(), !coords.is_empty()) { + use read_fonts::tables::mvar::tags::*; + let metric_delta = + |tag| mvar.metric_delta(tag, coords).unwrap_or_default().to_f64() as f32 * scale; + metrics.ascent += metric_delta(HASC); + metrics.descent += metric_delta(HDSC); + metrics.leading += metric_delta(HLGP); + if let Some(cap_height) = &mut metrics.cap_height { + *cap_height += metric_delta(CPHT); + } + if let Some(x_height) = &mut metrics.x_height { + *x_height += metric_delta(XHGT); + } + if let Some(underline) = &mut metrics.underline { + underline.offset += metric_delta(UNDO); + underline.thickness += metric_delta(UNDS); + } + if let Some(strikeout) = &mut metrics.strikeout { + strikeout.offset += metric_delta(STRO); + strikeout.thickness += metric_delta(STRS); + } + } + metrics + } +} + +/// Glyph specific metrics. +#[derive(Clone)] +pub struct GlyphMetrics<'a> { + glyph_count: u32, + fixed_scale: FixedScaleFactor, + h_metrics: &'a [LongMetric], + default_advance_width: u16, + lsbs: &'a [BigEndian], + hvar: Option>, + gvar: Option>, + loca_glyf: Option<(Loca<'a>, Glyf<'a>)>, + coords: &'a [NormalizedCoord], +} + +impl<'a> GlyphMetrics<'a> { + /// Creates new glyph metrics from the given font, size, and location in + /// normalized variation space. + pub fn new( + font: &impl TableProvider<'a>, + size: Size, + location: impl Into>, + ) -> Self { + let glyph_count = font + .maxp() + .map(|maxp| maxp.num_glyphs() as u32) + .unwrap_or_default(); + let upem = font + .head() + .map(|head| head.units_per_em()) + .unwrap_or_default(); + let fixed_scale = FixedScaleFactor(size.fixed_linear_scale(upem)); + let coords = location.into().coords(); + let (h_metrics, default_advance_width, lsbs) = font + .hmtx() + .map(|hmtx| { + let h_metrics = hmtx.h_metrics(); + let default_advance_width = h_metrics.last().map(|m| m.advance.get()).unwrap_or(0); + let lsbs = hmtx.left_side_bearings(); + (h_metrics, default_advance_width, lsbs) + }) + .unwrap_or_default(); + let hvar = font.hvar().ok(); + let gvar = font.gvar().ok(); + let loca_glyf = if let (Ok(loca), Ok(glyf)) = (font.loca(None), font.glyf()) { + Some((loca, glyf)) + } else { + None + }; + Self { + glyph_count, + fixed_scale, + h_metrics, + default_advance_width, + lsbs, + hvar, + gvar, + loca_glyf, + coords, + } + } + + /// Returns the number of available glyphs in the font. + pub fn glyph_count(&self) -> u32 { + self.glyph_count + } + + /// Returns the advance width for the specified glyph. + /// + /// If normalized coordinates were provided when constructing glyph metrics and + /// an `HVAR` table is present, applies the appropriate delta. + /// + /// Returns `None` if `glyph_id >= self.glyph_count()` or the underlying font + /// data is invalid. + pub fn advance_width(&self, glyph_id: GlyphId) -> Option { + if glyph_id.to_u32() >= self.glyph_count { + return None; + } + let mut advance = self + .h_metrics + .get(glyph_id.to_u32() as usize) + .map(|metric| metric.advance()) + .unwrap_or(self.default_advance_width) as i32; + if let Some(hvar) = &self.hvar { + advance += hvar + .advance_width_delta(glyph_id, self.coords) + // FreeType truncates metric deltas... + // https://github.com/freetype/freetype/blob/7838c78f53f206ac5b8e9cefde548aa81cb00cf4/src/truetype/ttgxvar.c#L1027 + .map(|delta| delta.to_f64() as i32) + .unwrap_or(0); + } else if self.gvar.is_some() { + advance += self.metric_deltas_from_gvar(glyph_id).unwrap_or_default()[1]; + } + Some(self.fixed_scale.apply(advance)) + } + + /// Returns the left side bearing for the specified glyph. + /// + /// If normalized coordinates were provided when constructing glyph metrics and + /// an `HVAR` table is present, applies the appropriate delta. + /// + /// Returns `None` if `glyph_id >= self.glyph_count()` or the underlying font + /// data is invalid. + pub fn left_side_bearing(&self, glyph_id: GlyphId) -> Option { + if glyph_id.to_u32() >= self.glyph_count { + return None; + } + let gid_index = glyph_id.to_u32() as usize; + let mut lsb = self + .h_metrics + .get(gid_index) + .map(|metric| metric.side_bearing()) + .unwrap_or_else(|| { + self.lsbs + .get(gid_index.saturating_sub(self.h_metrics.len())) + .map(|lsb| lsb.get()) + .unwrap_or_default() + }) as i32; + if let Some(hvar) = &self.hvar { + lsb += hvar + .lsb_delta(glyph_id, self.coords) + // FreeType truncates metric deltas... + // https://github.com/freetype/freetype/blob/7838c78f53f206ac5b8e9cefde548aa81cb00cf4/src/truetype/ttgxvar.c#L1027 + .map(|delta| delta.to_f64() as i32) + .unwrap_or(0); + } else if self.gvar.is_some() { + lsb += self.metric_deltas_from_gvar(glyph_id).unwrap_or_default()[0]; + } + Some(self.fixed_scale.apply(lsb)) + } + + /// Returns the bounding box for the specified glyph. + /// + /// Note that variations are not reflected in the bounding box returned by + /// this method. + /// + /// Returns `None` if `glyph_id >= self.glyph_count()`, the underlying font + /// data is invalid, or the font does not contain TrueType outlines. + pub fn bounds(&self, glyph_id: GlyphId) -> Option { + let (loca, glyf) = self.loca_glyf.as_ref()?; + Some(match loca.get_glyf(glyph_id, glyf).ok()? { + Some(glyph) => BoundingBox { + x_min: self.fixed_scale.apply(glyph.x_min() as i32), + y_min: self.fixed_scale.apply(glyph.y_min() as i32), + x_max: self.fixed_scale.apply(glyph.x_max() as i32), + y_max: self.fixed_scale.apply(glyph.y_max() as i32), + }, + // Empty glyphs have an empty bounding box + None => BoundingBox::default(), + }) + } +} + +impl GlyphMetrics<'_> { + fn metric_deltas_from_gvar(&self, glyph_id: GlyphId) -> Option<[i32; 2]> { + let (loca, glyf) = self.loca_glyf.as_ref()?; + let mut deltas = self + .gvar + .as_ref()? + .phantom_point_deltas(glyf, loca, self.coords, glyph_id) + .ok()?; + deltas[1] -= deltas[0]; + Some([deltas[0], deltas[1]].map(|delta| delta.x.to_i32())) + } +} + +#[derive(Copy, Clone)] +struct FixedScaleFactor(Fixed); + +impl FixedScaleFactor { + #[inline(always)] + fn apply(self, value: i32) -> f32 { + // Match FreeType metric scaling + // + self.0 + .mul_div(Fixed::from_bits(value), Fixed::from_bits(64)) + .to_f32() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::MetadataProvider as _; + use font_test_data::{SIMPLE_GLYF, VAZIRMATN_VAR}; + use read_fonts::FontRef; + + #[test] + fn metrics() { + let font = FontRef::new(SIMPLE_GLYF).unwrap(); + let metrics = font.metrics(Size::unscaled(), LocationRef::default()); + let expected = Metrics { + units_per_em: 1024, + glyph_count: 3, + bounds: Some(BoundingBox { + x_min: 51.0, + y_min: -250.0, + x_max: 998.0, + y_max: 950.0, + }), + average_width: Some(1275.0), + max_width: None, + x_height: Some(512.0), + cap_height: Some(717.0), + is_monospace: false, + italic_angle: 0.0, + ascent: 950.0, + descent: -250.0, + leading: 0.0, + underline: None, + strikeout: Some(Decoration { + offset: 307.0, + thickness: 51.0, + }), + }; + assert_eq!(metrics, expected); + } + + #[test] + fn metrics_missing_os2() { + let font = FontRef::new(VAZIRMATN_VAR).unwrap(); + let metrics = font.metrics(Size::unscaled(), LocationRef::default()); + let expected = Metrics { + units_per_em: 2048, + glyph_count: 4, + bounds: Some(BoundingBox { + x_min: 29.0, + y_min: 0.0, + x_max: 1310.0, + y_max: 1847.0, + }), + average_width: None, + max_width: Some(1336.0), + x_height: None, + cap_height: None, + is_monospace: false, + italic_angle: 0.0, + ascent: 2100.0, + descent: -1100.0, + leading: 0.0, + underline: None, + strikeout: None, + }; + assert_eq!(metrics, expected); + } + + #[test] + fn glyph_metrics() { + let font = FontRef::new(VAZIRMATN_VAR).unwrap(); + let glyph_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::default()); + // (advance_width, lsb) in glyph order + let expected = &[ + (908.0, 100.0), + (1336.0, 29.0), + (1336.0, 29.0), + (633.0, 57.0), + ]; + let result = (0..4) + .map(|i| { + let gid = GlyphId::new(i as u32); + let advance_width = glyph_metrics.advance_width(gid).unwrap(); + let lsb = glyph_metrics.left_side_bearing(gid).unwrap(); + (advance_width, lsb) + }) + .collect::>(); + assert_eq!(expected, &result[..]); + } + + /// Asserts that the results generated with Size::unscaled() and + /// Size::new(upem) are equal. + /// + /// See + #[test] + fn glyph_metrics_unscaled_matches_upem_scale() { + let font = FontRef::new(VAZIRMATN_VAR).unwrap(); + let upem = font.head().unwrap().units_per_em() as f32; + let unscaled_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::default()); + let upem_metrics = font.glyph_metrics(Size::new(upem), LocationRef::default()); + for i in 0..unscaled_metrics.glyph_count() { + let gid = GlyphId::new(i); + assert_eq!( + unscaled_metrics.advance_width(gid), + upem_metrics.advance_width(gid) + ); + assert_eq!( + unscaled_metrics.left_side_bearing(gid), + upem_metrics.left_side_bearing(gid) + ); + } + } + + #[test] + fn glyph_metrics_var() { + let font = FontRef::new(VAZIRMATN_VAR).unwrap(); + let coords = &[NormalizedCoord::from_f32(-0.8)]; + let glyph_metrics = font.glyph_metrics(Size::unscaled(), LocationRef::new(coords)); + // (advance_width, lsb) in glyph order + let expected = &[ + (908.0, 100.0), + (1246.0, 29.0), + (1246.0, 29.0), + (556.0, 57.0), + ]; + let result = (0..4) + .map(|i| { + let gid = GlyphId::new(i as u32); + let advance_width = glyph_metrics.advance_width(gid).unwrap(); + let lsb = glyph_metrics.left_side_bearing(gid).unwrap(); + (advance_width, lsb) + }) + .collect::>(); + assert_eq!(expected, &result[..]); + } + + #[test] + fn glyph_metrics_missing_hvar() { + let font = FontRef::new(VAZIRMATN_VAR).unwrap(); + let glyph_count = font.maxp().unwrap().num_glyphs(); + // Test a few different locations in variation space + for coord in [-1.0, -0.8, 0.0, 0.75, 1.0] { + let coords = &[NormalizedCoord::from_f32(coord)]; + let location = LocationRef::new(coords); + let glyph_metrics = font.glyph_metrics(Size::unscaled(), location); + let mut glyph_metrics_no_hvar = glyph_metrics.clone(); + // Setting hvar to None forces use of gvar for metric deltas + glyph_metrics_no_hvar.hvar = None; + for gid in 0..glyph_count { + let gid = GlyphId::from(gid); + assert_eq!( + glyph_metrics.advance_width(gid), + glyph_metrics_no_hvar.advance_width(gid) + ); + assert_eq!( + glyph_metrics.left_side_bearing(gid), + glyph_metrics_no_hvar.left_side_bearing(gid) + ); + } + } + } + + /// Ensure our fixed point scaling code matches FreeType for advances. + /// + /// + #[test] + fn match_freetype_glyph_metric_scaling() { + // fontations: + // gid: 36 advance: 15.33600044250488281250 gid: 68 advance: 13.46399974822998046875 gid: 47 advance: 12.57600021362304687500 gid: 79 advance: 6.19199991226196289062 + // ft: + // gid: 36 advance: 15.33595275878906250000 gid: 68 advance: 13.46395874023437500000 gid: 47 advance: 12.57595825195312500000 gid: 79 advance: 6.19198608398437500000 + // with font.setSize(24); + // + // Raw advances for gids 36, 68, 47, and 79 in NotoSans-Regular + let font_unit_advances = [639, 561, 524, 258]; + #[allow(clippy::excessive_precision)] + let scaled_advances = [ + 15.33595275878906250000, + 13.46395874023437500000, + 12.57595825195312500000, + 6.19198608398437500000, + ]; + let fixed_scale = FixedScaleFactor(Size::new(24.0).fixed_linear_scale(1000)); + for (font_unit_advance, expected_scaled_advance) in + font_unit_advances.iter().zip(scaled_advances) + { + let scaled_advance = fixed_scale.apply(*font_unit_advance); + assert_eq!(scaled_advance, expected_scaled_advance); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,949 @@ +//! Edge hinting. +//! +//! Let's actually do some grid fitting. Here we align edges to the pixel +//! grid. This is the final step before applying the edge adjustments to +//! the original outline points. + +use super::super::{ + metrics::{fixed_mul_div, pix_floor, pix_round, Scale, ScaledAxisMetrics, ScaledWidth}, + style::ScriptGroup, + topo::{Axis, Edge}, +}; + +/// Main Latin grid-fitting routine. +/// +/// Note: this is one huge function in FreeType, broken up into several below. +/// +/// See +pub(crate) fn hint_edges( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, + mut top_to_bottom_hinting: bool, +) { + if axis.dim != Axis::VERTICAL { + top_to_bottom_hinting = false; + } + // First align horizontal edges to blue zones if needed + let anchor_ix = align_edges_to_blues(axis, metrics, group, scale); + // Now align the stem edges + let (serif_count, anchor_ix) = align_stem_edges( + axis, + metrics, + group, + scale, + top_to_bottom_hinting, + anchor_ix, + ); + let edges = axis.edges.as_mut_slice(); + // Special case for lowercase m + if axis.dim == Axis::HORIZONTAL && (edges.len() == 6 || edges.len() == 12) { + hint_lowercase_m(edges, group); + } + // Handle serifs and single segment edges + if serif_count > 0 || anchor_ix.is_none() { + align_remaining_edges(axis, group, top_to_bottom_hinting, serif_count, anchor_ix); + } +} + +/// Align horizontal edges to blue zones. +/// +/// See +fn align_edges_to_blues( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, +) -> Option { + let mut anchor_ix = None; + // For default script group, only do vertical blues + if group == ScriptGroup::Default && axis.dim != Axis::VERTICAL { + return anchor_ix; + } + for edge_ix in 0..axis.edges.len() { + let edges = axis.edges.as_mut_slice(); + let edge = &edges[edge_ix]; + if edge.flags & Edge::DONE != 0 { + continue; + } + let edge2_ix = edge.link_ix.map(|x| x as usize); + let edge2 = edge2_ix.map(|ix| &edges[ix]); + // If we have two neutral zones, skip one of them. + if let (true, Some(edge2)) = (edge.blue_edge.is_some(), edge2) { + if edge2.blue_edge.is_some() { + let skip_ix = if edge2.flags & Edge::NEUTRAL != 0 { + edge2_ix + } else if edge.flags & Edge::NEUTRAL != 0 { + Some(edge_ix) + } else { + None + }; + if let Some(skip_ix) = skip_ix { + let skip_edge = &mut edges[skip_ix]; + skip_edge.blue_edge = None; + skip_edge.flags &= !Edge::NEUTRAL; + } + } + } + // Flip edges if the other is aligned to a blue zone + let blue = edges[edge_ix].blue_edge; + let (blue, edge1_ix, edge2_ix) = if let Some(blue) = blue { + (blue, Some(edge_ix), edge2_ix) + } else if let Some(edge2_blue) = edge2_ix.and_then(|ix| edges[ix].blue_edge) { + (edge2_blue, edge2_ix, Some(edge_ix)) + } else { + (Default::default(), None, None) + }; + let Some(edge1_ix) = edge1_ix else { + continue; + }; + let edge1 = &mut edges[edge1_ix]; + edge1.pos = blue.fitted; + edge1.flags |= Edge::DONE; + if let Some(edge2_ix) = edge2_ix { + let edge2 = &mut edges[edge2_ix]; + if edge2.blue_edge.is_none() { + edge2.flags |= Edge::DONE; + align_linked_edge(axis, metrics, group, scale, edge1_ix, edge2_ix); + } + } + if anchor_ix.is_none() { + anchor_ix = Some(edge_ix); + } + } + anchor_ix +} + +/// Align stem edges, trying to main relative order of stems in the glyph. +/// +/// See +fn align_stem_edges( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, + top_to_bottom_hinting: bool, + mut anchor_ix: Option, +) -> (usize, Option) { + let mut serif_count = 0; + let mut last_stem_pos = None; + let mut delta = 0; + // Now align all other stem edges + // This code starts at: + for edge_ix in 0..axis.edges.len() { + let edges = axis.edges.as_mut_slice(); + let edge = &edges[edge_ix]; + if edge.flags & Edge::DONE != 0 { + continue; + } + // Skip all non-stem edges + let Some(edge2_ix) = edge.link_ix.map(|ix| ix as usize) else { + serif_count += 1; + continue; + }; + // For CJK, skip stems that are too close. We'll deal with them later + // See + if group != ScriptGroup::Default { + if let Some(last_pos) = last_stem_pos { + if edge.pos < last_pos + 64 || edges[edge2_ix].pos < last_pos + 64 { + serif_count += 1; + continue; + } + } + } + // This shouldn't happen? + if edges[edge2_ix].blue_edge.is_some() { + edges[edge2_ix].flags |= Edge::DONE; + align_linked_edge(axis, metrics, group, scale, edge2_ix, edge_ix); + continue; + } + if group == ScriptGroup::Default { + // Now align the stem + // Note: the branches here are reversed from the FreeType code + // See + if let Some(anchor_ix) = anchor_ix { + let anchor = &edges[anchor_ix]; + let edge = edges[edge_ix]; + let edge2 = edges[edge2_ix]; + let original_pos = anchor.pos + (edge.opos - anchor.opos); + let original_len = edge2.opos - edge.opos; + let original_center = original_pos + (original_len >> 1); + let cur_len = stem_width( + metrics, + group, + scale, + original_len, + 0, + edge.flags, + edge2.flags, + ); + if edge2.flags & Edge::DONE != 0 { + let new_pos = edge2.pos - cur_len; + edges[edge_ix].pos = new_pos; + } else if cur_len < 96 { + let cur_pos1 = pix_round(original_center); + let (u_off, d_off) = if cur_len <= 64 { (32, 32) } else { (38, 26) }; + let delta1 = (original_center - (cur_pos1 - u_off)).abs(); + let delta2 = (original_center - (cur_pos1 + d_off)).abs(); + let cur_pos1 = if delta1 < delta2 { + cur_pos1 - u_off + } else { + cur_pos1 + d_off + }; + edges[edge_ix].pos = cur_pos1 - cur_len / 2; + edges[edge2_ix].pos = cur_pos1 + cur_len / 2; + } else { + let cur_pos1 = pix_round(original_pos); + let delta1 = (cur_pos1 + (cur_len >> 1) - original_center).abs(); + let cur_pos2 = pix_round(original_pos + original_len) - cur_len; + let delta2 = (cur_pos2 + (cur_len >> 1) - original_center).abs(); + let new_pos = if delta1 < delta2 { cur_pos1 } else { cur_pos2 }; + let new_pos2 = new_pos + cur_len; + edges[edge_ix].pos = new_pos; + edges[edge2_ix].pos = new_pos2; + } + edges[edge_ix].flags |= Edge::DONE; + edges[edge2_ix].flags |= Edge::DONE; + if edge_ix > 0 { + adjust_link(edges, edge_ix, LinkDir::Prev, top_to_bottom_hinting); + } + } else { + // No stem has been aligned yet + let edge = edges[edge_ix]; + let edge2 = edges[edge2_ix]; + let original_len = edge2.opos - edge.opos; + let cur_len = stem_width( + metrics, + group, + scale, + original_len, + 0, + edge.flags, + edge2.flags, + ); + // Some "voodoo" to specially round edges for small stem widths + let (u_off, d_off) = if cur_len <= 64 { + // width <= 1px + (32, 32) + } else { + // 1px < width < 1.5px + (38, 26) + }; + if cur_len < 96 { + let original_center = edge.opos + (original_len >> 1); + let mut cur_pos1 = pix_round(original_center); + let error1 = (original_center - (cur_pos1 - u_off)).abs(); + let error2 = (original_center - (cur_pos1 + d_off)).abs(); + if error1 < error2 { + cur_pos1 -= u_off; + } else { + cur_pos1 += d_off; + } + let edge_pos = cur_pos1 - cur_len / 2; + edges[edge_ix].pos = edge_pos; + edges[edge2_ix].pos = edge_pos + cur_len; + } else { + edges[edge_ix].pos = pix_round(edge.opos); + } + edges[edge_ix].flags |= Edge::DONE; + align_linked_edge(axis, metrics, group, scale, edge_ix, edge2_ix); + anchor_ix = Some(edge_ix); + } + } else { + // More CJK divergence + // See + if edge2_ix < edge_ix { + last_stem_pos = Some(edge.pos); + edges[edge_ix].flags |= Edge::DONE; + align_linked_edge(axis, metrics, group, scale, edge2_ix, edge_ix); + continue; + } + if axis.dim != Axis::VERTICAL && anchor_ix.is_none() { + delta = hint_normal_stem_cjk(axis, metrics, group, scale, edge_ix, edge2_ix, delta); + } else { + hint_normal_stem_cjk(axis, metrics, group, scale, edge_ix, edge2_ix, delta); + } + anchor_ix = Some(edge_ix); + axis.edges[edge_ix].flags |= Edge::DONE; + let edge2 = &mut axis.edges[edge2_ix]; + edge2.flags |= Edge::DONE; + last_stem_pos = Some(edge2.pos); + } + } + (serif_count, anchor_ix) +} + +/// Make sure that lowercase m's maintain symmetry. +/// +/// See +fn hint_lowercase_m(edges: &mut [Edge], group: ScriptGroup) { + let (edge1_ix, edge2_ix, edge3_ix) = if edges.len() == 6 { + (0, 2, 4) + } else { + (1, 5, 9) + }; + let edge1 = &edges[edge1_ix]; + let edge2 = &edges[edge2_ix]; + let edge3 = &edges[edge3_ix]; + let dist1 = edge2.opos - edge1.opos; + let dist2 = edge3.opos - edge2.opos; + let span = (dist1 - dist2).abs(); + if group != ScriptGroup::Default { + // CJK has additional conditions on the following... + // See + for (edge, ix) in [(edge1, edge1_ix), (edge2, edge2_ix), (edge3, edge3_ix)] { + if edge.link_ix != Some((ix + 1) as u16) { + return; + } + } + } + if span < 8 { + let delta = edge3.pos - (2 * edge2.pos - edge1.pos); + let link_ix = edge3.link_ix.map(|ix| ix as usize); + let edge3 = &mut edges[edge3_ix]; + edge3.pos -= delta; + edge3.flags |= Edge::DONE; + if let Some(link_ix) = link_ix { + let link = &mut edges[link_ix]; + link.pos -= delta; + link.flags |= Edge::DONE; + } + // Move serifs along with the stem + if edges.len() == 12 { + edges[8].pos -= delta; + edges[11].pos -= delta; + } + } +} + +/// Align serif and single segment edges. +fn align_remaining_edges( + axis: &mut Axis, + group: ScriptGroup, + top_to_bottom_hinting: bool, + mut serif_count: usize, + mut anchor_ix: Option, +) { + if group == ScriptGroup::Default { + // See + for edge_ix in 0..axis.edges.len() { + let edges = &mut axis.edges; + let edge = &edges[edge_ix]; + if edge.flags & Edge::DONE != 0 { + continue; + } + let mut delta = 1000; + if let Some(serif) = edge.serif(edges) { + delta = (serif.opos - edge.opos).abs(); + } + if delta < 64 + 16 { + // delta is only < 1000 if edge.serif_ix is Some(_) + let serif_ix = edge.serif_ix.unwrap() as usize; + align_serif_edge(axis, serif_ix, edge_ix) + } else if let Some(anchor_ix) = anchor_ix { + let [before_ix, after_ix] = find_bounding_completed_edges(edges, edge_ix); + if let Some((before_ix, after_ix)) = before_ix.zip(after_ix) { + let before = &edges[before_ix]; + let after = &edges[after_ix]; + let new_pos = if after.opos == before.opos { + before.pos + } else { + before.pos + + fixed_mul_div( + edge.opos - before.opos, + after.pos - before.pos, + after.opos - before.opos, + ) + }; + edges[edge_ix].pos = new_pos; + } else { + let anchor = &edges[anchor_ix]; + let new_pos = anchor.pos + ((edge.opos - anchor.opos + 16) & !31); + edges[edge_ix].pos = new_pos; + } + } else { + anchor_ix = Some(edge_ix); + let new_pos = pix_round(edge.opos); + edges[edge_ix].pos = new_pos; + } + let edges = &mut axis.edges; + edges[edge_ix].flags |= Edge::DONE; + adjust_link(edges, edge_ix, LinkDir::Prev, top_to_bottom_hinting); + adjust_link(edges, edge_ix, LinkDir::Next, top_to_bottom_hinting); + } + } else { + // See + for edge_ix in 0..axis.edges.len() { + let edge = &mut axis.edges[edge_ix]; + if edge.flags & Edge::DONE != 0 { + continue; + } + if let Some(serif_ix) = edge.serif_ix.map(|ix| ix as usize) { + edge.flags |= Edge::DONE; + align_serif_edge(axis, serif_ix, edge_ix); + serif_count = serif_count.saturating_sub(1); + } + } + if serif_count == 0 { + return; + } + for edge_ix in 0..axis.edges.len() { + let edges = axis.edges.as_mut_slice(); + let edge = &edges[edge_ix]; + if edge.flags & Edge::DONE != 0 { + continue; + } + let [before_ix, after_ix] = find_bounding_completed_edges(edges, edge_ix); + match (before_ix, after_ix) { + (Some(before_ix), None) => { + align_serif_edge(axis, before_ix, edge_ix); + } + (None, Some(after_ix)) => { + align_serif_edge(axis, after_ix, edge_ix); + } + (Some(before_ix), Some(after_ix)) => { + let before = edges[before_ix]; + let after = edges[after_ix]; + if after.fpos == before.fpos { + edges[edge_ix].pos = before.pos; + } else { + edges[edge_ix].pos = before.pos + + fixed_mul_div( + edge.fpos as i32 - before.fpos as i32, + after.pos - before.pos, + after.fpos as i32 - before.fpos as i32, + ); + } + } + _ => {} + } + } + } +} + +#[derive(Copy, Clone, PartialEq)] +enum LinkDir { + Prev, + Next, +} + +/// Helper to adjust links based on hinting direction. +/// +/// See +fn adjust_link( + edges: &mut [Edge], + edge_ix: usize, + link_dir: LinkDir, + top_to_bottom_hinting: bool, +) -> Option<()> { + let edge = &edges[edge_ix]; + let (edge2, prev_edge) = if link_dir == LinkDir::Next { + let edge2 = edges.get(edge_ix + 1)?; + // Don't adjust next edge if it's not done yet + if edge2.flags & Edge::DONE == 0 { + return None; + } + (edge2, edges.get(edge_ix.checked_sub(1)?)?) + } else { + let edge = edges.get(edge_ix.checked_sub(1)?)?; + (edge, edge) + }; + let pos1 = edge.pos; + let pos2 = edge2.pos; + let order_check = match (link_dir, top_to_bottom_hinting) { + (LinkDir::Prev, true) | (LinkDir::Next, false) => pos1 > pos2, + (LinkDir::Prev, false) | (LinkDir::Next, true) => pos1 < pos2, + }; + if !order_check { + return None; + } + let link = edge.link(edges)?; + if (link.pos - prev_edge.pos).abs() > 16 { + let new_pos = edge2.pos; + edges[edge_ix].pos = new_pos; + } + Some(()) +} + +/// Returns the indices of the "completed" edges before and after the given +/// edge index. +fn find_bounding_completed_edges(edges: &[Edge], ix: usize) -> [Option; 2] { + let before_ix = edges + .get(..ix) + .unwrap_or_default() + .iter() + .enumerate() + .rev() + .filter_map(|(ix, edge)| (edge.flags & Edge::DONE != 0).then_some(ix)) + .next(); + let after_ix = edges + .iter() + .enumerate() + .skip(ix + 1) + .filter_map(|(ix, edge)| (edge.flags & Edge::DONE != 0).then_some(ix)) + .next(); + [before_ix, after_ix] +} + +/// Snap a scaled width to one of the standard widths. +/// +/// See +fn snap_width(widths: &[ScaledWidth], width: i32) -> i32 { + let (_, ref_width) = + widths + .iter() + .fold((64 + 32 + 2, width), |(best_dist, ref_width), candidate| { + let dist = (width - candidate.scaled).abs(); + if dist < best_dist { + (dist, candidate.scaled) + } else { + (best_dist, ref_width) + } + }); + let scaled = pix_round(ref_width); + if width >= ref_width { + if width < scaled + 48 { + ref_width + } else { + width + } + } else if width > scaled - 48 { + ref_width + } else { + width + } +} + +/// Compute the snapped width of a given stem. +/// +/// See +fn stem_width( + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, + width: i32, + base_delta: i32, + base_flags: u8, + stem_flags: u8, +) -> i32 { + if scale.flags & Scale::STEM_ADJUST == 0 + || (group == ScriptGroup::Default && metrics.width_metrics.is_extra_light) + { + return width; + } + let is_vertical = metrics.dim == Axis::VERTICAL; + let sign = if width < 0 { -1 } else { 1 }; + let mut dist = width.abs(); + if (is_vertical && scale.flags & Scale::VERTICAL_SNAP == 0) + || (!is_vertical && scale.flags & Scale::HORIZONTAL_SNAP == 0) + { + // Do smooth hinting + if group == ScriptGroup::Default { + if (stem_flags & Edge::SERIF != 0) && is_vertical && (dist < 3 * 64) { + // Don't touch widths of serifs + return dist * sign; + } else if base_flags & Edge::ROUND != 0 { + if dist < 80 { + dist = 64; + } + } else if dist < 56 { + dist = 56; + } + } + if !metrics.widths.is_empty() { + // Compare to standard width + let min_width = metrics.widths[0].scaled; + let delta = (dist - min_width).abs(); + if delta < 40 { + dist = min_width.max(48); + return dist * sign; + } + if group == ScriptGroup::Default { + // Default/Latin behavior + // See + if dist < 3 * 64 { + let delta = dist & 63; + dist &= -64; + if delta < 10 { + dist += delta; + } else if delta < 32 { + dist += 10; + } else if delta < 54 { + dist += 54; + } else { + dist += delta; + } + } else { + let mut new_base_delta = 0; + if (width > 0 && base_delta > 0) || (width < 0 && base_delta < 0) { + if scale.size < 10.0 { + new_base_delta = base_delta; + } else if scale.size < 30.0 { + new_base_delta = (base_delta * (30.0 - scale.size) as i32) / 20; + } + } + dist = (dist - new_base_delta.abs() + 32) & !63; + } + } + } + if group != ScriptGroup::Default { + // Divergent CJK behavior + // See + if dist < 54 { + dist += (54 - dist) / 2; + } else if dist < 3 * 64 { + let delta = dist & 63; + dist &= -64; + if delta < 10 { + dist += delta; + } else if delta < 22 { + dist += 10; + } else if delta < 42 { + dist += delta; + } else if delta < 54 { + dist += 54; + } else { + dist += delta; + } + } + } + } else { + // Do strong hinting: snap to integer pixels + let original_dist = dist; + dist = snap_width(&metrics.widths, dist); + if is_vertical { + // Always round to integers in the vertical case + if dist >= 64 { + dist = (dist + 16) & !63; + } else { + dist = 64; + } + } else if scale.flags & Scale::MONO != 0 { + // Mono horizontal hinting: snap to integer with different + // threshold + if dist < 64 { + dist = 64; + } else { + dist = (dist + 32) & !63; + } + } else { + // Smooth horizontal hinting: strengthen small stems, round + // stems whose size is between 1 and 2 pixels + if dist < 48 { + dist = (dist + 64) >> 1; + } else if dist < 128 { + // Only round to integer if distortion is less than + // 1/4 pixel + dist = (dist + 22) & !63; + if group == ScriptGroup::Default { + // See + let delta = (dist - original_dist).abs(); + if delta >= 16 { + dist = original_dist; + if dist < 48 { + dist = (dist + 64) >> 1; + } + } + } + } else { + // Round otherwise to prevent color fringes in LCD mode + dist = (dist + 32) & !63; + } + } + } + dist * sign +} + +/// Align one stem edge relative to previous stem edge. +/// +/// See +fn align_linked_edge( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, + base_edge_ix: usize, + stem_edge_ix: usize, +) { + let edges = axis.edges.as_mut_slice(); + let base_edge = &edges[base_edge_ix]; + let stem_edge = &edges[stem_edge_ix]; + let width = stem_edge.opos - base_edge.opos; + let base_delta = base_edge.pos - base_edge.opos; + let fitted_width = stem_width( + metrics, + group, + scale, + width, + base_delta, + base_edge.flags, + stem_edge.flags, + ); + edges[stem_edge_ix].pos = base_edge.pos + fitted_width; +} + +/// Shift the serif edge by the adjustment made to base edge. +/// +/// See +fn align_serif_edge(axis: &mut Axis, base_edge_ix: usize, serif_edge_ix: usize) { + let edges = axis.edges.as_mut_slice(); + let base_edge = &edges[base_edge_ix]; + let serif_edge = &edges[serif_edge_ix]; + edges[serif_edge_ix].pos = base_edge.pos + (serif_edge.opos - base_edge.opos); +} + +/// Adjusts both edges of a stem and returns the delta. +/// +/// See +fn hint_normal_stem_cjk( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + group: ScriptGroup, + scale: &Scale, + edge_ix: usize, + edge2_ix: usize, + anchor: i32, +) -> i32 { + const MAX_HORIZONTAL_GAP: i32 = 9; + const MAX_VERTICAL_GAP: i32 = 15; + const MAX_DELTA_ABS: i32 = 14; + let edge = axis.edges[edge_ix]; + let edge2 = axis.edges[edge2_ix]; + let do_stem_adjust = scale.flags & Scale::STEM_ADJUST != 0; + let threshold_delta = if do_stem_adjust { + 0 + } else { + let delta = if axis.dim == Axis::VERTICAL { + MAX_HORIZONTAL_GAP + } else { + MAX_VERTICAL_GAP + }; + if edge.flags & Edge::ROUND != 0 && edge2.flags & Edge::ROUND != 0 { + delta + } else { + delta / 3 + } + }; + let threshold = 64 - threshold_delta; + let original_len = edge2.opos - edge.opos; + let cur_len = stem_width( + metrics, + group, + scale, + original_len, + 0, + edge.flags, + edge2.flags, + ); + let original_center = (edge.opos + edge2.opos) / 2 + anchor; + let cur_pos1 = original_center - cur_len / 2; + let cur_pos2 = cur_pos1 + cur_len; + let mut finish = |mut delta: i32| { + if !do_stem_adjust { + delta = delta.clamp(-MAX_DELTA_ABS, MAX_DELTA_ABS); + } + let adjustment = cur_pos1 + delta; + if edge.opos < edge2.opos { + axis.edges[edge_ix].pos = adjustment; + axis.edges[edge2_ix].pos = adjustment + cur_len; + } else { + axis.edges[edge2_ix].pos = adjustment; + axis.edges[edge_ix].pos = adjustment + cur_len; + } + delta + }; + let mut d_off1 = cur_pos1 - pix_floor(cur_pos1); + let mut d_off2 = cur_pos2 - pix_floor(cur_pos2); + let mut delta = 0; + if d_off1 == 0 || d_off2 == 0 { + return finish(delta); + } + let mut u_off1 = 64 - d_off1; + let mut u_off2 = 64 - d_off2; + if cur_len <= threshold { + if d_off2 < cur_len { + delta = if u_off1 <= d_off2 { u_off1 } else { -d_off2 }; + } + return finish(delta); + } + if threshold < 64 + && (d_off1 >= threshold + || u_off1 >= threshold + || d_off2 >= threshold + || u_off2 >= threshold) + { + return finish(delta); + } + let mut offset = cur_len & 63; + if offset < 32 { + if u_off1 <= offset || d_off2 <= offset { + return finish(delta); + } + } else { + offset = 64 - threshold; + } + d_off1 = threshold - u_off1; + u_off1 -= offset; + u_off2 = threshold - d_off2; + d_off2 -= offset; + if d_off1 <= u_off1 { + u_off1 = -d_off1; + } + if d_off2 <= u_off2 { + u_off2 = -d_off2; + } + if u_off1.abs() <= u_off2.abs() { + delta = u_off1; + } else { + delta = u_off2; + } + finish(delta) +} + +#[cfg(test)] +mod tests { + use super::{ + super::super::{ + metrics, + outline::Outline, + shape::{Shaper, ShaperMode}, + style, topo, + }, + *, + }; + use crate::{attribute::Style, MetadataProvider}; + use raw::{types::GlyphId, FontRef, TableProvider}; + + #[test] + fn edge_hinting_default() { + let expected_h_edges = [ + (0, Edge::DONE | Edge::ROUND), + (133, Edge::DONE), + (187, Edge::DONE), + (192, Edge::DONE | Edge::ROUND), + ]; + let expected_v_edges = [ + (-256, Edge::DONE), + (463, Edge::DONE), + (576, Edge::DONE | Edge::ROUND | Edge::SERIF), + (633, Edge::DONE), + ]; + check_edges( + font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, + GlyphId::new(9), + style::StyleClass::HEBR, + &expected_h_edges, + &expected_v_edges, + ); + } + + #[test] + fn edge_hinting_cjk() { + let expected_h_edges = [ + (128, Edge::DONE), + (193, Edge::DONE), + (473, 0), + (594, 0), + (704, Edge::DONE), + (673, Edge::DONE), + (767, Edge::DONE), + (832, Edge::DONE), + (896, Edge::DONE), + ]; + let expected_v_edges = [ + (-64, Edge::DONE | Edge::ROUND), + (15, Edge::ROUND), + (142, Edge::ROUND), + (546, Edge::DONE), + (624, Edge::DONE), + (576, Edge::DONE), + (720, Edge::DONE), + (768, Edge::DONE), + (799, Edge::ROUND), + ]; + check_edges( + font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, + GlyphId::new(9), + style::StyleClass::HANI, + &expected_h_edges, + &expected_v_edges, + ); + } + + fn check_edges( + font_data: &[u8], + glyph_id: GlyphId, + class: usize, + expected_h_edges: &[(i32, u8)], + expected_v_edges: &[(i32, u8)], + ) { + let font = FontRef::new(font_data).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let class = &style::STYLE_CLASSES[class]; + let unscaled_metrics = + metrics::compute_unscaled_style_metrics(&shaper, Default::default(), class); + let scale = metrics::Scale::new( + 16.0, + font.head().unwrap().units_per_em() as i32, + Style::Normal, + Default::default(), + class.script.group, + ); + let scaled_metrics = metrics::scale_style_metrics(&unscaled_metrics, scale); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(glyph_id).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axes = [ + Axis::new(Axis::HORIZONTAL, outline.orientation), + Axis::new(Axis::VERTICAL, outline.orientation), + ]; + for (dim, axis) in axes.iter_mut().enumerate() { + topo::compute_segments(&mut outline, axis, class.script.group); + topo::link_segments( + &outline, + axis, + scaled_metrics.axes[dim].scale, + class.script.group, + unscaled_metrics.axes[dim].max_width(), + ); + topo::compute_edges( + axis, + &scaled_metrics.axes[0], + class.script.hint_top_to_bottom, + scaled_metrics.axes[1].scale, + class.script.group, + ); + if dim == Axis::VERTICAL { + topo::compute_blue_edges( + axis, + &scale, + &unscaled_metrics.axes[dim].blues, + &scaled_metrics.axes[dim].blues, + class.script.group, + ); + } + hint_edges( + axis, + &scaled_metrics.axes[dim], + class.script.group, + &scale, + class.script.hint_top_to_bottom, + ); + } + // Only pos and flags fields are modified by edge hinting + let h_edges = axes[Axis::HORIZONTAL] + .edges + .iter() + .map(|edge| (edge.pos, edge.flags)) + .collect::>(); + let v_edges = axes[Axis::VERTICAL] + .edges + .iter() + .map(|edge| (edge.pos, edge.flags)) + .collect::>(); + assert_eq!(h_edges, expected_h_edges); + assert_eq!(v_edges, expected_v_edges); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,119 @@ +//! Entry point to hinting algorithm. + +mod edges; +mod outline; + +use super::{ + metrics::{scale_style_metrics, Scale, UnscaledStyleMetrics}, + outline::Outline, + style::{GlyphStyle, ScriptGroup}, + topo::{self, Axis}, +}; + +/// Captures adjusted horizontal scale and outer edge positions to be used +/// for horizontal metrics adjustments. +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub(crate) struct EdgeMetrics { + pub left_opos: i32, + pub left_pos: i32, + pub right_opos: i32, + pub right_pos: i32, +} + +#[derive(Copy, Clone, PartialEq, Default, Debug)] +pub(crate) struct HintedMetrics { + pub x_scale: i32, + /// This will be `None` when we've identified fewer than two horizontal + /// edges in the outline. This will occur for empty outlines and outlines + /// that are degenerate (all x coordinates have the same value, within + /// a threshold). In these cases, horizontal metrics will not be adjusted. + pub edge_metrics: Option, +} + +/// Applies the complete hinting process to a latin outline. +/// +/// See +pub(crate) fn hint_outline( + outline: &mut Outline, + metrics: &UnscaledStyleMetrics, + scale: &Scale, + glyph_style: Option, +) -> HintedMetrics { + let scaled_metrics = scale_style_metrics(metrics, *scale); + let scale = &scaled_metrics.scale; + let mut axis = Axis::default(); + let hint_top_to_bottom = metrics.style_class().script.hint_top_to_bottom; + outline.scale(&scaled_metrics.scale); + let mut hinted_metrics = HintedMetrics { + x_scale: scale.x_scale, + ..Default::default() + }; + let group = metrics.style_class().script.group; + // For default script group, we don't proceed with hinting if we're + // missing alignment zones. FreeType swaps in a "dummy" hinter here + // See + if group == ScriptGroup::Default && scaled_metrics.axes[1].blues.is_empty() { + return hinted_metrics; + } + for dim in 0..2 { + if (dim == Axis::HORIZONTAL && scale.flags & Scale::NO_HORIZONTAL != 0) + || (dim == Axis::VERTICAL && scale.flags & Scale::NO_VERTICAL != 0) + { + continue; + } + axis.reset(dim, outline.orientation); + topo::compute_segments(outline, &mut axis, group); + topo::link_segments( + outline, + &mut axis, + scaled_metrics.axes[dim].scale, + group, + metrics.axes[dim].max_width(), + ); + topo::compute_edges( + &mut axis, + &scaled_metrics.axes[dim], + hint_top_to_bottom, + scaled_metrics.scale.y_scale, + group, + ); + if dim == Axis::VERTICAL { + if group != ScriptGroup::Default + || glyph_style + .map(|style| !style.is_non_base()) + .unwrap_or(true) + { + topo::compute_blue_edges( + &mut axis, + scale, + &metrics.axes[dim].blues, + &scaled_metrics.axes[dim].blues, + group, + ); + } + } else { + hinted_metrics.x_scale = scaled_metrics.axes[0].scale; + } + edges::hint_edges( + &mut axis, + &scaled_metrics.axes[dim], + group, + scale, + hint_top_to_bottom, + ); + outline::align_edge_points(outline, &axis, group, scale); + outline::align_strong_points(outline, &mut axis); + outline::align_weak_points(outline, dim); + if dim == 0 && axis.edges.len() > 1 { + let left = axis.edges.first().unwrap(); + let right = axis.edges.last().unwrap(); + hinted_metrics.edge_metrics = Some(EdgeMetrics { + left_pos: left.pos, + left_opos: left.opos, + right_pos: right.pos, + right_opos: right.opos, + }); + } + } + hinted_metrics +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,661 @@ +//! Apply edge hints to an outline. +//! +//! This happens in three passes: +//! 1. Align points that are directly attached to edges. These are the points +//! which originally generated the edge and are coincident with the edge +//! coordinate (within a threshold) for a given axis. This may include +//! points that were originally classified as weak. +//! 2. Interpolate non-weak points that were not touched by the previous pass. +//! This searches for the edges that enclose the point and interpolates the +//! coordinate based on the adjustment applied to those edges. +//! 3. Interpolate remaining untouched points. These are generally the weak +//! points: those that are very near other points or lacking a dominant +//! inward or outward direction. +//! +//! The final result is a fully hinted outline. + +use super::super::{ + metrics::{fixed_div, fixed_mul, Scale}, + outline::{Outline, Point}, + style::ScriptGroup, + topo::{Axis, Dimension}, +}; +use core::cmp::Ordering; +use raw::tables::glyf::PointMarker; + +/// Align all points of an edge to the same coordinate value. +/// +/// See +pub(crate) fn align_edge_points( + outline: &mut Outline, + axis: &Axis, + group: ScriptGroup, + scale: &Scale, +) -> Option<()> { + let edges = axis.edges.as_slice(); + let segments = axis.segments.as_slice(); + let points = outline.points.as_mut_slice(); + // Snapping is configurable for CJK + // See + let snap = group == ScriptGroup::Default + || ((axis.dim == Axis::HORIZONTAL && scale.flags & Scale::HORIZONTAL_SNAP != 0) + || (axis.dim == Axis::VERTICAL && scale.flags & Scale::VERTICAL_SNAP != 0)); + for segment in segments { + let Some(edge) = segment.edge(edges) else { + continue; + }; + let delta = edge.pos - edge.opos; + let mut point_ix = segment.first(); + let last_ix = segment.last(); + loop { + let point = points.get_mut(point_ix)?; + if axis.dim == Axis::HORIZONTAL { + if snap { + point.x = edge.pos; + } else { + point.x += delta; + } + point.flags.set_marker(PointMarker::TOUCHED_X); + } else { + if snap { + point.y = edge.pos; + } else { + point.y += delta; + } + point.flags.set_marker(PointMarker::TOUCHED_Y); + } + if point_ix == last_ix { + break; + } + point_ix = point.next(); + } + } + Some(()) +} + +/// Align the strong points; equivalent to the TrueType `IP` instruction. +/// +/// See +pub(crate) fn align_strong_points(outline: &mut Outline, axis: &mut Axis) -> Option<()> { + if axis.edges.is_empty() { + return Some(()); + } + let dim = axis.dim; + let touch_flag = if dim == Axis::HORIZONTAL { + PointMarker::TOUCHED_X + } else { + PointMarker::TOUCHED_Y + }; + let points = outline.points.as_mut_slice(); + 'points: for point in points { + // Skip points that are already touched; do weak interpolation in the + // next pass + if point + .flags + .has_marker(touch_flag | PointMarker::WEAK_INTERPOLATION) + { + continue; + } + let (u, ou) = if dim == Axis::VERTICAL { + (point.fy, point.oy) + } else { + (point.fx, point.ox) + }; + let edges = axis.edges.as_mut_slice(); + // Is the point before the first edge? + let edge = edges.first()?; + let delta = edge.fpos as i32 - u; + if delta >= 0 { + store_point(point, dim, edge.pos - (edge.opos - ou)); + continue; + } + // Is the point after the last edge? + let edge = edges.last()?; + let delta = u - edge.fpos as i32; + if delta >= 0 { + store_point(point, dim, edge.pos + (ou - edge.opos)); + continue; + } + // Find enclosing edges; for a small number of edges, use a linear + // search. + // Note: this is actually critical for matching FreeType in cases where + // we have more than one edge with the same fpos. When this happens, + // linear and binary searches can produce different results. + // See + let min_ix = if edges.len() <= 8 { + if let Some((min_ix, edge)) = edges + .iter() + .enumerate() + .find(|(_ix, edge)| edge.fpos as i32 >= u) + { + if edge.fpos as i32 == u { + store_point(point, dim, edge.pos); + continue 'points; + } + min_ix + } else { + 0 + } + } else { + let mut min_ix = 0; + let mut max_ix = edges.len(); + while min_ix < max_ix { + let mid_ix = (min_ix + max_ix) >> 1; + let edge = &edges[mid_ix]; + let fpos = edge.fpos as i32; + match u.cmp(&fpos) { + Ordering::Less => max_ix = mid_ix, + Ordering::Greater => min_ix = mid_ix + 1, + Ordering::Equal => { + // We are on an edge + store_point(point, dim, edge.pos); + continue 'points; + } + } + } + min_ix + }; + // Point is not on an edge + if let Some(before_ix) = min_ix.checked_sub(1) { + let edge_before = edges.get(before_ix)?; + let before_pos = edge_before.pos; + let before_fpos = edge_before.fpos as i32; + let scale = if edge_before.scale == 0 { + let edge_after = edges.get(min_ix)?; + let scale = fixed_div( + edge_after.pos - edge_before.pos, + edge_after.fpos as i32 - before_fpos, + ); + edges[before_ix].scale = scale; + scale + } else { + edge_before.scale + }; + store_point(point, dim, before_pos + fixed_mul(u - before_fpos, scale)); + } + } + Some(()) +} + +/// Align the weak points; equivalent to the TrueType `IUP` instruction. +/// +/// See +pub(crate) fn align_weak_points(outline: &mut Outline, dim: Dimension) -> Option<()> { + let touch_marker = if dim == Axis::HORIZONTAL { + for point in &mut outline.points { + point.u = point.x; + point.v = point.ox; + } + PointMarker::TOUCHED_X + } else { + for point in &mut outline.points { + point.u = point.y; + point.v = point.oy; + } + PointMarker::TOUCHED_Y + }; + for contour in &outline.contours { + let points = outline.points.get_mut(contour.range())?; + // Find first touched point + let Some(first_touched_ix) = points + .iter() + .position(|point| point.flags.has_marker(touch_marker)) + else { + continue; + }; + let last_ix = points.len() - 1; + let mut point_ix = first_touched_ix; + let mut last_touched_ix; + 'outer: loop { + // Skip any touched neighbors + while point_ix < last_ix && points.get(point_ix + 1)?.flags.has_marker(touch_marker) { + point_ix += 1; + } + last_touched_ix = point_ix; + // Find the next touched point + point_ix += 1; + loop { + if point_ix > last_ix { + break 'outer; + } + if points[point_ix].flags.has_marker(touch_marker) { + break; + } + point_ix += 1; + } + iup_interpolate( + points, + last_touched_ix + 1, + point_ix - 1, + last_touched_ix, + point_ix, + ); + } + if last_touched_ix == first_touched_ix { + // Special case: only one point was touched + iup_shift(points, 0, last_ix, first_touched_ix); + } else { + // Interpolate the remainder + if last_touched_ix < last_ix { + iup_interpolate( + points, + last_touched_ix + 1, + last_ix, + last_touched_ix, + first_touched_ix, + ); + } + if first_touched_ix > 0 { + iup_interpolate( + points, + 0, + first_touched_ix - 1, + last_touched_ix, + first_touched_ix, + ); + } + } + } + // Save interpolated values + if dim == Axis::HORIZONTAL { + for point in &mut outline.points { + point.x = point.u; + } + } else { + for point in &mut outline.points { + point.y = point.u; + } + } + Some(()) +} + +#[inline(always)] +fn store_point(point: &mut Point, dim: Dimension, u: i32) { + if dim == Axis::HORIZONTAL { + point.x = u; + point.flags.set_marker(PointMarker::TOUCHED_X); + } else { + point.y = u; + point.flags.set_marker(PointMarker::TOUCHED_Y); + } +} + +/// Shift original coordinates of all points between `p1_ix` and `p2_ix` +/// (inclusive) to get hinted coordinates using the same difference as +/// given by the point at `ref_ix`. +/// +/// The `u` and `v` members are the current and original coordinate values, +/// respectively. +/// +/// See +fn iup_shift(points: &mut [Point], p1_ix: usize, p2_ix: usize, ref_ix: usize) -> Option<()> { + let ref_point = points.get(ref_ix)?; + let delta = ref_point.u - ref_point.v; + if delta == 0 { + return Some(()); + } + for point in points.get_mut(p1_ix..ref_ix)? { + point.u = point.v + delta; + } + for point in points.get_mut(ref_ix + 1..=p2_ix)? { + point.u = point.v + delta; + } + Some(()) +} + +/// Interpolate the original coordinates all of points between `p1_ix` and +/// `p2_ix` (inclusive) to get hinted coordinates, using the points at +/// `ref1_ix` and `ref2_ix` as the reference points. +/// +/// The `u` and `v` members are the current and original coordinate values, +/// respectively. +/// +/// See +fn iup_interpolate( + points: &mut [Point], + p1_ix: usize, + p2_ix: usize, + ref1_ix: usize, + ref2_ix: usize, +) -> Option<()> { + if p1_ix > p2_ix { + return Some(()); + } + let mut ref_point1 = points.get(ref1_ix)?; + let mut ref_point2 = points.get(ref2_ix)?; + if ref_point1.v > ref_point2.v { + core::mem::swap(&mut ref_point1, &mut ref_point2); + } + let (u1, v1) = (ref_point1.u, ref_point1.v); + let (u2, v2) = (ref_point2.u, ref_point2.v); + let d1 = u1 - v1; + let d2 = u2 - v2; + if u1 == u2 || v1 == v2 { + for point in points.get_mut(p1_ix..=p2_ix)? { + point.u = if point.v <= v1 { + point.v + d1 + } else if point.v >= v2 { + point.v + d2 + } else { + u1 + }; + } + } else { + let scale = fixed_div(u2 - u1, v2 - v1); + for point in points.get_mut(p1_ix..=p2_ix)? { + point.u = if point.v <= v1 { + point.v + d1 + } else if point.v >= v2 { + point.v + d2 + } else { + u1 + fixed_mul(point.v - v1, scale) + }; + } + } + Some(()) +} + +#[cfg(test)] +mod tests { + use super::{ + super::super::{ + metrics::{compute_unscaled_style_metrics, Scale}, + shape::{Shaper, ShaperMode}, + style, + }, + super::{EdgeMetrics, HintedMetrics}, + *, + }; + use crate::{attribute::Style, MetadataProvider}; + use raw::{ + types::{F2Dot14, GlyphId}, + FontRef, TableProvider, + }; + + #[test] + fn hinted_coords_and_metrics_default() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let (outline, metrics) = hint_outline( + &font, + 16.0, + Default::default(), + GlyphId::new(9), + &style::STYLE_CLASSES[style::StyleClass::HEBR], + ); + // Expected values were painfully extracted from FreeType with some + // printf debugging + #[rustfmt::skip] + let expected_coords = [ + (133, -256), + (133, 282), + (133, 343), + (146, 431), + (158, 463), + (158, 463), + (57, 463), + (30, 463), + (0, 495), + (0, 534), + (0, 548), + (2, 570), + (11, 604), + (17, 633), + (50, 633), + (50, 629), + (50, 604), + (77, 576), + (101, 576), + (163, 576), + (180, 576), + (192, 562), + (192, 542), + (192, 475), + (190, 457), + (187, 423), + (187, 366), + (187, 315), + (187, -220), + (178, -231), + (159, -248), + (146, -256), + ]; + let coords = outline + .points + .iter() + .map(|point| (point.x, point.y)) + .collect::>(); + assert_eq!(coords, expected_coords); + let expected_metrics = HintedMetrics { + x_scale: 67109, + edge_metrics: Some(EdgeMetrics { + left_opos: 15, + left_pos: 0, + right_opos: 210, + right_pos: 192, + }), + }; + assert_eq!(metrics, expected_metrics); + } + + #[test] + fn hinted_coords_and_metrics_cjk() { + let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); + let (outline, metrics) = hint_outline( + &font, + 16.0, + Default::default(), + GlyphId::new(9), + &style::STYLE_CLASSES[style::StyleClass::HANI], + ); + // Expected values were painfully extracted from FreeType with some + // printf debugging + let expected_coords = [ + (279, 768), + (568, 768), + (618, 829), + (618, 829), + (634, 812), + (657, 788), + (685, 758), + (695, 746), + (692, 720), + (667, 720), + (288, 720), + (704, 704), + (786, 694), + (785, 685), + (777, 672), + (767, 670), + (767, 163), + (767, 159), + (750, 148), + (728, 142), + (716, 142), + (704, 142), + (402, 767), + (473, 767), + (473, 740), + (450, 598), + (338, 357), + (236, 258), + (220, 270), + (274, 340), + (345, 499), + (390, 675), + (344, 440), + (398, 425), + (464, 384), + (496, 343), + (501, 307), + (486, 284), + (458, 281), + (441, 291), + (434, 314), + (398, 366), + (354, 416), + (334, 433), + (832, 841), + (934, 830), + (932, 819), + (914, 804), + (896, 802), + (896, 30), + (896, 5), + (885, -35), + (848, -60), + (809, -65), + (807, -51), + (794, -27), + (781, -19), + (767, -11), + (715, 0), + (673, 5), + (673, 21), + (673, 21), + (707, 18), + (756, 15), + (799, 13), + (807, 13), + (821, 13), + (832, 23), + (832, 35), + (407, 624), + (594, 624), + (594, 546), + (396, 546), + (569, 576), + (558, 576), + (599, 614), + (677, 559), + (671, 552), + (654, 547), + (636, 545), + (622, 458), + (572, 288), + (488, 130), + (357, -5), + (259, -60), + (246, -45), + (327, 9), + (440, 150), + (516, 311), + (558, 486), + (128, 542), + (158, 581), + (226, 576), + (223, 562), + (207, 543), + (193, 539), + (193, -44), + (193, -46), + (175, -56), + (152, -64), + (141, -64), + (128, -64), + (195, 850), + (300, 820), + (295, 799), + (259, 799), + (234, 712), + (163, 543), + (80, 395), + (33, 338), + (19, 347), + (54, 410), + (120, 575), + (176, 759), + ]; + let coords = outline + .points + .iter() + .map(|point| (point.x, point.y)) + .collect::>(); + assert_eq!(coords, expected_coords); + let expected_metrics = HintedMetrics { + x_scale: 67109, + edge_metrics: Some(EdgeMetrics { + left_opos: 141, + left_pos: 128, + right_opos: 933, + right_pos: 896, + }), + }; + assert_eq!(metrics, expected_metrics); + } + + /// Empty glyphs (like spaces) have no edges and therefore no edge + /// metrics + #[test] + fn missing_edge_metrics() { + let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); + let (_outline, metrics) = hint_outline( + &font, + 16.0, + Default::default(), + GlyphId::new(1), + &style::STYLE_CLASSES[style::StyleClass::LATN], + ); + let expected_metrics = HintedMetrics { + x_scale: 65536, + edge_metrics: None, + }; + assert_eq!(metrics, expected_metrics); + } + + // Specific test case for which + // uses the Ahem + // font + #[test] + fn skia_ahem_test_case() { + let font = FontRef::new(font_test_data::AHEM).unwrap(); + let outline = hint_outline( + &font, + 24.0, + Default::default(), + // This glyph is the typical Ahem block square; the link to the + // font description above more detail. + GlyphId::new(5), + &style::STYLE_CLASSES[style::StyleClass::LATN], + ) + .0; + let expected_coords = [(0, 1216), (1536, 1216), (1536, -320), (0, -320)]; + // See + // Note that Skia inverts y coords + let expected_float_coords = [(0.0, 19.0), (24.0, 19.0), (24.0, -5.0), (0.0, -5.0)]; + let coords = outline + .points + .iter() + .map(|point| (point.x, point.y)) + .collect::>(); + let float_coords = coords + .iter() + .map(|(x, y)| (*x as f32 / 64.0, *y as f32 / 64.0)) + .collect::>(); + assert_eq!(coords, expected_coords); + assert_eq!(float_coords, expected_float_coords); + } + + fn hint_outline( + font: &FontRef, + size: f32, + coords: &[F2Dot14], + gid: GlyphId, + style: &style::StyleClass, + ) -> (Outline, HintedMetrics) { + let shaper = Shaper::new(font, ShaperMode::Nominal); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(gid).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, coords).unwrap(); + let metrics = compute_unscaled_style_metrics(&shaper, coords, style); + let scale = Scale::new( + size, + font.head().unwrap().units_per_em() as i32, + Style::Normal, + Default::default(), + metrics.style_class().script.group, + ); + let hinted_metrics = super::super::hint_outline(&mut outline, &metrics, &scale, None); + (outline, hinted_metrics) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,181 @@ +//! Autohinting state for a font instance. + +use crate::{attribute::Style, prelude::Size, MetadataProvider}; + +use super::{ + super::{ + pen::PathStyle, AdjustedMetrics, DrawError, OutlineGlyph, OutlineGlyphCollection, + OutlinePen, Target, + }, + metrics::{fixed_mul, pix_round, Scale, UnscaledStyleMetricsSet}, + outline::Outline, + shape::{Shaper, ShaperMode}, + style::GlyphStyleMap, +}; +use alloc::sync::Arc; +use raw::{ + types::{F26Dot6, F2Dot14}, + FontRef, TableProvider, +}; + +/// We enable "best effort" mode by default but allow it to be disabled with +/// a feature for testing. +const SHAPER_MODE: ShaperMode = if cfg!(feature = "autohint_shaping") { + ShaperMode::BestEffort +} else { + ShaperMode::Nominal +}; + +/// Set of derived glyph styles that are used for automatic hinting. +/// +/// These are invariant per font so can be precomputed and reused for multiple +/// instances when requesting automatic hinting with [`Engine::Auto`](super::super::hint::Engine::Auto). +#[derive(Clone, Debug)] +pub struct GlyphStyles(Arc); + +impl GlyphStyles { + /// Precomputes the full set of glyph styles for the given outlines. + pub fn new(outlines: &OutlineGlyphCollection) -> Self { + if let Some(font) = outlines.font() { + let glyph_count = font + .maxp() + .map(|maxp| maxp.num_glyphs() as u32) + .unwrap_or_default(); + let shaper = Shaper::new(font, SHAPER_MODE); + Self(Arc::new(GlyphStyleMap::new(glyph_count, &shaper))) + } else { + Self(Default::default()) + } + } +} + +#[derive(Clone)] +pub(crate) struct Instance { + styles: GlyphStyles, + metrics: UnscaledStyleMetricsSet, + target: Target, + is_fixed_width: bool, + style: Style, +} + +impl Instance { + pub fn new( + font: &FontRef, + outlines: &OutlineGlyphCollection, + coords: &[F2Dot14], + target: Target, + styles: Option, + lazy_metrics: bool, + ) -> Self { + let styles = styles.unwrap_or_else(|| GlyphStyles::new(outlines)); + #[cfg(feature = "std")] + let metrics = if lazy_metrics { + UnscaledStyleMetricsSet::lazy(&styles.0) + } else { + UnscaledStyleMetricsSet::precomputed(font, coords, SHAPER_MODE, &styles.0) + }; + #[cfg(not(feature = "std"))] + let metrics = UnscaledStyleMetricsSet::precomputed(font, coords, SHAPER_MODE, &styles.0); + let is_fixed_width = font + .post() + .map(|post| post.is_fixed_pitch() != 0) + .unwrap_or_default(); + let style = font.attributes().style; + Self { + styles, + metrics, + target, + is_fixed_width, + style, + } + } + + pub fn draw( + &self, + size: Size, + coords: &[F2Dot14], + glyph: &OutlineGlyph, + path_style: PathStyle, + pen: &mut impl OutlinePen, + ) -> Result { + let font = glyph.font(); + let glyph_id = glyph.glyph_id(); + let style = self + .styles + .0 + .style(glyph_id) + .ok_or(DrawError::GlyphNotFound(glyph_id))?; + let metrics = self + .metrics + .get(font, coords, SHAPER_MODE, &self.styles.0, glyph_id) + .ok_or(DrawError::GlyphNotFound(glyph_id))?; + let units_per_em = glyph.units_per_em() as i32; + let scale = Scale::new( + size.ppem().unwrap_or(units_per_em as f32), + units_per_em, + self.style, + self.target, + metrics.style_class().script.group, + ); + let mut outline = Outline::default(); + outline.fill(glyph, coords)?; + let hinted_metrics = super::hint::hint_outline(&mut outline, &metrics, &scale, Some(style)); + let h_advance = outline.advance; + let mut pp1x = 0; + let mut pp2x = fixed_mul(h_advance, hinted_metrics.x_scale); + let is_light = self.target.is_light() || self.target.preserve_linear_metrics(); + // + if !is_light { + if let (true, Some(edge_metrics)) = ( + scale.flags & Scale::NO_ADVANCE == 0, + hinted_metrics.edge_metrics, + ) { + let old_rsb = pp2x - edge_metrics.right_opos; + let old_lsb = edge_metrics.left_opos; + let new_lsb = edge_metrics.left_pos; + let mut pp1x_uh = new_lsb - old_lsb; + let mut pp2x_uh = edge_metrics.right_pos + old_rsb; + if old_lsb < 24 { + pp1x_uh -= 8; + } + if old_rsb < 24 { + pp2x_uh += 8; + } + pp1x = pix_round(pp1x_uh); + pp2x = pix_round(pp2x_uh); + if pp1x >= new_lsb && old_lsb > 0 { + pp1x -= 64; + } + if pp2x <= edge_metrics.right_pos && old_rsb > 0 { + pp2x += 64; + } + } else { + pp1x = pix_round(pp1x); + pp2x = pix_round(pp2x); + } + } else { + pp1x = pix_round(pp1x); + pp2x = pix_round(pp2x); + } + if pp1x != 0 { + for point in &mut outline.points { + point.x -= pp1x; + } + } + let advance = if !is_light + && (self.is_fixed_width || (metrics.digits_have_same_width && style.is_digit())) + { + fixed_mul(h_advance, scale.x_scale) + } else if h_advance != 0 { + pp2x - pp1x + } else { + 0 + }; + outline.to_path(path_style, pen)?; + Ok(AdjustedMetrics { + has_overlaps: glyph.has_overlaps().unwrap_or_default(), + lsb: None, + advance_width: Some(F26Dot6::from_bits(pix_round(advance)).to_f32()), + }) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,952 @@ +//! Latin blue values. + +use super::{ + super::{ + super::{unscaled::UnscaledOutlineBuf, OutlineGlyphCollection}, + shape::{ShapedCluster, Shaper}, + style::{ScriptGroup, StyleClass}, + }, + ScaledWidth, +}; +use crate::{collections::SmallVec, FontRef, MetadataProvider}; +use raw::types::F2Dot14; +use raw::TableProvider; + +/// Maximum number of blue values. +/// +/// See +const MAX_BLUES: usize = 8; + +// Chosen to maximize opportunity to avoid heap allocation while keeping stack +// size < 2k. +const MAX_INLINE_POINTS: usize = 256; + +// +const BLUE_STRING_MAX_LEN: usize = 51; + +/// Defines the zone(s) that are associated with a blue value. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[repr(transparent)] +pub(crate) struct BlueZones(u16); + +impl BlueZones { + // These properties ostensibly come from + // + // but are modified to match those at + // + // so that when don't need to keep two sets and adjust during blue + // computation. + pub const NONE: Self = Self(0); + pub const TOP: Self = Self(1 << 1); + pub const SUB_TOP: Self = Self(1 << 2); + pub const NEUTRAL: Self = Self(1 << 3); + pub const ADJUSTMENT: Self = Self(1 << 4); + pub const X_HEIGHT: Self = Self(1 << 5); + pub const LONG: Self = Self(1 << 6); + pub const HORIZONTAL: Self = Self(1 << 2); + pub const RIGHT: Self = Self::TOP; + + pub const fn contains(self, other: Self) -> bool { + self.0 & other.0 == other.0 + } + + // Used for generated data structures because the bit-or operator + // cannot be const. + #[must_use] + pub const fn union(self, other: Self) -> Self { + Self(self.0 | other.0) + } + + pub fn is_top_like(self) -> bool { + self & (Self::TOP | Self::SUB_TOP) != Self::NONE + } + + pub fn is_top(self) -> bool { + self.contains(Self::TOP) + } + + pub fn is_sub_top(self) -> bool { + self.contains(Self::SUB_TOP) + } + + pub fn is_neutral(self) -> bool { + self.contains(Self::NEUTRAL) + } + + pub fn is_x_height(self) -> bool { + self.contains(Self::X_HEIGHT) + } + + pub fn is_long(self) -> bool { + self.contains(Self::LONG) + } + + pub fn is_horizontal(self) -> bool { + self.contains(Self::HORIZONTAL) + } + + pub fn is_right(self) -> bool { + self.contains(Self::RIGHT) + } + + #[must_use] + pub fn retain_top_like_or_neutral(self) -> Self { + self & (Self::TOP | Self::SUB_TOP | Self::NEUTRAL) + } +} + +impl core::ops::Not for BlueZones { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl core::ops::BitOr for BlueZones { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } +} + +impl core::ops::BitOrAssign for BlueZones { + fn bitor_assign(&mut self, rhs: Self) { + self.0 |= rhs.0; + } +} + +impl core::ops::BitAnd for BlueZones { + type Output = Self; + + fn bitand(self, rhs: Self) -> Self::Output { + Self(self.0 & rhs.0) + } +} + +impl core::ops::BitAndAssign for BlueZones { + fn bitand_assign(&mut self, rhs: Self) { + self.0 &= rhs.0; + } +} + +// FreeType keeps a single array of blue values per metrics set +// and mutates when the scale factor changes. We'll separate them so +// that we can reuse unscaled metrics as immutable state without +// recomputing them (which is the expensive part). +// +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(crate) struct UnscaledBlue { + pub position: i32, + pub overshoot: i32, + pub ascender: i32, + pub descender: i32, + pub zones: BlueZones, +} + +pub(crate) type UnscaledBlues = SmallVec; + +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(crate) struct ScaledBlue { + pub position: ScaledWidth, + pub overshoot: ScaledWidth, + pub zones: BlueZones, + pub is_active: bool, +} + +pub(crate) type ScaledBlues = SmallVec; + +/// Compute unscaled blues values for each axis. +pub(crate) fn compute_unscaled_blues( + shaper: &Shaper, + coords: &[F2Dot14], + style: &StyleClass, +) -> [UnscaledBlues; 2] { + match style.script.group { + ScriptGroup::Default => [ + // Default group doesn't have horizontal blues + Default::default(), + compute_default_blues(shaper, coords, style), + ], + ScriptGroup::Cjk => compute_cjk_blues(shaper, coords, style), + // Indic group doesn't use blue values (yet?) + ScriptGroup::Indic => Default::default(), + } +} + +/// Compute unscaled blue values for the default script set. +/// +/// See +fn compute_default_blues(shaper: &Shaper, coords: &[F2Dot14], style: &StyleClass) -> UnscaledBlues { + let mut blues = UnscaledBlues::new(); + let (mut outline_buf, mut flats, mut rounds) = buffers(); + let (glyphs, units_per_em) = things_all_blues_need(shaper.font()); + let flat_threshold = units_per_em / 14; + let mut cluster_shaper = shaper.cluster_shaper(style); + let mut shaped_cluster = ShapedCluster::default(); + // Walk over each of the blue character sets for our script. + for (blue_str, blue_zones) in style.script.blues { + let mut ascender = i32::MIN; + let mut descender = i32::MAX; + let mut n_flats = 0; + let mut n_rounds = 0; + for cluster in blue_str.split(' ') { + let mut best_y_extremum = if blue_zones.is_top() { + i32::MIN + } else { + i32::MAX + }; + let mut best_is_round = false; + cluster_shaper.shape(cluster, &mut shaped_cluster); + for (glyph, y_offset) in shaped_cluster + .iter() + .filter(|g| g.id.to_u32() != 0) + .filter_map(|g| Some((glyphs.get(g.id)?, g.y_offset))) + { + outline_buf.clear(); + if glyph.draw_unscaled(coords, None, &mut outline_buf).is_err() { + continue; + } + let outline = outline_buf.as_ref(); + // Reject glyphs that can't produce any rendering + if outline.points.len() <= 2 { + continue; + } + let mut best_y: Option = None; + // Find the extreme point depending on whether this is a top or + // bottom blue + let best_contour_and_point = if blue_zones.is_top_like() { + outline.find_last_contour(|point| { + if best_y.is_none() || Some(point.y) > best_y { + best_y = Some(point.y); + ascender = ascender.max(point.y as i32 + y_offset); + true + } else { + descender = descender.min(point.y as i32 + y_offset); + false + } + }) + } else { + outline.find_last_contour(|point| { + if best_y.is_none() || Some(point.y) < best_y { + best_y = Some(point.y); + descender = descender.min(point.y as i32 + y_offset); + true + } else { + ascender = ascender.max(point.y as i32 + y_offset); + false + } + }) + }; + let Some((best_contour_range, best_point_ix)) = best_contour_and_point else { + continue; + }; + let best_contour = &outline.points[best_contour_range]; + // If we have a contour and point then best_y is guaranteed to + // be Some + let mut best_y = best_y.unwrap() as i32; + let best_x = best_contour[best_point_ix].x as i32; + // Now determine whether the point belongs to a straight or + // round segment by examining the previous and next points. + let [mut on_point_first, mut on_point_last] = + if best_contour[best_point_ix].is_on_curve() { + [Some(best_point_ix); 2] + } else { + [None; 2] + }; + let mut segment_first = best_point_ix; + let mut segment_last = best_point_ix; + // Look for the previous and next points on the contour that + // are not on the same Y coordinate, then threshold the + // "closeness" + for (ix, prev) in cycle_backward(best_contour, best_point_ix) { + let dist = (prev.y as i32 - best_y).abs(); + // Allow a small distance or angle (20 == roughly 2.9 degrees) + if dist > 5 && ((prev.x as i32 - best_x).abs() <= (20 * dist)) { + break; + } + segment_first = ix; + if prev.is_on_curve() { + on_point_first = Some(ix); + if on_point_last.is_none() { + on_point_last = Some(ix); + } + } + } + let mut next_ix = 0; + for (ix, next) in cycle_forward(best_contour, best_point_ix) { + // Save next_ix which is used in "long" blue computation + // later + next_ix = ix; + let dist = (next.y as i32 - best_y).abs(); + // Allow a small distance or angle (20 == roughly 2.9 degrees) + if dist > 5 && ((next.x as i32 - best_x).abs() <= (20 * dist)) { + break; + } + segment_last = ix; + if next.is_on_curve() { + on_point_last = Some(ix); + if on_point_first.is_none() { + on_point_first = Some(ix); + } + } + } + if blue_zones.is_long() { + // Taken verbatim from FreeType: + // + // "If this flag is set, we have an additional constraint to + // get the blue zone distance: Find a segment of the topmost + // (or bottommost) contour that is longer than a heuristic + // threshold. This ensures that small bumps in the outline + // are ignored (for example, the `vertical serifs' found in + // many Hebrew glyph designs). + // + // If this segment is long enough, we are done. Otherwise, + // search the segment next to the extremum that is long + // enough, has the same direction, and a not too large + // vertical distance from the extremum. Note that the + // algorithm doesn't check whether the found segment is + // actually the one (vertically) nearest to the extremum."" + // + // See + // heuristic threshold value + let length_threshold = units_per_em / 25; + let dist = (best_contour[segment_last].x as i32 + - best_contour[segment_first].x as i32) + .abs(); + if dist < length_threshold + && satisfies_min_long_segment_len( + segment_first, + segment_last, + best_contour.len() - 1, + ) + { + // heuristic threshold value + let height_threshold = units_per_em / 4; + // find previous point with different x value + let mut prev_ix = best_point_ix; + for (ix, prev) in cycle_backward(best_contour, best_point_ix) { + if prev.x as i32 != best_x { + prev_ix = ix; + break; + } + } + // skip for degenerate case + if prev_ix == best_point_ix { + continue; + } + let is_ltr = (best_contour[prev_ix].x as i32) < best_x; + let mut first = segment_last; + let mut last = first; + let mut p_first = None; + let mut p_last = None; + let mut hit = false; + loop { + if !hit { + // no hit, adjust first point + first = last; + // also adjust first and last on curve point + if best_contour[first].is_on_curve() { + p_first = Some(first); + p_last = Some(first); + } else { + p_first = None; + p_last = None; + } + hit = true; + } + if last < best_contour.len() - 1 { + last += 1; + } else { + last = 0; + } + if (best_y - best_contour[first].y as i32).abs() > height_threshold { + // vertical distance too large + hit = false; + continue; + } + let dist = + (best_contour[last].y as i32 - best_contour[first].y as i32).abs(); + if dist > 5 + && (best_contour[last].x as i32 - best_contour[first].x as i32) + .abs() + <= 20 * dist + { + hit = false; + if last == segment_first { + break; + } + continue; + } + if best_contour[last].is_on_curve() { + p_last = Some(last); + if p_first.is_none() { + p_first = Some(last); + } + } + let first_x = best_contour[first].x as i32; + let last_x = best_contour[last].x as i32; + let is_cur_ltr = first_x < last_x; + let dx = (last_x - first_x).abs(); + if is_cur_ltr == is_ltr && dx >= length_threshold { + loop { + if last < best_contour.len() - 1 { + last += 1; + } else { + last = 0; + } + let dy = (best_contour[last].y as i32 + - best_contour[first].y as i32) + .abs(); + if dy > 5 + && (best_contour[next_ix].x as i32 + - best_contour[first].x as i32) + .abs() + <= 20 * dist + { + if last > 0 { + last -= 1; + } else { + last = best_contour.len() - 1; + } + break; + } + p_last = Some(last); + if best_contour[last].is_on_curve() { + p_last = Some(last); + if p_first.is_none() { + p_first = Some(last); + } + } + if last == segment_first { + break; + } + } + best_y = best_contour[first].y as i32; + segment_first = first; + segment_last = last; + on_point_first = p_first; + on_point_last = p_last; + break; + } + if last == segment_first { + break; + } + } + } + } + best_y += y_offset; + // Is the segment round? + // 1. horizontal distance between first and last oncurve point + // is larger than a heuristic flat threshold, then it's flat + // 2. either first or last point of segment is offcurve then + // it's round + let is_round = match (on_point_first, on_point_last) { + (Some(first), Some(last)) + if (best_contour[last].x as i32 - best_contour[first].x as i32).abs() + > flat_threshold => + { + false + } + _ => { + !best_contour[segment_first].is_on_curve() + || !best_contour[segment_last].is_on_curve() + } + }; + if is_round && blue_zones.is_neutral() { + // Ignore round segments for neutral zone + continue; + } + // This seems to ignore LATIN_SUB_TOP? + if blue_zones.is_top() { + if best_y > best_y_extremum { + best_y_extremum = best_y; + best_is_round = is_round; + } + } else if best_y < best_y_extremum { + best_y_extremum = best_y; + best_is_round = is_round; + } + } + if best_y_extremum != i32::MIN && best_y_extremum != i32::MAX { + if best_is_round { + rounds[n_rounds] = best_y_extremum; + n_rounds += 1; + } else { + flats[n_flats] = best_y_extremum; + n_flats += 1; + } + } + } + if n_flats == 0 && n_rounds == 0 { + continue; + } + rounds[..n_rounds].sort_unstable(); + flats[..n_flats].sort_unstable(); + let (mut blue_ref, mut blue_shoot) = if n_flats == 0 { + let val = rounds[n_rounds / 2]; + (val, val) + } else if n_rounds == 0 { + let val = flats[n_flats / 2]; + (val, val) + } else { + (flats[n_flats / 2], rounds[n_rounds / 2]) + }; + if blue_shoot != blue_ref { + let over_ref = blue_shoot > blue_ref; + if blue_zones.is_top_like() ^ over_ref { + let val = (blue_shoot + blue_ref) / 2; + blue_ref = val; + blue_shoot = val; + } + } + let mut blue = UnscaledBlue { + position: blue_ref, + overshoot: blue_shoot, + ascender, + descender, + zones: blue_zones.retain_top_like_or_neutral(), + }; + if blue_zones.is_x_height() { + blue.zones |= BlueZones::ADJUSTMENT; + } + blues.push(blue); + } + // sort bottoms + let mut sorted_indices: [usize; MAX_BLUES] = core::array::from_fn(|ix| ix); + let blue_values = blues.as_mut_slice(); + let len = blue_values.len(); + if len == 0 { + return blues; + } + // sort from bottom to top + for i in 1..len { + for j in (1..=i).rev() { + let first = &blue_values[sorted_indices[j - 1]]; + let second = &blue_values[sorted_indices[j]]; + let a = if first.zones.is_top_like() { + first.position + } else { + first.overshoot + }; + let b = if second.zones.is_top_like() { + second.position + } else { + second.overshoot + }; + if b >= a { + break; + } + sorted_indices.swap(j, j - 1); + } + } + // and adjust tops + for i in 0..len - 1 { + let index1 = sorted_indices[i]; + let index2 = sorted_indices[i + 1]; + let first = &blue_values[index1]; + let second = &blue_values[index2]; + let a = if first.zones.is_top_like() { + first.overshoot + } else { + first.position + }; + let b = if second.zones.is_top_like() { + second.overshoot + } else { + second.position + }; + if a > b { + if first.zones.is_top_like() { + blue_values[index1].overshoot = b; + } else { + blue_values[index1].position = b; + } + } + } + blues +} + +/// Given inclusive indices and a contour length, returns true if the segment +/// is of sufficient size to test for bumps when detecting "long" Hebrew +/// alignment zones. +fn satisfies_min_long_segment_len(first_ix: usize, last_ix: usize, contour_last: usize) -> bool { + let inclusive_diff = if first_ix <= last_ix { + last_ix - first_ix + } else { + // If first_ix > last_ix, then we want to capture the sum of the ranges + // [first_ix, contour_last] and [0, last_ix] + // We add 1 here to ensure the element that crosses the boundary is + // included. For example, if first_ix == contour_last and + // last_ix == 0, then we want the result to be 1 + contour_last - first_ix + 1 + last_ix + }; + // The +2 matches FreeType. The assumption is that this includes sufficient + // points to detect a bump and extend the segment? + // + inclusive_diff + 2 <= contour_last +} + +/// Compute unscaled blue values for the CJK script set. +/// +/// Note: unlike the default code above, this produces two sets of blues, +/// one for horizontal zones and one for vertical zones, respectively. The +/// horizontal set is currently not generated because this has been +/// disabled in FreeType but the code remains because we may want to revisit +/// in the future. +/// +/// See +fn compute_cjk_blues( + shaper: &Shaper, + coords: &[F2Dot14], + style: &StyleClass, +) -> [UnscaledBlues; 2] { + let mut blues = [UnscaledBlues::new(), UnscaledBlues::new()]; + let (mut outline_buf, mut flats, mut fills) = buffers(); + let (glyphs, _) = things_all_blues_need(shaper.font()); + let mut cluster_shaper = shaper.cluster_shaper(style); + let mut shaped_cluster = ShapedCluster::default(); + // Walk over each of the blue character sets for our script. + for (blue_str, blue_zones) in style.script.blues { + let is_horizontal = blue_zones.is_horizontal(); + // Note: horizontal blue zones are disabled by default and have been + // for many years in FreeType: + // See + // and + if is_horizontal { + continue; + } + let is_right = blue_zones.is_right(); + let is_top = blue_zones.is_top(); + let blues = &mut blues[!is_horizontal as usize]; + if blues.len() >= MAX_BLUES { + continue; + } + let mut n_flats = 0; + let mut n_fills = 0; + let mut is_fill = true; + for cluster in blue_str.split(' ') { + // The '|' character is used as a sentinel in the blue string that + // signifies a switch to characters that define "flat" values + // + if cluster == "|" { + is_fill = false; + continue; + } + cluster_shaper.shape(cluster, &mut shaped_cluster); + for glyph in shaped_cluster + .iter() + .filter(|g| g.id.to_u32() != 0) + .filter_map(|g| glyphs.get(g.id)) + { + outline_buf.clear(); + if glyph.draw_unscaled(coords, None, &mut outline_buf).is_err() { + continue; + } + let outline = outline_buf.as_ref(); + // Reject glyphs that can't produce any rendering + if outline.points.len() <= 2 { + continue; + } + // Step right up and find an extrema! + // Unwrap is safe because we know per ^ that we have at least 3 points + let best_pos = outline + .points + .iter() + .map(|p| if is_horizontal { p.x } else { p.y }) + .reduce( + if (is_horizontal && is_right) || (!is_horizontal && is_top) { + |a: i16, c: i16| a.max(c) + } else { + |a: i16, c: i16| a.min(c) + }, + ) + .unwrap(); + if is_fill { + fills[n_fills] = best_pos; + n_fills += 1; + } else { + flats[n_flats] = best_pos; + n_flats += 1; + } + } + } + if n_flats == 0 && n_fills == 0 { + continue; + } + // Now determine the reference and overshoot of the blue; simply + // take the median after a sort + fills[..n_fills].sort_unstable(); + flats[..n_flats].sort_unstable(); + let (mut blue_ref, mut blue_shoot) = if n_flats == 0 { + let value = fills[n_fills / 2] as i32; + (value, value) + } else if n_fills == 0 { + let value = flats[n_flats / 2] as i32; + (value, value) + } else { + (fills[n_fills / 2] as i32, flats[n_flats / 2] as i32) + }; + // Make sure blue_ref >= blue_shoot for top/right or vice versa for + // bottom left + if blue_shoot != blue_ref { + let under_ref = blue_shoot < blue_ref; + if blue_zones.is_top() ^ under_ref { + blue_ref = (blue_shoot + blue_ref) / 2; + blue_shoot = blue_ref; + } + } + blues.push(UnscaledBlue { + position: blue_ref, + overshoot: blue_shoot, + ascender: 0, + descender: 0, + zones: *blue_zones & BlueZones::TOP, + }); + } + blues +} + +#[inline(always)] +fn buffers() -> ( + UnscaledOutlineBuf, + [T; BLUE_STRING_MAX_LEN], + [T; BLUE_STRING_MAX_LEN], +) { + ( + UnscaledOutlineBuf::::new(), + [T::default(); BLUE_STRING_MAX_LEN], + [T::default(); BLUE_STRING_MAX_LEN], + ) +} + +/// A thneed is something everyone needs +#[inline(always)] +fn things_all_blues_need<'a>(font: &FontRef<'a>) -> (OutlineGlyphCollection<'a>, i32) { + ( + font.outline_glyphs(), + font.head() + .map(|head| head.units_per_em()) + .unwrap_or_default() as i32, + ) +} + +/// Iterator that begins at `start + 1` and cycles through all items +/// of the slice in forward order, ending with `start`. +pub(super) fn cycle_forward(items: &[T], start: usize) -> impl Iterator { + let len = items.len(); + let start = start + 1; + (0..len).map(move |ix| { + let real_ix = (ix + start) % len; + (real_ix, &items[real_ix]) + }) +} + +/// Iterator that begins at `start - 1` and cycles through all items +/// of the slice in reverse order, ending with `start`. +pub(super) fn cycle_backward(items: &[T], start: usize) -> impl Iterator { + let len = items.len(); + (0..len).rev().map(move |ix| { + let real_ix = (ix + start) % len; + (real_ix, &items[real_ix]) + }) +} + +#[cfg(test)] +mod tests { + use crate::outline::autohint::metrics::BlueZones; + + use super::{ + super::super::{ + shape::{Shaper, ShaperMode}, + style, + }, + satisfies_min_long_segment_len, UnscaledBlue, + }; + use raw::FontRef; + + #[test] + fn latin_blues() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let style = &style::STYLE_CLASSES[super::StyleClass::LATN]; + let blues = super::compute_default_blues(&shaper, &[], style); + let values = blues.as_slice(); + let expected = [ + UnscaledBlue { + position: 714, + overshoot: 725, + ascender: 725, + descender: -230, + zones: BlueZones::TOP, + }, + UnscaledBlue { + position: 0, + overshoot: -10, + ascender: 725, + descender: -10, + zones: BlueZones::default(), + }, + UnscaledBlue { + position: 760, + overshoot: 760, + ascender: 770, + descender: -240, + zones: BlueZones::TOP, + }, + UnscaledBlue { + position: 536, + overshoot: 546, + ascender: 546, + descender: -10, + zones: BlueZones::TOP | BlueZones::ADJUSTMENT, + }, + UnscaledBlue { + position: 0, + overshoot: -10, + ascender: 546, + descender: -10, + zones: BlueZones::default(), + }, + UnscaledBlue { + position: -240, + overshoot: -240, + ascender: 760, + descender: -240, + zones: BlueZones::default(), + }, + ]; + assert_eq!(values, &expected); + } + + #[test] + fn hebrew_long_blues() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + // Hebrew triggers "long" blue code path + let style = &style::STYLE_CLASSES[super::StyleClass::HEBR]; + let blues = super::compute_default_blues(&shaper, &[], style); + let values = blues.as_slice(); + assert_eq!(values.len(), 3); + let expected = [ + UnscaledBlue { + position: 592, + overshoot: 592, + ascender: 647, + descender: -240, + zones: BlueZones::TOP, + }, + UnscaledBlue { + position: 0, + overshoot: -9, + ascender: 647, + descender: -9, + zones: BlueZones::default(), + }, + UnscaledBlue { + position: -240, + overshoot: -240, + ascender: 647, + descender: -240, + zones: BlueZones::default(), + }, + ]; + assert_eq!(values, &expected); + } + + #[test] + fn cjk_blues() { + let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let style = &style::STYLE_CLASSES[super::StyleClass::HANI]; + let blues = super::compute_cjk_blues(&shaper, &[], style); + let values = blues[1].as_slice(); + let expected = [ + UnscaledBlue { + position: 837, + overshoot: 824, + ascender: 0, + descender: 0, + zones: BlueZones::TOP, + }, + UnscaledBlue { + position: -78, + overshoot: -66, + ascender: 0, + descender: 0, + zones: BlueZones::default(), + }, + ]; + assert_eq!(values, &expected); + } + + #[test] + fn c2sc_shaped_blues() { + let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::BestEffort); + let style = &style::STYLE_CLASSES[super::StyleClass::LATN_C2SC]; + let blues = super::compute_default_blues(&shaper, &[], style); + let values = blues.as_slice(); + // Captured from FreeType with HarfBuzz enabled + let expected = [ + UnscaledBlue { + position: 571, + overshoot: 571, + ascender: 571, + descender: 0, + zones: BlueZones::TOP, + }, + UnscaledBlue { + position: 0, + overshoot: 0, + ascender: 571, + descender: 0, + zones: BlueZones::default(), + }, + ]; + assert_eq!(values, &expected); + } + + /// Avoid subtraction overflow raised in + /// + #[test] + fn long_segment_len_avoid_overflow() { + // Test font in issue above triggers overflow with + // first = 22, last = 0, contour_last = 22 (all inclusive). + // FreeType succeeds on this with suspicious signed + // arithmetic and we should too with our code that + // takes the boundary into account + assert!(satisfies_min_long_segment_len(22, 0, 22)); + } + + #[test] + fn cycle_iter_forward() { + let items = [0, 1, 2, 3, 4, 5, 6, 7]; + let from_5 = super::cycle_forward(&items, 5) + .map(|(_, val)| *val) + .collect::>(); + assert_eq!(from_5, &[6, 7, 0, 1, 2, 3, 4, 5]); + let from_last = super::cycle_forward(&items, 7) + .map(|(_, val)| *val) + .collect::>(); + assert_eq!(from_last, &items); + // Don't panic on empty slice + let _ = super::cycle_forward::(&[], 5).count(); + } + + #[test] + fn cycle_iter_backward() { + let items = [0, 1, 2, 3, 4, 5, 6, 7]; + let from_5 = super::cycle_backward(&items, 5) + .map(|(_, val)| *val) + .collect::>(); + assert_eq!(from_5, &[4, 3, 2, 1, 0, 7, 6, 5]); + let from_0 = super::cycle_backward(&items, 0) + .map(|(_, val)| *val) + .collect::>(); + assert_eq!(from_0, &[7, 6, 5, 4, 3, 2, 1, 0]); + // Don't panic on empty slice + let _ = super::cycle_backward::(&[], 5).count(); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,480 @@ +//! Autohinting specific metrics. + +mod blues; +mod scale; +mod widths; + +use super::{ + super::Target, + shape::{Shaper, ShaperMode}, + style::{GlyphStyleMap, ScriptGroup, StyleClass}, + topo::Dimension, +}; +use crate::{attribute::Style, collections::SmallVec, FontRef}; +use alloc::vec::Vec; +use raw::types::{F2Dot14, Fixed, GlyphId}; +#[cfg(feature = "std")] +use std::sync::{Arc, RwLock}; + +pub(crate) use blues::{BlueZones, ScaledBlue, ScaledBlues, UnscaledBlue, UnscaledBlues}; +pub(crate) use scale::{compute_unscaled_style_metrics, scale_style_metrics}; + +/// Maximum number of widths, same for Latin and CJK. +/// +/// See +/// and +pub(crate) const MAX_WIDTHS: usize = 16; + +/// Unscaled metrics for a single axis. +/// +/// This is the union of the Latin and CJK axis records. +/// +/// See +/// and +#[derive(Clone, Default, Debug)] +pub(crate) struct UnscaledAxisMetrics { + pub dim: Dimension, + pub widths: UnscaledWidths, + pub width_metrics: WidthMetrics, + pub blues: UnscaledBlues, +} + +impl UnscaledAxisMetrics { + pub fn max_width(&self) -> Option { + self.widths.last().copied() + } +} + +/// Scaled metrics for a single axis. +#[derive(Clone, Default, Debug)] +pub(crate) struct ScaledAxisMetrics { + pub dim: Dimension, + /// Font unit to 26.6 scale in the axis direction. + pub scale: i32, + /// 1/64 pixel delta in the axis direction. + pub delta: i32, + pub widths: ScaledWidths, + pub width_metrics: WidthMetrics, + pub blues: ScaledBlues, +} + +/// Unscaled metrics for a single style and script. +/// +/// This is the union of the root, Latin and CJK style metrics but +/// the latter two are actually identical. +/// +/// See +/// and +/// and +#[derive(Clone, Default, Debug)] +pub(crate) struct UnscaledStyleMetrics { + /// Index of style class. + pub class_ix: u16, + /// Monospaced digits? + pub digits_have_same_width: bool, + /// Per-dimension unscaled metrics. + pub axes: [UnscaledAxisMetrics; 2], +} + +impl UnscaledStyleMetrics { + pub fn style_class(&self) -> &'static StyleClass { + &super::style::STYLE_CLASSES[self.class_ix as usize] + } +} + +/// The set of unscaled style metrics for a single font. +/// +/// For a variable font, this is dependent on the location in variation space. +#[derive(Clone, Debug)] +pub(crate) enum UnscaledStyleMetricsSet { + Precomputed(Vec), + #[cfg(feature = "std")] + Lazy(Arc>>>), +} + +impl UnscaledStyleMetricsSet { + /// Creates a precomputed style metrics set containing all metrics + /// required by the glyph map. + pub fn precomputed( + font: &FontRef, + coords: &[F2Dot14], + shaper_mode: ShaperMode, + style_map: &GlyphStyleMap, + ) -> Self { + // The metrics_styles() iterator does not report exact size so we + // preallocate and extend here rather than collect to avoid + // over allocating memory. + let shaper = Shaper::new(font, shaper_mode); + let mut vec = Vec::with_capacity(style_map.metrics_count()); + vec.extend( + style_map + .metrics_styles() + .map(|style| compute_unscaled_style_metrics(&shaper, coords, style)), + ); + Self::Precomputed(vec) + } + + /// Creates an unscaled style metrics set where each entry will be + /// initialized as needed. + #[cfg(feature = "std")] + pub fn lazy(style_map: &GlyphStyleMap) -> Self { + let vec = vec![None; style_map.metrics_count()]; + Self::Lazy(Arc::new(RwLock::new(vec))) + } + + /// Returns the unscaled style metrics for the given style map and glyph + /// identifier. + pub fn get( + &self, + font: &FontRef, + coords: &[F2Dot14], + shaper_mode: ShaperMode, + style_map: &GlyphStyleMap, + glyph_id: GlyphId, + ) -> Option { + let style = style_map.style(glyph_id)?; + let index = style_map.metrics_index(style)?; + match self { + Self::Precomputed(metrics) => metrics.get(index).cloned(), + #[cfg(feature = "std")] + Self::Lazy(lazy) => { + let read = lazy.read().unwrap(); + let entry = read.get(index)?; + if let Some(metrics) = &entry { + return Some(metrics.clone()); + } + core::mem::drop(read); + // The std RwLock doesn't support upgrading and contention is + // expected to be low, so let's just race to compute the new + // metrics. + let shaper = Shaper::new(font, shaper_mode); + let style_class = style.style_class()?; + let metrics = compute_unscaled_style_metrics(&shaper, coords, style_class); + let mut entry = lazy.write().unwrap(); + *entry.get_mut(index)? = Some(metrics.clone()); + Some(metrics) + } + } + } +} + +/// Scaled metrics for a single style and script. +#[derive(Clone, Default, Debug)] +pub(crate) struct ScaledStyleMetrics { + /// Multidimensional scaling factors and deltas. + pub scale: Scale, + /// Per-dimension scaled metrics. + pub axes: [ScaledAxisMetrics; 2], +} + +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(crate) struct WidthMetrics { + /// Used for creating edges. + pub edge_distance_threshold: i32, + /// Default stem thickness. + pub standard_width: i32, + /// Is standard width very light? + pub is_extra_light: bool, +} + +pub(crate) type UnscaledWidths = SmallVec; + +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(crate) struct ScaledWidth { + /// Width after applying scale. + pub scaled: i32, + /// Grid-fitted width. + pub fitted: i32, +} + +pub(crate) type ScaledWidths = SmallVec; + +/// Captures scaling parameters which may be modified during metrics +/// computation. +#[derive(Copy, Clone, Default, Debug)] +pub(crate) struct Scale { + /// Font unit to 26.6 scale in the X direction. + pub x_scale: i32, + /// Font unit to 26.6 scale in the Y direction. + pub y_scale: i32, + /// In 1/64 device pixels. + pub x_delta: i32, + /// In 1/64 device pixels. + pub y_delta: i32, + /// Font size in pixels per em. + pub size: f32, + /// From the source font. + pub units_per_em: i32, + /// Flags that determine hinting functionality. + pub flags: u32, +} + +impl Scale { + /// Create initial scaling parameters from metrics and hinting target. + pub fn new( + size: f32, + units_per_em: i32, + font_style: Style, + target: Target, + group: ScriptGroup, + ) -> Self { + let scale = + (Fixed::from_bits((size * 64.0) as i32) / Fixed::from_bits(units_per_em)).to_bits(); + let mut flags = 0; + let is_italic = font_style != Style::Normal; + let is_mono = target == Target::Mono; + let is_light = target.is_light() || target.preserve_linear_metrics(); + // Snap vertical stems for monochrome and horizontal LCD rendering. + if is_mono || target.is_lcd() { + flags |= Self::HORIZONTAL_SNAP; + } + // Snap horizontal stems for monochrome and vertical LCD rendering. + if is_mono || target.is_vertical_lcd() { + flags |= Self::VERTICAL_SNAP; + } + // Adjust stems to full pixels unless in LCD or light modes. + if !(target.is_lcd() || is_light) { + flags |= Self::STEM_ADJUST; + } + if is_mono { + flags |= Self::MONO; + } + if group == ScriptGroup::Default { + // Disable horizontal hinting completely for LCD, light hinting + // and italic fonts + // See + if target.is_lcd() || is_light || is_italic { + flags |= Self::NO_HORIZONTAL; + } + } else { + // CJK doesn't hint advances + // See + flags |= Self::NO_ADVANCE; + } + // CJK doesn't hint advances + // See + if group != ScriptGroup::Default { + flags |= Self::NO_ADVANCE; + } + Self { + x_scale: scale, + y_scale: scale, + x_delta: 0, + y_delta: 0, + size, + units_per_em, + flags, + } + } +} + +/// Scaler flags that determine hinting settings. +/// +/// See +/// and +impl Scale { + /// Stem width snapping. + pub const HORIZONTAL_SNAP: u32 = 1 << 0; + /// Stem height snapping. + pub const VERTICAL_SNAP: u32 = 1 << 1; + /// Stem width/height adjustment. + pub const STEM_ADJUST: u32 = 1 << 2; + /// Monochrome rendering. + pub const MONO: u32 = 1 << 3; + /// Disable horizontal hinting. + pub const NO_HORIZONTAL: u32 = 1 << 4; + /// Disable vertical hinting. + pub const NO_VERTICAL: u32 = 1 << 5; + /// Disable advance hinting. + pub const NO_ADVANCE: u32 = 1 << 6; +} + +// +pub(crate) fn sort_and_quantize_widths(widths: &mut UnscaledWidths, threshold: i32) { + if widths.len() <= 1 { + return; + } + widths.sort_unstable(); + let table = widths.as_mut_slice(); + let mut cur_ix = 0; + let mut cur_val = table[cur_ix]; + let last_ix = table.len() - 1; + let mut ix = 1; + // Compute and use mean values for clusters not larger than + // `threshold`. + while ix < table.len() { + if (table[ix] - cur_val) > threshold || ix == last_ix { + let mut sum = 0; + // Fix loop for end of array? + if (table[ix] - cur_val <= threshold) && ix == last_ix { + ix += 1; + } + for val in &mut table[cur_ix..ix] { + sum += *val; + *val = 0; + } + table[cur_ix] = sum / ix as i32; + if ix < last_ix { + cur_ix = ix + 1; + cur_val = table[cur_ix]; + } + } + ix += 1; + } + cur_ix = 1; + // Compress array to remove zero values + for ix in 1..table.len() { + if table[ix] != 0 { + table[cur_ix] = table[ix]; + cur_ix += 1; + } + } + widths.truncate(cur_ix); +} + +// Fixed point helpers +// +// Note: lots of bit fiddling based fixed point math in the autohinter +// so we're opting out of using the strongly typed variants because they +// just add noise and reduce clarity. + +pub(crate) fn fixed_mul(a: i32, b: i32) -> i32 { + (Fixed::from_bits(a) * Fixed::from_bits(b)).to_bits() +} + +pub(crate) fn fixed_div(a: i32, b: i32) -> i32 { + (Fixed::from_bits(a) / Fixed::from_bits(b)).to_bits() +} + +pub(crate) fn fixed_mul_div(a: i32, b: i32, c: i32) -> i32 { + Fixed::from_bits(a) + .mul_div(Fixed::from_bits(b), Fixed::from_bits(c)) + .to_bits() +} + +pub(crate) fn pix_round(a: i32) -> i32 { + (a + 32) & !63 +} + +pub(crate) fn pix_floor(a: i32) -> i32 { + a & !63 +} + +#[cfg(test)] +mod tests { + use super::{ + super::{ + shape::{Shaper, ShaperMode}, + style::STYLE_CLASSES, + }, + *, + }; + use raw::TableProvider; + + #[test] + fn sort_widths() { + // We use 10 and 20 as thresholds because the computation used + // is units_per_em / 100 + assert_eq!(sort_widths_helper(&[1], 10), &[1]); + assert_eq!(sort_widths_helper(&[1], 20), &[1]); + assert_eq!(sort_widths_helper(&[60, 20, 40, 35], 10), &[20, 35, 13, 60]); + assert_eq!(sort_widths_helper(&[60, 20, 40, 35], 20), &[31, 60]); + } + + fn sort_widths_helper(widths: &[i32], threshold: i32) -> Vec { + let mut widths2 = UnscaledWidths::new(); + for width in widths { + widths2.push(*width); + } + sort_and_quantize_widths(&mut widths2, threshold); + widths2.into_iter().collect() + } + + #[test] + fn precomputed_style_set() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let coords = &[]; + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let glyph_count = font.maxp().unwrap().num_glyphs() as u32; + let style_map = GlyphStyleMap::new(glyph_count, &shaper); + let style_set = + UnscaledStyleMetricsSet::precomputed(&font, coords, ShaperMode::Nominal, &style_map); + let UnscaledStyleMetricsSet::Precomputed(set) = &style_set else { + panic!("we definitely made a precomputed style set"); + }; + // This font has Latin, Hebrew and CJK (for unassigned chars) styles + assert_eq!(STYLE_CLASSES[set[0].class_ix as usize].name, "Latin"); + assert_eq!(STYLE_CLASSES[set[1].class_ix as usize].name, "Hebrew"); + assert_eq!( + STYLE_CLASSES[set[2].class_ix as usize].name, + "CJKV ideographs" + ); + assert_eq!(set.len(), 3); + } + + #[test] + fn lazy_style_set() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let coords = &[]; + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let glyph_count = font.maxp().unwrap().num_glyphs() as u32; + let style_map = GlyphStyleMap::new(glyph_count, &shaper); + let style_set = UnscaledStyleMetricsSet::lazy(&style_map); + let all_empty = lazy_set_presence(&style_set); + // Set starts out all empty + assert_eq!(all_empty, [false; 3]); + // First load a CJK glyph + let metrics2 = style_set + .get( + &font, + coords, + ShaperMode::Nominal, + &style_map, + GlyphId::new(0), + ) + .unwrap(); + assert_eq!( + STYLE_CLASSES[metrics2.class_ix as usize].name, + "CJKV ideographs" + ); + let only_cjk = lazy_set_presence(&style_set); + assert_eq!(only_cjk, [false, false, true]); + // Then a Hebrew glyph + let metrics1 = style_set + .get( + &font, + coords, + ShaperMode::Nominal, + &style_map, + GlyphId::new(1), + ) + .unwrap(); + assert_eq!(STYLE_CLASSES[metrics1.class_ix as usize].name, "Hebrew"); + let hebrew_and_cjk = lazy_set_presence(&style_set); + assert_eq!(hebrew_and_cjk, [false, true, true]); + // And finally a Latin glyph + let metrics0 = style_set + .get( + &font, + coords, + ShaperMode::Nominal, + &style_map, + GlyphId::new(15), + ) + .unwrap(); + assert_eq!(STYLE_CLASSES[metrics0.class_ix as usize].name, "Latin"); + let all_present = lazy_set_presence(&style_set); + assert_eq!(all_present, [true; 3]); + } + + fn lazy_set_presence(style_set: &UnscaledStyleMetricsSet) -> Vec { + let UnscaledStyleMetricsSet::Lazy(set) = &style_set else { + panic!("we definitely made a lazy style set"); + }; + set.read() + .unwrap() + .iter() + .map(|opt| opt.is_some()) + .collect() + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,429 @@ +//! Metrics scaling. +//! +//! Uses the widths and blues computations to generate unscaled metrics for a +//! given style/script. +//! +//! Then applies a scaling factor to those metrics, computes a potentially +//! modified scale, and tags active blue zones. + +use super::super::{ + metrics::{ + fixed_div, fixed_mul, fixed_mul_div, pix_round, BlueZones, Scale, ScaledAxisMetrics, + ScaledBlue, ScaledStyleMetrics, ScaledWidth, UnscaledAxisMetrics, UnscaledBlue, + UnscaledStyleMetrics, WidthMetrics, + }, + shape::Shaper, + style::{ScriptGroup, StyleClass}, + topo::{Axis, Dimension}, +}; +use crate::{prelude::Size, MetadataProvider}; +use raw::types::F2Dot14; + +/// Computes unscaled metrics for the Latin writing system. +/// +/// See +pub(crate) fn compute_unscaled_style_metrics( + shaper: &Shaper, + coords: &[F2Dot14], + style: &StyleClass, +) -> UnscaledStyleMetrics { + let charmap = shaper.charmap(); + // We don't attempt to produce any metrics if we don't have a Unicode + // cmap + // See + if charmap.is_symbol() { + return UnscaledStyleMetrics { + class_ix: style.index as u16, + axes: [ + UnscaledAxisMetrics { + dim: Axis::HORIZONTAL, + ..Default::default() + }, + UnscaledAxisMetrics { + dim: Axis::VERTICAL, + ..Default::default() + }, + ], + ..Default::default() + }; + } + let [hwidths, vwidths] = super::widths::compute_widths(shaper, coords, style); + let [hblues, vblues] = super::blues::compute_unscaled_blues(shaper, coords, style); + let glyph_metrics = shaper.font().glyph_metrics(Size::unscaled(), coords); + let mut digit_advance = None; + let mut digits_have_same_width = true; + for ch in '0'..='9' { + if let Some(advance) = charmap + .map(ch) + .and_then(|gid| glyph_metrics.advance_width(gid)) + { + if digit_advance.is_some() && digit_advance != Some(advance) { + digits_have_same_width = false; + break; + } + digit_advance = Some(advance); + } + } + UnscaledStyleMetrics { + class_ix: style.index as u16, + digits_have_same_width, + axes: [ + UnscaledAxisMetrics { + dim: Axis::HORIZONTAL, + blues: hblues, + width_metrics: hwidths.0, + widths: hwidths.1, + }, + UnscaledAxisMetrics { + dim: Axis::VERTICAL, + blues: vblues, + width_metrics: vwidths.0, + widths: vwidths.1, + }, + ], + } +} + +/// Computes scaled metrics for the Latin writing system. +/// +/// See +pub(crate) fn scale_style_metrics( + unscaled_metrics: &UnscaledStyleMetrics, + mut scale: Scale, +) -> ScaledStyleMetrics { + let scale_axis_fn = if unscaled_metrics.style_class().script.group == ScriptGroup::Default { + scale_default_axis_metrics + } else { + scale_cjk_axis_metrics + }; + let mut scale_axis = |axis: &UnscaledAxisMetrics| { + scale_axis_fn( + axis.dim, + &axis.widths, + axis.width_metrics, + &axis.blues, + &mut scale, + ) + }; + let axes = [ + scale_axis(&unscaled_metrics.axes[0]), + scale_axis(&unscaled_metrics.axes[1]), + ]; + ScaledStyleMetrics { scale, axes } +} + +/// Computes scaled metrics for a single axis. +/// +/// See +fn scale_default_axis_metrics( + dim: Dimension, + widths: &[i32], + width_metrics: WidthMetrics, + blues: &[UnscaledBlue], + scale: &mut Scale, +) -> ScaledAxisMetrics { + let mut axis = ScaledAxisMetrics { + dim, + ..Default::default() + }; + if dim == Axis::HORIZONTAL { + axis.scale = scale.x_scale; + axis.delta = scale.x_delta; + } else { + axis.scale = scale.y_scale; + axis.delta = scale.y_delta; + }; + // Correct Y scale to optimize alignment + if let Some(blue_ix) = blues + .iter() + .position(|blue| blue.zones.contains(BlueZones::ADJUSTMENT)) + { + let unscaled_blue = &blues[blue_ix]; + let scaled = fixed_mul(axis.scale, unscaled_blue.overshoot); + let fitted = (scaled + 40) & !63; + if scaled != fitted && dim == Axis::VERTICAL { + let new_scale = fixed_mul_div(axis.scale, fitted, scaled); + // Scaling should not adjust by more than 2 pixels + let mut max_height = scale.units_per_em; + for blue in blues { + max_height = max_height.max(blue.ascender).max(-blue.descender); + } + let mut dist = fixed_mul(max_height, new_scale - axis.scale).abs(); + dist &= !127; + if dist == 0 { + axis.scale = new_scale; + scale.y_scale = new_scale; + } + } + } + // Now scale the widths + axis.width_metrics = width_metrics; + for unscaled_width in widths { + let scaled = fixed_mul(axis.scale, *unscaled_width); + axis.widths.push(ScaledWidth { + scaled, + fitted: scaled, + }); + } + // Compute extra light property: this is a standard width that is + // less than 5/8 pixels + axis.width_metrics.is_extra_light = + fixed_mul(axis.width_metrics.standard_width, axis.scale) < (32 + 8); + if dim == Axis::VERTICAL { + // And scale the blue zones + for unscaled_blue in blues { + let scaled_position = fixed_mul(axis.scale, unscaled_blue.position) + axis.delta; + let scaled_overshoot = fixed_mul(axis.scale, unscaled_blue.overshoot) + axis.delta; + let mut blue = ScaledBlue { + position: ScaledWidth { + scaled: scaled_position, + fitted: scaled_position, + }, + overshoot: ScaledWidth { + scaled: scaled_overshoot, + fitted: scaled_overshoot, + }, + zones: unscaled_blue.zones, + is_active: false, + }; + // Only activate blue zones less than 3/4 pixel tall + let dist = fixed_mul(unscaled_blue.position - unscaled_blue.overshoot, axis.scale); + if (-48..=48).contains(&dist) { + let mut delta = dist.abs(); + if delta < 32 { + delta = 0; + } else if delta < 48 { + delta = 32; + } else { + delta = 64; + } + if dist < 0 { + delta = -delta; + } + blue.position.fitted = pix_round(blue.position.scaled); + blue.overshoot.fitted = blue.position.fitted - delta; + blue.is_active = true; + } + axis.blues.push(blue); + } + // Use sub-top blue zone if it doesn't overlap with another + // non-sub-top blue zone + for blue_ix in 0..axis.blues.len() { + let blue = axis.blues[blue_ix]; + if !blue.zones.is_sub_top() || !blue.is_active { + continue; + } + for blue2 in &axis.blues { + if blue2.zones.is_sub_top() || !blue2.is_active { + continue; + } + if blue2.position.fitted <= blue.overshoot.fitted + && blue2.overshoot.fitted >= blue.position.fitted + { + axis.blues[blue_ix].is_active = false; + break; + } + } + } + } + axis +} + +/// Computes scaled metrics for a single axis for the CJK script group. +/// +/// See +fn scale_cjk_axis_metrics( + dim: Dimension, + widths: &[i32], + width_metrics: WidthMetrics, + blues: &[UnscaledBlue], + scale: &mut Scale, +) -> ScaledAxisMetrics { + let mut axis = ScaledAxisMetrics { + dim, + ..Default::default() + }; + axis.dim = dim; + if dim == Axis::HORIZONTAL { + axis.scale = scale.x_scale; + axis.delta = scale.x_delta; + } else { + axis.scale = scale.y_scale; + axis.delta = scale.y_delta; + }; + let scale = axis.scale; + // Scale the blue zones + for unscaled_blue in blues { + let position = fixed_mul(unscaled_blue.position, scale) + axis.delta; + let overshoot = fixed_mul(unscaled_blue.overshoot, scale) + axis.delta; + let mut blue = ScaledBlue { + position: ScaledWidth { + scaled: position, + fitted: position, + }, + overshoot: ScaledWidth { + scaled: overshoot, + fitted: overshoot, + }, + zones: unscaled_blue.zones, + is_active: false, + }; + // A blue zone is only active if it is less than 3/4 pixels tall + let dist = fixed_mul(unscaled_blue.position - unscaled_blue.overshoot, scale); + if (-48..=48).contains(&dist) { + blue.position.fitted = pix_round(blue.position.scaled); + // For CJK, "overshoot" is actually undershoot + let delta1 = fixed_div(blue.position.fitted, scale) - unscaled_blue.overshoot; + let mut delta2 = fixed_mul(delta1.abs(), scale); + if delta2 < 32 { + delta2 = 0; + } else { + delta2 = pix_round(delta2); + } + if delta1 < 0 { + delta2 = -delta2; + } + blue.overshoot.fitted = blue.position.fitted - delta2; + blue.is_active = true; + } + axis.blues.push(blue); + } + // FreeType never seems to compute scaled width values. We'll just + // match this behavior for now. + // + for _ in 0..widths.len() { + axis.widths.push(ScaledWidth::default()); + } + axis.width_metrics = width_metrics; + axis +} + +#[cfg(test)] +mod tests { + use super::{ + super::super::{shape::ShaperMode, style}, + *, + }; + use crate::attribute::Style; + use raw::{FontRef, TableProvider}; + + #[test] + fn scaled_metrics_default() { + // Note: expected values scraped from a FreeType debugging + // session + let scaled_metrics = make_scaled_metrics( + font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, + StyleClass::HEBR, + ); + // Check scale and deltas + assert_eq!(scaled_metrics.scale.x_scale, 67109); + assert_eq!(scaled_metrics.scale.y_scale, 67109); + assert_eq!(scaled_metrics.scale.x_delta, 0); + assert_eq!(scaled_metrics.scale.y_delta, 0); + // Horizontal widths + let h_axis = &scaled_metrics.axes[0]; + let expected_h_widths = [55]; + // No horizontal blues + check_axis(h_axis, &expected_h_widths, &[]); + // Not extra light + assert!(!h_axis.width_metrics.is_extra_light); + // Vertical widths + let v_axis = &scaled_metrics.axes[1]; + let expected_v_widths = [22, 112]; + // Vertical blues + #[rustfmt::skip] + let expected_v_blues = [ + // ((scaled_pos, fitted_pos), (scaled_shoot, fitted_shoot), flags, is_active) + ScaledBlue::from(((606, 576), (606, 576), BlueZones::TOP, true)), + ScaledBlue::from(((0, 0), (-9, 0), BlueZones::default(), true)), + ScaledBlue::from(((-246, -256), (-246, -256), BlueZones::default(), true)), + ]; + check_axis(v_axis, &expected_v_widths, &expected_v_blues); + // This one is extra light + assert!(v_axis.width_metrics.is_extra_light); + } + + #[test] + fn cjk_scaled_metrics() { + // Note: expected values scraped from a FreeType debugging + // session + let scaled_metrics = make_scaled_metrics( + font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, + StyleClass::HANI, + ); + // Check scale and deltas + assert_eq!(scaled_metrics.scale.x_scale, 67109); + assert_eq!(scaled_metrics.scale.y_scale, 67109); + assert_eq!(scaled_metrics.scale.x_delta, 0); + assert_eq!(scaled_metrics.scale.y_delta, 0); + // Horizontal widths + let h_axis = &scaled_metrics.axes[0]; + let expected_h_widths = [0]; + check_axis(h_axis, &expected_h_widths, &[]); + // Not extra light + assert!(!h_axis.width_metrics.is_extra_light); + // Vertical widths + let v_axis = &scaled_metrics.axes[1]; + let expected_v_widths = [0]; + // Vertical blues + #[rustfmt::skip] + let expected_v_blues = [ + // ((scaled_pos, fitted_pos), (scaled_shoot, fitted_shoot), flags, is_active) + ScaledBlue::from(((857, 832), (844, 832), BlueZones::TOP, true)), + ScaledBlue::from(((-80, -64), (-68, -64), BlueZones::default(), true)), + ]; + // No horizontal blues + check_axis(v_axis, &expected_v_widths, &expected_v_blues); + // Also not extra light + assert!(!v_axis.width_metrics.is_extra_light); + } + + fn make_scaled_metrics(font_data: &[u8], style_class: usize) -> ScaledStyleMetrics { + let font = FontRef::new(font_data).unwrap(); + let class = &style::STYLE_CLASSES[style_class]; + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let unscaled_metrics = compute_unscaled_style_metrics(&shaper, Default::default(), class); + let scale = Scale::new( + 16.0, + font.head().unwrap().units_per_em() as i32, + Style::Normal, + Default::default(), + class.script.group, + ); + scale_style_metrics(&unscaled_metrics, scale) + } + + fn check_axis( + axis: &ScaledAxisMetrics, + expected_widths: &[i32], + expected_blues: &[ScaledBlue], + ) { + let widths = axis + .widths + .iter() + .map(|width| width.scaled) + .collect::>(); + assert_eq!(widths, expected_widths); + assert_eq!(axis.blues.as_slice(), expected_blues); + } + + impl From<(i32, i32)> for ScaledWidth { + fn from(value: (i32, i32)) -> Self { + Self { + scaled: value.0, + fitted: value.1, + } + } + } + + impl From<((i32, i32), (i32, i32), BlueZones, bool)> for ScaledBlue { + fn from(value: ((i32, i32), (i32, i32), BlueZones, bool)) -> Self { + Self { + position: value.0.into(), + overshoot: value.1.into(), + zones: value.2, + is_active: value.3, + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,205 @@ +//! Latin standard stem width computation. + +use super::super::{ + derived_constant, + metrics::{self, UnscaledWidths, WidthMetrics, MAX_WIDTHS}, + outline::Outline, + shape::{ShapedCluster, Shaper}, + style::{ScriptGroup, StyleClass}, + topo::{compute_segments, link_segments, Axis}, +}; +use crate::MetadataProvider; +use raw::{types::F2Dot14, TableProvider}; + +/// Compute all stem widths and initialize standard width and height for the +/// given script. +/// +/// Returns width metrics and unscaled widths for each dimension. +/// +/// See +pub(super) fn compute_widths( + shaper: &Shaper, + coords: &[F2Dot14], + style: &StyleClass, +) -> [(WidthMetrics, UnscaledWidths); 2] { + let mut result: [(WidthMetrics, UnscaledWidths); 2] = Default::default(); + let font = shaper.font(); + let glyphs = font.outline_glyphs(); + let units_per_em = font + .head() + .map(|head| head.units_per_em() as i32) + .unwrap_or_default(); + let mut outline = Outline::default(); + let mut axis = Axis::default(); + let mut cluster_shaper = shaper.cluster_shaper(style); + let mut shaped_cluster = ShapedCluster::default(); + // We take the first available glyph from the standard character set. + let glyph = style + .script + .std_chars + .split(' ') + .filter_map(|cluster| { + cluster_shaper.shape(cluster, &mut shaped_cluster); + // Reject input that maps to more than a single glyph + // See + match shaped_cluster.as_slice() { + [glyph] if glyph.id.to_u32() != 0 => glyphs.get(glyph.id), + _ => None, + } + }) + .next(); + if let Some(glyph) = glyph { + if outline.fill(&glyph, coords).is_ok() && !outline.points.is_empty() { + // Now process each dimension + for (dim, (_metrics, widths)) in result.iter_mut().enumerate() { + axis.reset(dim, outline.orientation); + // Segment computation for widths always uses the default + // script group + compute_segments(&mut outline, &mut axis, ScriptGroup::Default); + link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); + let segments = axis.segments.as_slice(); + for (segment_ix, segment) in segments.iter().enumerate() { + let segment_ix = segment_ix as u16; + let Some(link_ix) = segment.link_ix else { + continue; + }; + let link = &segments[link_ix as usize]; + if link_ix > segment_ix && link.link_ix == Some(segment_ix) { + let dist = (segment.pos as i32 - link.pos as i32).abs(); + if widths.len() < MAX_WIDTHS { + widths.push(dist); + } else { + break; + } + } + } + // FreeTypes `af_sort_and_quantize_widths()` has the side effect + // of always updating the width count to 1 when we don't find + // any... + // See + if widths.is_empty() { + widths.push(0); + } + // The value 100 is heuristic + metrics::sort_and_quantize_widths(widths, units_per_em / 100); + } + } + } + for (metrics, widths) in result.iter_mut() { + // Now set derived values + let stdw = widths + .first() + .copied() + .unwrap_or_else(|| derived_constant(units_per_em, 50)); + // Heuristic value of 20% of the smallest width + metrics.edge_distance_threshold = stdw / 5; + metrics.standard_width = stdw; + metrics.is_extra_light = false; + } + result +} + +#[cfg(test)] +mod tests { + use super::{ + super::super::{shape::ShaperMode, style}, + *, + }; + use raw::FontRef; + + #[test] + fn computed_widths() { + // Expected data produced by internal routines in FreeType. Scraped + // from a debugger + check_widths( + font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, + super::StyleClass::HEBR, + [ + ( + WidthMetrics { + edge_distance_threshold: 10, + standard_width: 54, + is_extra_light: false, + }, + &[54], + ), + ( + WidthMetrics { + edge_distance_threshold: 4, + standard_width: 21, + is_extra_light: false, + }, + &[21, 109], + ), + ], + ); + } + + #[test] + fn fallback_widths() { + // Expected data produced by internal routines in FreeType. Scraped + // from a debugger + check_widths( + font_test_data::CANTARELL_VF_TRIMMED, + super::StyleClass::LATN, + [ + ( + WidthMetrics { + edge_distance_threshold: 4, + standard_width: 24, + is_extra_light: false, + }, + &[], + ), + ( + WidthMetrics { + edge_distance_threshold: 4, + standard_width: 24, + is_extra_light: false, + }, + &[], + ), + ], + ); + } + + #[test] + fn cjk_computed_widths() { + // Expected data produced by internal routines in FreeType. Scraped + // from a debugger + check_widths( + font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, + super::StyleClass::HANI, + [ + ( + WidthMetrics { + edge_distance_threshold: 13, + standard_width: 65, + is_extra_light: false, + }, + &[65], + ), + ( + WidthMetrics { + edge_distance_threshold: 5, + standard_width: 29, + is_extra_light: false, + }, + &[29], + ), + ], + ); + } + + fn check_widths(font_data: &[u8], style_class: usize, expected: [(WidthMetrics, &[i32]); 2]) { + let font = FontRef::new(font_data).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let script = &style::STYLE_CLASSES[style_class]; + let [(hori_metrics, hori_widths), (vert_metrics, vert_widths)] = + compute_widths(&shaper, Default::default(), script); + assert_eq!(hori_metrics, expected[0].0); + assert_eq!(hori_widths.as_slice(), expected[0].1); + assert_eq!(vert_metrics, expected[1].0); + assert_eq!(vert_widths.as_slice(), expected[1].1); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,19 @@ +//! Runtime autohinting support. + +mod hint; +mod instance; +mod metrics; +mod outline; +mod shape; +mod style; +mod topo; + +pub use instance::GlyphStyles; +pub(crate) use instance::Instance; + +/// All constants are defined based on a UPEM of 2048. +/// +/// See +fn derived_constant(units_per_em: i32, value: i32) -> i32 { + value * units_per_em / 2048 +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,768 @@ +//! Outline representation and helpers for autohinting. + +use super::{ + super::{ + path, + pen::PathStyle, + unscaled::{UnscaledOutlineSink, UnscaledPoint}, + DrawError, LocationRef, OutlineGlyph, OutlinePen, + }, + metrics::Scale, +}; +use crate::collections::SmallVec; +use core::ops::Range; +use raw::{ + tables::glyf::{PointFlags, PointMarker}, + types::{F26Dot6, F2Dot14}, +}; + +/// Hinting directions. +/// +/// The values are such that `dir1 + dir2 == 0` when the directions are +/// opposite. +/// +/// See +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[repr(i8)] +pub(crate) enum Direction { + #[default] + None = 4, + Right = 1, + Left = -1, + Up = 2, + Down = -2, +} + +impl Direction { + /// Computes a direction from a vector. + /// + /// See + pub fn new(dx: i32, dy: i32) -> Self { + let (dir, long_arm, short_arm) = if dy >= dx { + if dy >= -dx { + (Direction::Up, dy, dx) + } else { + (Direction::Left, -dx, dy) + } + } else if dy >= -dx { + (Direction::Right, dx, dy) + } else { + (Direction::Down, -dy, dx) + }; + // Return no direction if arm lengths do not differ enough. + // + if long_arm <= 14 * short_arm.abs() { + Direction::None + } else { + dir + } + } + + pub fn is_opposite(self, other: Self) -> bool { + self as i8 + other as i8 == 0 + } + + pub fn is_same_axis(self, other: Self) -> bool { + (self as i8).abs() == (other as i8).abs() + } + + pub fn normalize(self) -> Self { + // FreeType uses absolute value for this. + match self { + Self::Left => Self::Right, + Self::Down => Self::Up, + _ => self, + } + } +} + +/// The overall orientation of an outline. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) enum Orientation { + Clockwise, + CounterClockwise, +} + +/// Outline point with a lot of context for hinting. +/// +/// See +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(super) struct Point { + /// Describes the type and hinting state of the point. + pub flags: PointFlags, + /// X coordinate in font units. + pub fx: i32, + /// Y coordinate in font units. + pub fy: i32, + /// Scaled X coordinate. + pub ox: i32, + /// Scaled Y coordinate. + pub oy: i32, + /// Hinted X coordinate. + pub x: i32, + /// Hinted Y coordinate. + pub y: i32, + /// Direction of inwards vector. + pub in_dir: Direction, + /// Direction of outwards vector. + pub out_dir: Direction, + /// Context dependent coordinate. + pub u: i32, + /// Context dependent coordinate. + pub v: i32, + /// Index of next point in contour. + pub next_ix: u16, + /// Index of previous point in contour. + pub prev_ix: u16, +} + +impl Point { + pub fn is_on_curve(&self) -> bool { + self.flags.is_on_curve() + } + + /// Returns the index of the next point in the contour. + pub fn next(&self) -> usize { + self.next_ix as usize + } + + /// Returns the index of the previous point in the contour. + pub fn prev(&self) -> usize { + self.prev_ix as usize + } + + #[inline(always)] + fn as_contour_point(&self) -> path::ContourPoint { + path::ContourPoint { + x: F26Dot6::from_bits(self.x), + y: F26Dot6::from_bits(self.y), + flags: self.flags, + } + } +} + +// Matches FreeType's inline usage +// +// See +const MAX_INLINE_POINTS: usize = 96; +const MAX_INLINE_CONTOURS: usize = 8; + +#[derive(Default)] +pub(super) struct Outline { + pub units_per_em: i32, + pub orientation: Option, + pub points: SmallVec, + pub contours: SmallVec, + pub advance: i32, +} + +impl Outline { + /// Fills the outline from the given glyph. + pub fn fill(&mut self, glyph: &OutlineGlyph, coords: &[F2Dot14]) -> Result<(), DrawError> { + self.clear(); + let advance = glyph.draw_unscaled(LocationRef::new(coords), None, self)?; + self.advance = advance; + self.units_per_em = glyph.units_per_em() as i32; + // Heuristic value + let near_limit = 20 * self.units_per_em / 2048; + self.link_points(); + self.mark_near_points(near_limit); + self.compute_directions(near_limit); + self.simplify_topology(); + self.check_remaining_weak_points(); + self.compute_orientation(); + Ok(()) + } + + /// Applies dimension specific scaling factors and deltas to each + /// point in the outline. + pub fn scale(&mut self, scale: &Scale) { + use super::metrics::fixed_mul; + for point in &mut self.points { + let x = fixed_mul(point.fx, scale.x_scale) + scale.x_delta; + let y = fixed_mul(point.fy, scale.y_scale) + scale.y_delta; + point.ox = x; + point.x = x; + point.oy = y; + point.y = y; + } + } + + pub fn clear(&mut self) { + self.units_per_em = 0; + self.points.clear(); + self.contours.clear(); + self.advance = 0; + } + + pub fn to_path( + &self, + style: PathStyle, + pen: &mut impl OutlinePen, + ) -> Result<(), path::ToPathError> { + for contour in &self.contours { + let Some(points) = self.points.get(contour.range()) else { + continue; + }; + if let Some(last_point) = points.last().map(Point::as_contour_point) { + path::contour_to_path( + points.iter().map(Point::as_contour_point), + last_point, + style, + pen, + )?; + } + } + Ok(()) + } +} + +impl Outline { + /// Sets next and previous indices for each point. + fn link_points(&mut self) { + let points = self.points.as_mut_slice(); + for contour in &self.contours { + let Some(points) = points.get_mut(contour.range()) else { + continue; + }; + let first_ix = contour.first() as u16; + let mut prev_ix = contour.last() as u16; + for (ix, point) in points.iter_mut().enumerate() { + let ix = ix as u16 + first_ix; + point.prev_ix = prev_ix; + prev_ix = ix; + point.next_ix = ix + 1; + } + points.last_mut().unwrap().next_ix = first_ix; + } + } + + /// Computes the near flag for each contour. + /// + /// See + fn mark_near_points(&mut self, near_limit: i32) { + let points = self.points.as_mut_slice(); + for contour in &self.contours { + let mut prev_ix = contour.last(); + for ix in contour.range() { + let point = points[ix]; + let prev = &mut points[prev_ix]; + // + let out_x = point.fx - prev.fx; + let out_y = point.fy - prev.fy; + if out_x.abs() + out_y.abs() < near_limit { + prev.flags.set_marker(PointMarker::NEAR); + } + prev_ix = ix; + } + } + } + + /// Compute directions of in and out vectors. + /// + /// See + fn compute_directions(&mut self, near_limit: i32) { + let near_limit2 = 2 * near_limit - 1; + let points = self.points.as_mut_slice(); + for contour in &self.contours { + // Walk backward to find the first non-near point. + let mut first_ix = contour.first(); + let mut ix = first_ix; + let mut prev_ix = contour.prev(first_ix); + let mut point = points[first_ix]; + while prev_ix != first_ix { + let prev = points[prev_ix]; + let out_x = point.fx - prev.fx; + let out_y = point.fy - prev.fy; + // + if out_x.abs() + out_y.abs() >= near_limit2 { + break; + } + point = prev; + ix = prev_ix; + prev_ix = contour.prev(prev_ix); + } + first_ix = ix; + // Abuse u and v fields to store deltas to the next and previous + // non-near points, respectively. + let first = &mut points[first_ix]; + first.u = first_ix as _; + first.v = first_ix as _; + let mut next_ix = first_ix; + let mut ix = first_ix; + // Now loop over all points in the contour to compute in and + // out directions + let mut out_x = 0; + let mut out_y = 0; + loop { + let point_ix = next_ix; + next_ix = contour.next(point_ix); + let point = points[point_ix]; + let next = &mut points[next_ix]; + // Accumulate the deltas until we surpass near_limit + out_x += next.fx - point.fx; + out_y += next.fy - point.fy; + if out_x.abs() + out_y.abs() < near_limit { + next.flags.set_marker(PointMarker::WEAK_INTERPOLATION); + // The original code is a do-while loop, so make + // sure we keep this condition before the continue + if next_ix == first_ix { + break; + } + continue; + } + let out_dir = Direction::new(out_x, out_y); + next.in_dir = out_dir; + next.v = ix as _; + let cur = &mut points[ix]; + cur.u = next_ix as _; + cur.out_dir = out_dir; + // Adjust directions for all intermediate points + let mut inter_ix = contour.next(ix); + while inter_ix != next_ix { + let point = &mut points[inter_ix]; + point.in_dir = out_dir; + point.out_dir = out_dir; + inter_ix = contour.next(inter_ix); + } + ix = next_ix; + points[ix].u = first_ix as _; + points[first_ix].v = ix as _; + out_x = 0; + out_y = 0; + if next_ix == first_ix { + break; + } + } + } + } + + /// Simplify so that we can identify local extrema more reliably. + /// + /// See + fn simplify_topology(&mut self) { + let points = self.points.as_mut_slice(); + for i in 0..points.len() { + let point = points[i]; + if point.flags.has_marker(PointMarker::WEAK_INTERPOLATION) { + continue; + } + if point.in_dir == Direction::None && point.out_dir == Direction::None { + let u_index = point.u as usize; + let v_index = point.v as usize; + let next_u = points[u_index]; + let prev_v = points[v_index]; + let in_x = point.fx - prev_v.fx; + let in_y = point.fy - prev_v.fy; + let out_x = next_u.fx - point.fx; + let out_y = next_u.fy - point.fy; + if (in_x ^ out_x) >= 0 && (in_y ^ out_y) >= 0 { + // Both vectors point into the same quadrant + points[i].flags.set_marker(PointMarker::WEAK_INTERPOLATION); + points[v_index].u = u_index as _; + points[u_index].v = v_index as _; + } + } + } + } + + /// Check for remaining weak points. + /// + /// See + fn check_remaining_weak_points(&mut self) { + let points = self.points.as_mut_slice(); + for i in 0..points.len() { + let point = points[i]; + let mut make_weak = false; + if point.flags.has_marker(PointMarker::WEAK_INTERPOLATION) { + // Already weak + continue; + } + if !point.flags.is_on_curve() { + // Control points are always weak + make_weak = true; + } else if point.out_dir == point.in_dir { + if point.out_dir != Direction::None { + // Point lies on a vertical or horizontal segment but + // not at start or end + make_weak = true; + } else { + let u_index = point.u as usize; + let v_index = point.v as usize; + let next_u = points[u_index]; + let prev_v = points[v_index]; + if is_corner_flat( + point.fx - prev_v.fx, + point.fy - prev_v.fy, + next_u.fx - point.fx, + next_u.fy - point.fy, + ) { + // One of the vectors is more dominant + make_weak = true; + points[v_index].u = u_index as _; + points[u_index].v = v_index as _; + } + } + } else if point.in_dir.is_opposite(point.out_dir) { + // Point forms a "spike" + make_weak = true; + } + if make_weak { + points[i].flags.set_marker(PointMarker::WEAK_INTERPOLATION); + } + } + } + + /// Computes the overall winding order of the outline. + /// + /// See + fn compute_orientation(&mut self) { + self.orientation = None; + let points = self.points.as_slice(); + if points.is_empty() { + return; + } + fn point_to_i64(point: &Point) -> (i64, i64) { + (point.fx as i64, point.fy as i64) + } + let mut area = 0i64; + for contour in &self.contours { + let last_ix = contour.last(); + let first_ix = contour.first(); + let (mut prev_x, mut prev_y) = point_to_i64(&points[last_ix]); + for point in &points[first_ix..=last_ix] { + let (x, y) = point_to_i64(point); + area += (y - prev_y) * (x + prev_x); + (prev_x, prev_y) = (x, y); + } + } + use core::cmp::Ordering; + self.orientation = match area.cmp(&0) { + Ordering::Less => Some(Orientation::CounterClockwise), + Ordering::Greater => Some(Orientation::Clockwise), + Ordering::Equal => None, + }; + } +} + +/// See +fn is_corner_flat(in_x: i32, in_y: i32, out_x: i32, out_y: i32) -> bool { + let ax = in_x + out_x; + let ay = in_y + out_y; + fn hypot(x: i32, y: i32) -> i32 { + let x = x.abs(); + let y = y.abs(); + if x > y { + x + ((3 * y) >> 3) + } else { + y + ((3 * x) >> 3) + } + } + let d_in = hypot(in_x, in_y); + let d_out = hypot(out_x, out_y); + let d_hypot = hypot(ax, ay); + (d_in + d_out - d_hypot) < (d_hypot >> 4) +} + +#[derive(Copy, Clone, Default, Debug)] +pub(super) struct Contour { + first_ix: u16, + last_ix: u16, +} + +impl Contour { + pub fn first(self) -> usize { + self.first_ix as usize + } + + pub fn last(self) -> usize { + self.last_ix as usize + } + + pub fn next(self, index: usize) -> usize { + if index >= self.last_ix as usize { + self.first_ix as usize + } else { + index + 1 + } + } + + pub fn prev(self, index: usize) -> usize { + if index <= self.first_ix as usize { + self.last_ix as usize + } else { + index - 1 + } + } + + pub fn range(self) -> Range { + self.first()..self.last() + 1 + } +} + +impl UnscaledOutlineSink for Outline { + fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError> { + if self.points.try_reserve(additional) { + Ok(()) + } else { + Err(DrawError::InsufficientMemory) + } + } + + fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError> { + let new_point = Point { + flags: point.flags, + fx: point.x as i32, + fy: point.y as i32, + ..Default::default() + }; + let new_point_ix: u16 = self + .points + .len() + .try_into() + .map_err(|_| DrawError::InsufficientMemory)?; + if point.is_contour_start { + self.contours.push(Contour { + first_ix: new_point_ix, + last_ix: new_point_ix, + }); + } else if let Some(last_contour) = self.contours.last_mut() { + last_contour.last_ix += 1; + } else { + // If our first point is not marked as contour start, just + // create a new contour. + self.contours.push(Contour { + first_ix: new_point_ix, + last_ix: new_point_ix, + }); + } + self.points.push(new_point); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::super::super::{pen::SvgPen, DrawSettings}; + use super::*; + use crate::{prelude::Size, MetadataProvider}; + use raw::{types::GlyphId, FontRef, TableProvider}; + + #[test] + fn direction_from_vectors() { + assert_eq!(Direction::new(-100, 0), Direction::Left); + assert_eq!(Direction::new(100, 0), Direction::Right); + assert_eq!(Direction::new(0, -100), Direction::Down); + assert_eq!(Direction::new(0, 100), Direction::Up); + assert_eq!(Direction::new(7, 100), Direction::Up); + // This triggers the too close heuristic + assert_eq!(Direction::new(8, 100), Direction::None); + } + + #[test] + fn direction_axes() { + use Direction::*; + let hori = [Left, Right]; + let vert = [Up, Down]; + for h in hori { + for h2 in hori { + assert!(h.is_same_axis(h2)); + if h != h2 { + assert!(h.is_opposite(h2)); + } else { + assert!(!h.is_opposite(h2)); + } + } + for v in vert { + assert!(!h.is_same_axis(v)); + assert!(!h.is_opposite(v)); + } + } + for v in vert { + for v2 in vert { + assert!(v.is_same_axis(v2)); + if v != v2 { + assert!(v.is_opposite(v2)); + } else { + assert!(!v.is_opposite(v2)); + } + } + } + } + + #[test] + fn fill_outline() { + let outline = make_outline(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, 8); + use Direction::*; + let expected = &[ + // (x, y, in_dir, out_dir, flags) + (107, 0, Left, Left, 3), + (85, 0, Left, None, 2), + (55, 26, None, Up, 2), + (55, 71, Up, Up, 3), + (55, 332, Up, Up, 3), + (55, 360, Up, None, 2), + (67, 411, None, None, 2), + (93, 459, None, None, 2), + (112, 481, None, Up, 1), + (112, 504, Up, Right, 1), + (168, 504, Right, Down, 1), + (168, 483, Down, None, 1), + (153, 473, None, None, 2), + (126, 428, None, None, 2), + (109, 366, None, Down, 2), + (109, 332, Down, Down, 3), + (109, 109, Down, Right, 1), + (407, 109, Right, Right, 3), + (427, 109, Right, None, 2), + (446, 136, None, None, 2), + (453, 169, None, Up, 2), + (453, 178, Up, Up, 3), + (453, 374, Up, Up, 3), + (453, 432, Up, None, 2), + (400, 483, None, Left, 2), + (362, 483, Left, Left, 3), + (109, 483, Left, Left, 3), + (86, 483, Left, None, 2), + (62, 517, None, Up, 2), + (62, 555, Up, Up, 3), + (62, 566, Up, None, 2), + (64, 587, None, None, 2), + (71, 619, None, None, 2), + (76, 647, None, Right, 1), + (103, 647, Right, Down, 9), + (103, 644, Down, Down, 3), + (103, 619, Down, None, 2), + (131, 592, None, Right, 2), + (155, 592, Right, Right, 3), + (386, 592, Right, Right, 3), + (437, 592, Right, None, 2), + (489, 552, None, None, 2), + (507, 485, None, Down, 2), + (507, 443, Down, Down, 3), + (507, 75, Down, Down, 3), + (507, 40, Down, None, 2), + (470, 0, None, Left, 2), + (436, 0, Left, Left, 3), + ]; + let points = outline + .points + .iter() + .map(|point| { + ( + point.fx, + point.fy, + point.in_dir, + point.out_dir, + point.flags.to_bits(), + ) + }) + .collect::>(); + assert_eq!(&points, expected); + } + + #[test] + fn orientation() { + let tt_outline = make_outline(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, 8); + // TrueType outlines are counter clockwise + assert_eq!(tt_outline.orientation, Some(Orientation::CounterClockwise)); + let ps_outline = make_outline(font_test_data::CANTARELL_VF_TRIMMED, 4); + // PostScript outlines are clockwise + assert_eq!(ps_outline.orientation, Some(Orientation::Clockwise)); + } + + fn make_outline(font_data: &[u8], glyph_id: u32) -> Outline { + let font = FontRef::new(font_data).unwrap(); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::from(glyph_id)).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + outline + } + + #[test] + fn mostly_off_curve_to_path_scan_backward() { + compare_path_conversion(font_test_data::MOSTLY_OFF_CURVE, PathStyle::FreeType); + } + + #[test] + fn mostly_off_curve_to_path_scan_forward() { + compare_path_conversion(font_test_data::MOSTLY_OFF_CURVE, PathStyle::HarfBuzz); + } + + #[test] + fn starting_off_curve_to_path_scan_backward() { + compare_path_conversion(font_test_data::STARTING_OFF_CURVE, PathStyle::FreeType); + } + + #[test] + fn starting_off_curve_to_path_scan_forward() { + compare_path_conversion(font_test_data::STARTING_OFF_CURVE, PathStyle::HarfBuzz); + } + + #[test] + fn cubic_to_path_scan_backward() { + compare_path_conversion(font_test_data::CUBIC_GLYF, PathStyle::FreeType); + } + + #[test] + fn cubic_to_path_scan_forward() { + compare_path_conversion(font_test_data::CUBIC_GLYF, PathStyle::HarfBuzz); + } + + #[test] + fn cff_to_path_scan_backward() { + compare_path_conversion(font_test_data::CANTARELL_VF_TRIMMED, PathStyle::FreeType); + } + + #[test] + fn cff_to_path_scan_forward() { + compare_path_conversion(font_test_data::CANTARELL_VF_TRIMMED, PathStyle::HarfBuzz); + } + + /// Ensures autohint path conversion matches the base scaler path + /// conversion for all glyphs in the given font with a certain + /// path style. + fn compare_path_conversion(font_data: &[u8], path_style: PathStyle) { + let font = FontRef::new(font_data).unwrap(); + let glyph_count = font.maxp().unwrap().num_glyphs(); + let glyphs = font.outline_glyphs(); + let mut results = Vec::new(); + // And all glyphs + for gid in 0..glyph_count { + let glyph = glyphs.get(GlyphId::from(gid)).unwrap(); + // Unscaled, unhinted code path + let mut base_svg = SvgPen::default(); + let settings = DrawSettings::unhinted(Size::unscaled(), LocationRef::default()) + .with_path_style(path_style); + glyph.draw(settings, &mut base_svg).unwrap(); + let base_svg = base_svg.to_string(); + // Autohinter outline code path + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + // The to_path method uses the (x, y) coords which aren't filled + // until we scale (and we aren't doing that here) so update + // them with 26.6 values manually + for point in &mut outline.points { + point.x = point.fx << 6; + point.y = point.fy << 6; + } + let mut autohint_svg = SvgPen::default(); + outline.to_path(path_style, &mut autohint_svg).unwrap(); + let autohint_svg = autohint_svg.to_string(); + if base_svg != autohint_svg { + results.push((gid, base_svg, autohint_svg)); + } + } + if !results.is_empty() { + let report: String = results + .into_iter() + .map(|(gid, expected, got)| { + format!("[glyph {gid}]\nexpected: {expected}\n got: {got}") + }) + .collect::>() + .join("\n"); + panic!("outline to path comparison failed:\n{report}"); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,850 @@ +//! Shaping support for autohinting. + +use super::style::{GlyphStyle, StyleClass}; +use crate::{charmap::Charmap, collections::SmallVec, FontRef, GlyphId, MetadataProvider}; +use core::ops::Range; +use raw::{ + tables::{ + gsub::{ + ChainedSequenceContext, Gsub, SequenceContext, SingleSubst, SubstitutionLookupList, + SubstitutionSubtables, + }, + layout::{Feature, ScriptTags}, + varc::CoverageTable, + }, + types::Tag, + ReadError, TableProvider, +}; + +// To prevent infinite recursion in contextual lookups. Matches HB +// +const MAX_NESTING_DEPTH: usize = 64; + +/// Determines the fidelity with which we apply shaping in the +/// autohinter. +/// +/// Shaping only affects glyph style classification and the glyphs that +/// are chosen for metrics computations. We keep the `Nominal` mode around +/// to enable validation of internal algorithms against a configuration that +/// is known to match FreeType. The `BestEffort` mode should always be +/// used for actual rendering. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) enum ShaperMode { + /// Characters are mapped to nominal glyph identifiers and layout tables + /// are not used for style coverage. + /// + /// This matches FreeType when HarfBuzz support is not enabled. + Nominal, + /// Simple substitutions are applied according to script rules and layout + /// tables are used to extend style coverage beyond the character map. + #[allow(unused)] + BestEffort, +} + +#[derive(Copy, Clone, Default, Debug)] +pub(crate) struct ShapedGlyph { + pub id: GlyphId, + /// This may be used for computing vertical alignment zones, particularly + /// for glyphs like super/subscripts which might have adjustments in GPOS. + /// + /// Note that we don't do the same in the horizontal direction which + /// means that we don't care about the x-offset. + pub y_offset: i32, +} + +/// Arbitrarily chosen to cover our max input size plus some extra to account +/// for expansion from multiple substitution tables. +const SHAPED_CLUSTER_INLINE_SIZE: usize = 16; + +/// Container for storing the result of shaping a cluster. +/// +/// Some of our input "characters" for metrics computations are actually +/// multi-character [grapheme clusters](https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries) +/// that may expand to multiple glyphs. +pub(crate) type ShapedCluster = SmallVec; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(crate) enum ShaperCoverageKind { + /// Shaper coverage that traverses a specific script. + Script, + /// Shaper coverage that also includes the `Dflt` script. + /// + /// This is used as a catch all after all styles are processed. + Default, +} + +/// Maps characters to glyphs and handles extended style coverage beyond +/// glyphs that are available in the character map. +/// +/// Roughly covers the functionality in . +pub(crate) struct Shaper<'a> { + font: FontRef<'a>, + #[allow(unused)] + mode: ShaperMode, + charmap: Charmap<'a>, + gsub: Option>, +} + +impl<'a> Shaper<'a> { + pub fn new(font: &FontRef<'a>, mode: ShaperMode) -> Self { + let charmap = font.charmap(); + let gsub = (mode != ShaperMode::Nominal) + .then(|| font.gsub().ok()) + .flatten(); + Self { + font: font.clone(), + mode, + charmap, + gsub, + } + } + + pub fn font(&self) -> &FontRef<'a> { + &self.font + } + + pub fn charmap(&self) -> &Charmap<'a> { + &self.charmap + } + + pub fn lookup_count(&self) -> u16 { + self.gsub + .as_ref() + .and_then(|gsub| gsub.lookup_list().ok()) + .map(|list| list.lookup_count()) + .unwrap_or_default() + } + + pub fn cluster_shaper(&'a self, style: &StyleClass) -> ClusterShaper<'a> { + if self.mode == ShaperMode::BestEffort { + // For now, only apply substitutions for styles with an associated + // feature + if let Some(feature_tag) = style.feature { + if let Some((lookup_list, feature)) = self.gsub.as_ref().and_then(|gsub| { + let script_list = gsub.script_list().ok()?; + let selected_script = + script_list.select(&ScriptTags::from_unicode(style.script.tag))?; + let script = script_list.get(selected_script.index).ok()?; + let lang_sys = script.default_lang_sys()?.ok()?; + let feature_list = gsub.feature_list().ok()?; + let feature_ix = lang_sys.feature_index_for_tag(&feature_list, feature_tag)?; + let feature = feature_list.get(feature_ix).ok()?.element; + let lookup_list = gsub.lookup_list().ok()?; + Some((lookup_list, feature)) + }) { + return ClusterShaper { + shaper: self, + lookup_list: Some(lookup_list), + kind: ClusterShaperKind::SingleFeature(feature), + }; + } + } + } + ClusterShaper { + shaper: self, + lookup_list: None, + kind: ClusterShaperKind::Nominal, + } + } + + /// Uses layout tables to compute coverage for the given style. + /// + /// Returns `true` if any glyph styles were updated for this style. + /// + /// See + pub(crate) fn compute_coverage( + &self, + style: &StyleClass, + coverage_kind: ShaperCoverageKind, + glyph_styles: &mut [GlyphStyle], + visited_set: &mut VisitedLookupSet<'_>, + ) -> bool { + let Some(gsub) = self.gsub.as_ref() else { + return false; + }; + let (Ok(script_list), Ok(feature_list), Ok(lookup_list)) = + (gsub.script_list(), gsub.feature_list(), gsub.lookup_list()) + else { + return false; + }; + let mut script_tags: [Option; 3] = [None; 3]; + for (a, b) in script_tags + .iter_mut() + .zip(ScriptTags::from_unicode(style.script.tag).iter()) + { + *a = Some(*b); + } + // + const DEFAULT_SCRIPT: Tag = Tag::new(b"Dflt"); + if coverage_kind == ShaperCoverageKind::Default { + if script_tags[0].is_none() { + script_tags[0] = Some(DEFAULT_SCRIPT); + } else if script_tags[1].is_none() { + script_tags[1] = Some(DEFAULT_SCRIPT); + } else if script_tags[1] != Some(DEFAULT_SCRIPT) { + script_tags[2] = Some(DEFAULT_SCRIPT); + } + } else { + // Script classes contain some non-standard tags used for special + // purposes. We ignore these + // + const NON_STANDARD_TAGS: &[Option] = &[ + // Khmer symbols + Some(Tag::new(b"Khms")), + // Latin subscript fallbacks + Some(Tag::new(b"Latb")), + // Latin superscript fallbacks + Some(Tag::new(b"Latp")), + ]; + if NON_STANDARD_TAGS.contains(&script_tags[0]) { + return false; + } + } + // Check each requested script that is available in GSUB + let mut gsub_handler = GsubHandler::new( + &self.charmap, + &lookup_list, + style, + glyph_styles, + visited_set, + ); + for script in script_tags.iter().filter_map(|tag| { + tag.and_then(|tag| script_list.index_for_tag(tag)) + .and_then(|ix| script_list.script_records().get(ix as usize)) + .and_then(|rec| rec.script(script_list.offset_data()).ok()) + }) { + // And all language systems for each script + for langsys in script + .lang_sys_records() + .iter() + .filter_map(|rec| rec.lang_sys(script.offset_data()).ok()) + .chain(script.default_lang_sys().transpose().ok().flatten()) + { + for feature_ix in langsys.feature_indices() { + let Some(feature) = feature_list + .feature_records() + .get(feature_ix.get() as usize) + .and_then(|rec| { + // If our style has a feature tag, we only look at that specific + // feature; otherwise, handle all of them + if style.feature == Some(rec.feature_tag()) || style.feature.is_none() { + rec.feature(feature_list.offset_data()).ok() + } else { + None + } + }) + else { + continue; + }; + // And now process associated lookups + for index in feature.lookup_list_indices().iter() { + // We only care about errors here for testing + let _ = gsub_handler.process_lookup(index.get()); + } + } + } + } + if let Some(range) = gsub_handler.finish() { + // If we get a range then we captured at least some glyphs so + // let's try to assign our current style + let mut result = false; + for glyph_style in &mut glyph_styles[range] { + // We only want to return true here if we actually assign the + // style to avoid computing unnecessary metrics + result |= glyph_style.maybe_assign_gsub_output_style(style); + } + result + } else { + false + } + } +} + +pub(crate) struct ClusterShaper<'a> { + shaper: &'a Shaper<'a>, + lookup_list: Option>, + kind: ClusterShaperKind<'a>, +} + +impl ClusterShaper<'_> { + pub(crate) fn shape(&mut self, input: &str, output: &mut ShapedCluster) { + // First fill the output cluster with the nominal character + // to glyph id mapping + output.clear(); + for ch in input.chars() { + output.push(ShapedGlyph { + id: self.shaper.charmap.map(ch).unwrap_or_default(), + y_offset: 0, + }); + } + match self.kind.clone() { + ClusterShaperKind::Nominal => { + // In nominal mode, reject clusters with multiple glyphs + // See + if self.shaper.mode == ShaperMode::Nominal && output.len() > 1 { + output.clear(); + } + } + ClusterShaperKind::SingleFeature(feature) => { + let mut did_subst = false; + for lookup_ix in feature.lookup_list_indices() { + let mut glyph_ix = 0; + while glyph_ix < output.len() { + did_subst |= self.apply_lookup(lookup_ix.get(), output, glyph_ix, 0); + glyph_ix += 1; + } + } + // Reject clusters that weren't modified by the feature. + // FreeType detects this by shaping twice and comparing gids + // but we just track substitutions + // + if !did_subst { + output.clear(); + } + } + } + } + + fn apply_lookup( + &self, + lookup_index: u16, + cluster: &mut ShapedCluster, + glyph_ix: usize, + nesting_depth: usize, + ) -> bool { + if nesting_depth > MAX_NESTING_DEPTH { + return false; + } + let Some(glyph) = cluster.get_mut(glyph_ix) else { + return false; + }; + let Some(subtables) = self + .lookup_list + .as_ref() + .and_then(|list| list.lookups().get(lookup_index as usize).ok()) + .and_then(|lookup| lookup.subtables().ok()) + else { + return false; + }; + match subtables { + // For now, just applying single substitutions because we're + // currently only handling shaping for "feature" styles like + // c2sc (caps to small caps) which are (almost?) always + // single substs + SubstitutionSubtables::Single(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + match table { + SingleSubst::Format1(table) => { + let Some(_) = table.coverage().ok().and_then(|cov| cov.get(glyph.id)) + else { + continue; + }; + let delta = table.delta_glyph_id() as i32; + glyph.id = GlyphId::from((glyph.id.to_u32() as i32 + delta) as u16); + return true; + } + SingleSubst::Format2(table) => { + let Some(cov_ix) = + table.coverage().ok().and_then(|cov| cov.get(glyph.id)) + else { + continue; + }; + let Some(subst) = table.substitute_glyph_ids().get(cov_ix as usize) + else { + continue; + }; + glyph.id = subst.get().into(); + return true; + } + } + } + } + SubstitutionSubtables::Multiple(_tables) => {} + SubstitutionSubtables::Ligature(_tables) => {} + SubstitutionSubtables::Alternate(_tables) => {} + SubstitutionSubtables::Contextual(_tables) => {} + SubstitutionSubtables::ChainContextual(_tables) => {} + SubstitutionSubtables::Reverse(_tables) => {} + } + false + } +} + +#[derive(Clone)] +enum ClusterShaperKind<'a> { + Nominal, + SingleFeature(Feature<'a>), +} + +/// Captures glyphs from the GSUB table that aren't present in cmap. +/// +/// FreeType does this in a few phases: +/// 1. Collect all lookups for a given set of scripts and features. +/// +/// 2. For each lookup, collect all _output_ glyphs. +/// +/// 3. If the style represents a specific feature, make sure at least one of +/// the characters in the associated blue string would be substituted by +/// those lookups. If none would be substituted, then we don't assign the +/// style to any glyphs because we don't have any modified alignment +/// zones. +/// +/// +/// We roll these into one pass over the lookups below so that we don't have +/// to allocate a lookup set or iterate them twice. Note that since +/// substitutions are checked for individual characters, we ignore ligatures +/// and contextual lookups (and alternates since they aren't applicable). +struct GsubHandler<'a, 'b> { + charmap: &'a Charmap<'a>, + lookup_list: &'a SubstitutionLookupList<'a>, + style: &'a StyleClass, + glyph_styles: &'a mut [GlyphStyle], + // Set to true when we need to check if any substitutions are available + // for our blue strings. This is the case when style.feature != None + need_blue_substs: bool, + // Keep track of our range of touched gids in the style list + min_gid: usize, + max_gid: usize, + lookup_depth: usize, + visited_set: &'a mut VisitedLookupSet<'b>, +} + +impl<'a, 'b> GsubHandler<'a, 'b> { + fn new( + charmap: &'a Charmap<'a>, + lookup_list: &'a SubstitutionLookupList, + style: &'a StyleClass, + glyph_styles: &'a mut [GlyphStyle], + visited_set: &'a mut VisitedLookupSet<'b>, + ) -> Self { + let min_gid = glyph_styles.len(); + // If we have a feature, then we need to check the blue string to see + // if any substitutions are available. If not, we don't enable this + // style because it won't have any affect on alignment zones + let need_blue_substs = style.feature.is_some(); + Self { + charmap, + lookup_list, + style, + glyph_styles, + need_blue_substs, + min_gid, + max_gid: 0, + lookup_depth: 0, + visited_set, + } + } + + fn process_lookup(&mut self, lookup_index: u16) -> Result<(), ProcessLookupError> { + // General protection against stack overflows + if self.lookup_depth == MAX_NESTING_DEPTH { + return Err(ProcessLookupError::ExceededMaxDepth); + } + // Skip lookups that have already been processed + if !self.visited_set.insert(lookup_index) { + return Ok(()); + } + self.lookup_depth += 1; + // Actually process the lookup + let result = self.process_lookup_inner(lookup_index); + // Out we go again + self.lookup_depth -= 1; + result + } + + #[inline(always)] + fn process_lookup_inner(&mut self, lookup_index: u16) -> Result<(), ProcessLookupError> { + let Ok(subtables) = self + .lookup_list + .lookups() + .get(lookup_index as usize) + .and_then(|lookup| lookup.subtables()) + else { + return Ok(()); + }; + match subtables { + SubstitutionSubtables::Single(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + match table { + SingleSubst::Format1(table) => { + let Ok(coverage) = table.coverage() else { + continue; + }; + let delta = table.delta_glyph_id() as i32; + for gid in coverage.iter() { + self.capture_glyph((gid.to_u32() as i32 + delta) as u16 as u32); + } + // Check input coverage for blue strings if + // required and if we're not under a contextual + // lookup + if self.need_blue_substs && self.lookup_depth == 1 { + self.check_blue_coverage(Ok(coverage)); + } + } + SingleSubst::Format2(table) => { + for gid in table.substitute_glyph_ids() { + self.capture_glyph(gid.get().to_u32()); + } + // See above + if self.need_blue_substs && self.lookup_depth == 1 { + self.check_blue_coverage(table.coverage()); + } + } + } + } + } + SubstitutionSubtables::Multiple(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + for seq in table.sequences().iter().filter_map(|seq| seq.ok()) { + for gid in seq.substitute_glyph_ids() { + self.capture_glyph(gid.get().to_u32()); + } + } + // See above + if self.need_blue_substs && self.lookup_depth == 1 { + self.check_blue_coverage(table.coverage()); + } + } + } + SubstitutionSubtables::Ligature(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + for set in table.ligature_sets().iter().filter_map(|set| set.ok()) { + for lig in set.ligatures().iter().filter_map(|lig| lig.ok()) { + self.capture_glyph(lig.ligature_glyph().to_u32()); + } + } + } + } + SubstitutionSubtables::Alternate(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + for set in table.alternate_sets().iter().filter_map(|set| set.ok()) { + for gid in set.alternate_glyph_ids() { + self.capture_glyph(gid.get().to_u32()); + } + } + } + } + SubstitutionSubtables::Contextual(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + match table { + SequenceContext::Format1(table) => { + for set in table + .seq_rule_sets() + .iter() + .filter_map(|set| set.transpose().ok().flatten()) + { + for rule in set.seq_rules().iter().filter_map(|rule| rule.ok()) { + for rec in rule.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + SequenceContext::Format2(table) => { + for set in table + .class_seq_rule_sets() + .iter() + .filter_map(|set| set.transpose().ok().flatten()) + { + for rule in + set.class_seq_rules().iter().filter_map(|rule| rule.ok()) + { + for rec in rule.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + SequenceContext::Format3(table) => { + for rec in table.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + } + SubstitutionSubtables::ChainContextual(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + match table { + ChainedSequenceContext::Format1(table) => { + for set in table + .chained_seq_rule_sets() + .iter() + .filter_map(|set| set.transpose().ok().flatten()) + { + for rule in + set.chained_seq_rules().iter().filter_map(|rule| rule.ok()) + { + for rec in rule.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + ChainedSequenceContext::Format2(table) => { + for set in table + .chained_class_seq_rule_sets() + .iter() + .filter_map(|set| set.transpose().ok().flatten()) + { + for rule in set + .chained_class_seq_rules() + .iter() + .filter_map(|rule| rule.ok()) + { + for rec in rule.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + ChainedSequenceContext::Format3(table) => { + for rec in table.seq_lookup_records() { + self.process_lookup(rec.lookup_list_index())?; + } + } + } + } + } + SubstitutionSubtables::Reverse(tables) => { + for table in tables.iter().filter_map(|table| table.ok()) { + for gid in table.substitute_glyph_ids() { + self.capture_glyph(gid.get().to_u32()); + } + } + } + } + Ok(()) + } + + /// Finishes processing for this set of GSUB lookups and + /// returns the range of touched glyphs. + fn finish(self) -> Option> { + self.visited_set.clear(); + if self.min_gid > self.max_gid { + // We didn't touch any glyphs + return None; + } + let range = self.min_gid..self.max_gid + 1; + if self.need_blue_substs { + // We didn't find any substitutions for our blue strings so + // we ignore the style. Clear the GSUB marker for any touched + // glyphs + for glyph in &mut self.glyph_styles[range] { + glyph.clear_from_gsub(); + } + None + } else { + Some(range) + } + } + + /// Checks the given coverage table for any characters in the blue + /// strings associated with our current style. + fn check_blue_coverage(&mut self, coverage: Result, ReadError>) { + let Ok(coverage) = coverage else { + return; + }; + for (blue_str, _) in self.style.script.blues { + if blue_str + .chars() + .filter_map(|ch| self.charmap.map(ch)) + .filter_map(|gid| coverage.get(gid)) + .next() + .is_some() + { + // Condition satisfied, so don't check any further subtables + self.need_blue_substs = false; + return; + } + } + } + + fn capture_glyph(&mut self, gid: u32) { + let gid = gid as usize; + if let Some(style) = self.glyph_styles.get_mut(gid) { + style.set_from_gsub_output(); + self.min_gid = gid.min(self.min_gid); + self.max_gid = gid.max(self.max_gid); + } + } +} + +pub(crate) struct VisitedLookupSet<'a>(&'a mut [u8]); + +impl<'a> VisitedLookupSet<'a> { + pub fn new(storage: &'a mut [u8]) -> Self { + Self(storage) + } + + /// If the given lookup index is not already in the set, adds it and + /// returns `true`. Returns `false` otherwise. + /// + /// This follows the behavior of `HashSet::insert`. + fn insert(&mut self, lookup_index: u16) -> bool { + let byte_ix = lookup_index as usize / 8; + let bit_mask = 1 << (lookup_index % 8) as u8; + if let Some(byte) = self.0.get_mut(byte_ix) { + if *byte & bit_mask == 0 { + *byte |= bit_mask; + true + } else { + false + } + } else { + false + } + } + + fn clear(&mut self) { + self.0.fill(0); + } +} + +#[derive(PartialEq, Debug)] +enum ProcessLookupError { + ExceededMaxDepth, +} + +#[cfg(test)] +mod tests { + use super::{super::style, *}; + use raw::{test_helpers::BeBuffer, FontData, FontRead}; + + #[test] + fn small_caps_subst() { + let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::BestEffort); + let style = &style::STYLE_CLASSES[style::StyleClass::LATN_C2SC]; + let mut cluster_shaper = shaper.cluster_shaper(style); + let mut cluster = ShapedCluster::new(); + cluster_shaper.shape("H", &mut cluster); + assert_eq!(cluster.len(), 1); + // from ttx, gid 8 is small caps "H" + assert_eq!(cluster[0].id, GlyphId::new(8)); + } + + #[test] + fn small_caps_nominal() { + let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let style = &style::STYLE_CLASSES[style::StyleClass::LATN_C2SC]; + let mut cluster_shaper = shaper.cluster_shaper(style); + let mut cluster = ShapedCluster::new(); + cluster_shaper.shape("H", &mut cluster); + assert_eq!(cluster.len(), 1); + // from ttx, gid 1 is "H" + assert_eq!(cluster[0].id, GlyphId::new(1)); + } + + #[test] + fn exceed_max_depth() { + let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::BestEffort); + let style = &style::STYLE_CLASSES[style::StyleClass::LATN]; + // Build a lookup chain exceeding our max depth + let mut bad_lookup_builder = BadLookupBuilder::default(); + for i in 0..MAX_NESTING_DEPTH { + // each lookup calls the next + bad_lookup_builder.lookups.push(i as u16 + 1); + } + let lookup_list_buf = bad_lookup_builder.build(); + let lookup_list = SubstitutionLookupList::read(FontData::new(&lookup_list_buf)).unwrap(); + let mut set_buf = [0u8; 8192]; + let mut visited_set = VisitedLookupSet(&mut set_buf); + let mut gsub_handler = GsubHandler::new( + &shaper.charmap, + &lookup_list, + style, + &mut [], + &mut visited_set, + ); + assert_eq!( + gsub_handler.process_lookup(0), + Err(ProcessLookupError::ExceededMaxDepth) + ); + } + + #[test] + fn dont_cycle_forever() { + let font = FontRef::new(font_test_data::NOTOSERIF_AUTOHINT_SHAPING).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::BestEffort); + let style = &style::STYLE_CLASSES[style::StyleClass::LATN]; + // Build a lookup chain that cycles; 0 calls 1 which calls 0 + let mut bad_lookup_builder = BadLookupBuilder::default(); + bad_lookup_builder.lookups.push(1); + bad_lookup_builder.lookups.push(0); + let lookup_list_buf = bad_lookup_builder.build(); + let lookup_list = SubstitutionLookupList::read(FontData::new(&lookup_list_buf)).unwrap(); + let mut set_buf = [0u8; 8192]; + let mut visited_set = VisitedLookupSet(&mut set_buf); + let mut gsub_handler = GsubHandler::new( + &shaper.charmap, + &lookup_list, + style, + &mut [], + &mut visited_set, + ); + gsub_handler.process_lookup(0).unwrap(); + } + + #[test] + fn visited_set() { + let count = 2341u16; + let n_bytes = (count as usize + 7) / 8; + let mut set_buf = vec![0u8; n_bytes]; + let mut set = VisitedLookupSet::new(&mut set_buf); + for i in 0..count { + assert!(set.insert(i)); + assert!(!set.insert(i)); + } + for byte in &set_buf[0..set_buf.len() - 1] { + assert_eq!(*byte, 0xFF); + } + assert_eq!(*set_buf.last().unwrap(), 0b00011111); + } + + #[derive(Default)] + struct BadLookupBuilder { + /// Just a list of nested lookup indices for each generated lookup + lookups: Vec, + } + + impl BadLookupBuilder { + fn build(&self) -> Vec { + // Full byte size of a contextual format 3 lookup with one + // subtable and one nested lookup + const CONTEXT3_FULL_SIZE: usize = 18; + let mut buf = BeBuffer::default(); + // LookupList table + // count + buf = buf.push(self.lookups.len() as u16); + // offsets for each lookup + let base_offset = 2 + 2 * self.lookups.len(); + for i in 0..self.lookups.len() { + buf = buf.push((base_offset + i * CONTEXT3_FULL_SIZE) as u16); + } + // now the actual lookups + for nested_ix in &self.lookups { + // lookup type: GSUB contextual substitution + buf = buf.push(5u16); + // lookup flag + buf = buf.push(0u16); + // subtable count + buf = buf.push(1u16); + // offset to single subtable (always 8 bytes from start of lookup) + buf = buf.push(8u16); + // start of subtable, format == 3 + buf = buf.push(3u16); + // number of glyphs in sequence + buf = buf.push(0u16); + // sequence lookup count + buf = buf.push(1u16); + // (no coverage offsets) + // sequence lookup (sequence index, lookup index) + buf = buf.push(0u16).push(*nested_ix); + } + buf.to_vec() + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,587 @@ +//! Styles, scripts and glyph style mapping. + +use super::metrics::BlueZones; +use super::shape::{ShaperCoverageKind, VisitedLookupSet}; +use alloc::vec::Vec; +use raw::types::{GlyphId, Tag}; + +/// Defines the script and style associated with a single glyph. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[repr(transparent)] +pub(super) struct GlyphStyle(pub(super) u16); + +impl GlyphStyle { + // The following flags roughly correspond to those defined in FreeType + // here: https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/autofit/afglobal.h#L76 + // but with different values because we intend to store "meta style" + // information differently. + const STYLE_INDEX_MASK: u16 = 0xFF; + const UNASSIGNED: u16 = Self::STYLE_INDEX_MASK; + // A non-base character, perhaps more commonly referred to as a "mark" + const NON_BASE: u16 = 0x100; + const DIGIT: u16 = 0x200; + // Used as intermediate state to mark when a glyph appears as GSUB output + // for a given script + const FROM_GSUB_OUTPUT: u16 = 0x8000; + + pub const fn is_unassigned(self) -> bool { + self.0 & Self::STYLE_INDEX_MASK == Self::UNASSIGNED + } + + pub const fn is_non_base(self) -> bool { + self.0 & Self::NON_BASE != 0 + } + + pub const fn is_digit(self) -> bool { + self.0 & Self::DIGIT != 0 + } + + pub fn style_class(self) -> Option<&'static StyleClass> { + StyleClass::from_index(self.style_index()?) + } + + pub fn style_index(self) -> Option { + let ix = self.0 & Self::STYLE_INDEX_MASK; + if ix != Self::UNASSIGNED { + Some(ix) + } else { + None + } + } + + fn maybe_assign(&mut self, other: Self) { + // FreeType walks the style array in order so earlier styles + // have precedence. Since we walk the cmap and binary search + // on the full range mapping, our styles are mapped in a + // different order. This check allows us to replace a currently + // mapped style if the new style index is lower which matches + // FreeType's behavior. + // + // Note that we keep the extra bits because FreeType allows + // setting the NON_BASE bit to an already mapped style. + if other.0 & Self::STYLE_INDEX_MASK <= self.0 & Self::STYLE_INDEX_MASK { + self.0 = (self.0 & !Self::STYLE_INDEX_MASK) | other.0; + } + } + + pub(super) fn set_from_gsub_output(&mut self) { + self.0 |= Self::FROM_GSUB_OUTPUT + } + + pub(super) fn clear_from_gsub(&mut self) { + self.0 &= !Self::FROM_GSUB_OUTPUT; + } + + /// Assign a style if we've been marked as GSUB output _and_ the + /// we don't currently have an assigned style. + /// + /// This also clears the GSUB output bit. + /// + /// Returns `true` if this style was applied. + pub(super) fn maybe_assign_gsub_output_style(&mut self, style: &StyleClass) -> bool { + let style_ix = style.index as u16; + if self.0 & Self::FROM_GSUB_OUTPUT != 0 && self.is_unassigned() { + self.clear_from_gsub(); + self.0 = (self.0 & !Self::STYLE_INDEX_MASK) | style_ix; + true + } else { + false + } + } +} + +impl Default for GlyphStyle { + fn default() -> Self { + Self(Self::UNASSIGNED) + } +} + +/// Sentinel for unused styles in [`GlyphStyleMap::metrics_map`]. +const UNMAPPED_STYLE: u8 = 0xFF; + +/// Maps glyph identifiers to glyph styles. +/// +/// Also keeps track of the styles that are actually used so we can allocate +/// an appropriately sized metrics array. +#[derive(Debug)] +pub(crate) struct GlyphStyleMap { + /// List of styles, indexed by glyph id. + styles: Vec, + /// Maps an actual style class index into a compacted index for the + /// metrics table. + /// + /// Uses `0xFF` to signify unused styles. + metrics_map: [u8; MAX_STYLES], + /// Number of metrics styles in use. + metrics_count: u8, +} + +impl GlyphStyleMap { + /// Computes a new glyph style map for the given glyph count and character + /// map. + /// + /// Roughly based on + pub fn new(glyph_count: u32, shaper: &Shaper) -> Self { + let lookup_count = shaper.lookup_count() as usize; + if lookup_count > 0 { + // If we're processing lookups, allocate some temporary memory to + // store the visited set + let lookup_set_byte_size = (lookup_count + 7) / 8; + super::super::memory::with_temporary_memory(lookup_set_byte_size, |bytes| { + Self::new_inner(glyph_count, shaper, VisitedLookupSet::new(bytes)) + }) + } else { + Self::new_inner(glyph_count, shaper, VisitedLookupSet::new(&mut [])) + } + } + + fn new_inner(glyph_count: u32, shaper: &Shaper, mut visited_set: VisitedLookupSet) -> Self { + let mut map = Self { + styles: vec![GlyphStyle::default(); glyph_count as usize], + metrics_map: [UNMAPPED_STYLE; MAX_STYLES], + metrics_count: 0, + }; + // Step 1: compute styles for glyphs covered by OpenType features + // See + for style in super::style::STYLE_CLASSES { + if style.feature.is_some() + && shaper.compute_coverage( + style, + ShaperCoverageKind::Script, + &mut map.styles, + &mut visited_set, + ) + { + map.use_style(style.index); + } + } + // Step 2: compute styles for glyphs contained in the cmap + // cmap entries are sorted so we keep track of the most recent range to + // avoid a binary search per character + let mut last_range: Option<(usize, StyleRange)> = None; + for (ch, gid) in shaper.charmap().mappings() { + let Some(style) = map.styles.get_mut(gid.to_u32() as usize) else { + continue; + }; + // Charmaps enumerate in order so we're likely to encounter at least + // a few codepoints in the same range. + if let Some(last) = last_range { + if last.1.contains(ch) { + style.maybe_assign(last.1.style); + continue; + } + } + let ix = match STYLE_RANGES.binary_search_by(|x| x.first.cmp(&ch)) { + Ok(i) => i, + Err(i) => i.saturating_sub(1), + }; + let Some(range) = STYLE_RANGES.get(ix).copied() else { + continue; + }; + if range.contains(ch) { + style.maybe_assign(range.style); + if let Some(style_ix) = range.style.style_index() { + map.use_style(style_ix as usize); + } + last_range = Some((ix, range)); + } + } + // Step 3a: compute script based coverage + // See + for style in super::style::STYLE_CLASSES { + if style.feature.is_none() + && shaper.compute_coverage( + style, + ShaperCoverageKind::Script, + &mut map.styles, + &mut visited_set, + ) + { + map.use_style(style.index); + } + } + // Step 3b: compute coverage for "default" script which is always set + // to Latin in FreeType + // See + let default_style = &STYLE_CLASSES[StyleClass::LATN]; + if shaper.compute_coverage( + default_style, + ShaperCoverageKind::Default, + &mut map.styles, + &mut visited_set, + ) { + map.use_style(default_style.index); + } + // Step 4: Assign a default to all remaining glyphs + // For some reason, FreeType uses Hani as a default fallback style so + // let's do the same. + // + let mut need_hani = false; + for style in map.styles.iter_mut() { + if style.is_unassigned() { + style.0 &= !GlyphStyle::STYLE_INDEX_MASK; + style.0 |= StyleClass::HANI as u16; + need_hani = true; + } + } + if need_hani { + map.use_style(StyleClass::HANI); + } + // Step 5: Mark ASCII digits + // + for digit_char in '0'..='9' { + if let Some(style) = shaper + .charmap() + .map(digit_char) + .and_then(|gid| map.styles.get_mut(gid.to_u32() as usize)) + { + style.0 |= GlyphStyle::DIGIT; + } + } + map + } + + pub fn style(&self, glyph_id: GlyphId) -> Option { + self.styles.get(glyph_id.to_u32() as usize).copied() + } + + /// Returns a compacted metrics index for the given glyph style. + pub fn metrics_index(&self, style: GlyphStyle) -> Option { + let ix = style.style_index()? as usize; + let metrics_ix = *self.metrics_map.get(ix)? as usize; + if metrics_ix != UNMAPPED_STYLE as usize { + Some(metrics_ix) + } else { + None + } + } + + /// Returns the required size of the compacted metrics array. + pub fn metrics_count(&self) -> usize { + self.metrics_count as usize + } + + /// Returns an ordered iterator yielding each style class referenced by + /// this map. + pub fn metrics_styles(&self) -> impl Iterator + '_ { + // Need to build a reverse map so that these are properly ordered + let mut reverse_map = [UNMAPPED_STYLE; MAX_STYLES]; + for (ix, &entry) in self.metrics_map.iter().enumerate() { + if entry != UNMAPPED_STYLE { + reverse_map[entry as usize] = ix as u8; + } + } + reverse_map + .into_iter() + .enumerate() + .filter_map(move |(mapped, style_ix)| { + if mapped == UNMAPPED_STYLE as usize { + None + } else { + STYLE_CLASSES.get(style_ix as usize) + } + }) + } + + fn use_style(&mut self, style_ix: usize) { + let mapped = &mut self.metrics_map[style_ix]; + if *mapped == UNMAPPED_STYLE { + // This the first time we've seen this style so record + // it in the metrics map + *mapped = self.metrics_count; + self.metrics_count += 1; + } + } +} + +impl Default for GlyphStyleMap { + fn default() -> Self { + Self { + styles: Default::default(), + metrics_map: [UNMAPPED_STYLE; MAX_STYLES], + metrics_count: 0, + } + } +} + +/// Determines which algorithms the autohinter will use while generating +/// metrics and processing a glyph outline. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub(crate) enum ScriptGroup { + /// All scripts that are not CJK or Indic. + /// + /// FreeType calls this Latin. + #[default] + Default, + Cjk, + Indic, +} + +/// Defines the basic properties for each script supported by the +/// autohinter. +#[derive(Clone, Debug)] +pub(crate) struct ScriptClass { + #[allow(unused)] + pub name: &'static str, + /// Group that defines how glyphs belonging to this script are hinted. + pub group: ScriptGroup, + /// Unicode tag for the script. + #[allow(unused)] + pub tag: Tag, + /// True if outline edges are processed top to bottom. + pub hint_top_to_bottom: bool, + /// Characters used to define standard width and height of stems. + pub std_chars: &'static str, + /// "Blue" characters used to define alignment zones. + pub blues: &'static [(&'static str, BlueZones)], +} + +/// Defines the basic properties for each style supported by the +/// autohinter. +/// +/// There's mostly a 1:1 correspondence between styles and scripts except +/// in the cases where style coverage is determined by OpenType feature +/// coverage. +#[derive(Clone, Debug)] +pub(crate) struct StyleClass { + #[allow(unused)] + pub name: &'static str, + /// Index of self in the STYLE_CLASSES array. + pub index: usize, + /// Associated Unicode script. + pub script: &'static ScriptClass, + /// OpenType feature tag for styles that derive coverage from layout + /// tables. + #[allow(unused)] + pub feature: Option, +} + +impl StyleClass { + pub(crate) fn from_index(index: u16) -> Option<&'static StyleClass> { + STYLE_CLASSES.get(index as usize) + } +} + +/// Associates a basic glyph style with a range of codepoints. +#[derive(Copy, Clone, Debug)] +pub(super) struct StyleRange { + pub first: u32, + pub last: u32, + pub style: GlyphStyle, +} + +impl StyleRange { + pub fn contains(&self, ch: u32) -> bool { + (self.first..=self.last).contains(&ch) + } +} + +// The following are helpers for generated code. +const fn base_range(first: u32, last: u32, style_index: u16) -> StyleRange { + StyleRange { + first, + last, + style: GlyphStyle(style_index), + } +} + +const fn non_base_range(first: u32, last: u32, style_index: u16) -> StyleRange { + StyleRange { + first, + last, + style: GlyphStyle(style_index | GlyphStyle::NON_BASE), + } +} + +const MAX_STYLES: usize = STYLE_CLASSES.len(); + +use super::shape::Shaper; + +include!("../../../generated/generated_autohint_styles.rs"); + +#[cfg(test)] +mod tests { + use super::{super::shape::ShaperMode, *}; + use crate::{raw::TableProvider, FontRef, MetadataProvider}; + + /// Ensure that style mapping accurately applies the DIGIT bit to + /// ASCII digit glyphs. + #[test] + fn capture_digit_styles() { + let font = FontRef::new(font_test_data::AHEM).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let num_glyphs = font.maxp().unwrap().num_glyphs() as u32; + let style_map = GlyphStyleMap::new(num_glyphs, &shaper); + let charmap = font.charmap(); + let mut digit_count = 0; + for (ch, gid) in charmap.mappings() { + let style = style_map.style(gid).unwrap(); + let is_char_digit = char::from_u32(ch).unwrap().is_ascii_digit(); + assert_eq!(style.is_digit(), is_char_digit); + digit_count += is_char_digit as u32; + } + // This font has all 10 ASCII digits + assert_eq!(digit_count, 10); + } + + #[test] + fn glyph_styles() { + // generated by printf debugging in FreeType + // (gid, Option<(script_name, is_non_base_char)>) + // where "is_non_base_char" more common means "is_mark" + let expected = &[ + (0, Some(("CJKV ideographs", false))), + (1, Some(("Latin", true))), + (2, Some(("Armenian", true))), + (3, Some(("Hebrew", true))), + (4, Some(("Arabic", false))), + (5, Some(("Arabic", false))), + (6, Some(("Arabic", true))), + (7, Some(("Devanagari", true))), + (8, Some(("Devanagari", false))), + (9, Some(("Bengali", true))), + (10, Some(("Bengali", false))), + (11, Some(("Gurmukhi", true))), + (12, Some(("Gurmukhi", false))), + (13, Some(("Gujarati", true))), + (14, Some(("Gujarati", true))), + (15, Some(("Oriya", true))), + (16, Some(("Oriya", false))), + (17, Some(("Tamil", true))), + (18, Some(("Tamil", false))), + (19, Some(("Telugu", true))), + (20, Some(("Telugu", false))), + (21, Some(("Kannada", true))), + (22, Some(("Kannada", false))), + (23, Some(("Malayalam", true))), + (24, Some(("Malayalam", false))), + (25, Some(("Sinhala", true))), + (26, Some(("Sinhala", false))), + (27, Some(("Thai", true))), + (28, Some(("Thai", false))), + (29, Some(("Lao", true))), + (30, Some(("Lao", false))), + (31, Some(("Tibetan", true))), + (32, Some(("Tibetan", false))), + (33, Some(("Myanmar", true))), + (34, Some(("Ethiopic", true))), + (35, Some(("Buhid", true))), + (36, Some(("Buhid", false))), + (37, Some(("Khmer", true))), + (38, Some(("Khmer", false))), + (39, Some(("Mongolian", true))), + (40, Some(("Canadian Syllabics", false))), + (41, Some(("Limbu", true))), + (42, Some(("Limbu", false))), + (43, Some(("Khmer Symbols", false))), + (44, Some(("Sundanese", true))), + (45, Some(("Ol Chiki", false))), + (46, Some(("Georgian (Mkhedruli)", false))), + (47, Some(("Sundanese", false))), + (48, Some(("Latin Superscript Fallback", false))), + (49, Some(("Latin", true))), + (50, Some(("Greek", true))), + (51, Some(("Greek", false))), + (52, Some(("Latin Subscript Fallback", false))), + (53, Some(("Coptic", true))), + (54, Some(("Coptic", false))), + (55, Some(("Georgian (Khutsuri)", false))), + (56, Some(("Tifinagh", false))), + (57, Some(("Ethiopic", false))), + (58, Some(("Cyrillic", true))), + (59, Some(("CJKV ideographs", true))), + (60, Some(("CJKV ideographs", false))), + (61, Some(("Lisu", false))), + (62, Some(("Vai", false))), + (63, Some(("Cyrillic", true))), + (64, Some(("Bamum", true))), + (65, Some(("Syloti Nagri", true))), + (66, Some(("Syloti Nagri", false))), + (67, Some(("Saurashtra", true))), + (68, Some(("Saurashtra", false))), + (69, Some(("Kayah Li", true))), + (70, Some(("Kayah Li", false))), + (71, Some(("Myanmar", false))), + (72, Some(("Tai Viet", true))), + (73, Some(("Tai Viet", false))), + (74, Some(("Cherokee", false))), + (75, Some(("Armenian", false))), + (76, Some(("Hebrew", false))), + (77, Some(("Arabic", false))), + (78, Some(("Carian", false))), + (79, Some(("Gothic", false))), + (80, Some(("Deseret", false))), + (81, Some(("Shavian", false))), + (82, Some(("Osmanya", false))), + (83, Some(("Osage", false))), + (84, Some(("Cypriot", false))), + (85, Some(("Avestan", true))), + (86, Some(("Avestan", true))), + (87, Some(("Old Turkic", false))), + (88, Some(("Hanifi Rohingya", false))), + (89, Some(("Chakma", true))), + (90, Some(("Chakma", false))), + (91, Some(("Mongolian", false))), + (92, Some(("CJKV ideographs", false))), + (93, Some(("Medefaidrin", false))), + (94, Some(("Glagolitic", true))), + (95, Some(("Glagolitic", true))), + (96, Some(("Adlam", true))), + (97, Some(("Adlam", false))), + ]; + check_styles(font_test_data::AUTOHINT_CMAP, ShaperMode::Nominal, expected); + } + + #[test] + fn shaped_glyph_styles() { + // generated by printf debugging in FreeType + // (gid, Option<(script_name, is_non_base_char)>) + // where "is_non_base_char" more common means "is_mark" + let expected = &[ + (0, Some(("CJKV ideographs", false))), + (1, Some(("Latin", false))), + (2, Some(("Latin", false))), + (3, Some(("Latin", false))), + (4, Some(("Latin", false))), + // Note: ligatures starting with 'f' are assigned the Cyrillic + // script which matches FreeType + (5, Some(("Cyrillic", false))), + (6, Some(("Cyrillic", false))), + (7, Some(("Cyrillic", false))), + // Capture the Latin c2sc feature + (8, Some(("Latin small capitals from capitals", false))), + ]; + check_styles( + font_test_data::NOTOSERIF_AUTOHINT_SHAPING, + ShaperMode::BestEffort, + expected, + ); + } + + fn check_styles(font_data: &[u8], mode: ShaperMode, expected: &[(u32, Option<(&str, bool)>)]) { + let font = FontRef::new(font_data).unwrap(); + let shaper = Shaper::new(&font, mode); + let num_glyphs = font.maxp().unwrap().num_glyphs() as u32; + let style_map = GlyphStyleMap::new(num_glyphs, &shaper); + let results = style_map + .styles + .iter() + .enumerate() + .map(|(gid, style)| { + ( + gid as u32, + style + .style_class() + .map(|style_class| (style_class.name, style.is_non_base())), + ) + }) + .collect::>(); + for (i, result) in results.iter().enumerate() { + assert_eq!(result, &expected[i]); + } + // Ensure each style has a remapped metrics index + for style in &style_map.styles { + style_map.metrics_index(*style).unwrap(); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,823 @@ +//! Edge detection. +//! +//! Edges are sets of segments that all lie within a threshold based on +//! stem widths. +//! +//! Here we compute edges from the segment list, assign properties (round, +//! serif, links) and then associate them with blue zones. + +use super::{ + super::{ + metrics::{fixed_div, fixed_mul, Scale, ScaledAxisMetrics, ScaledBlue, UnscaledBlue}, + outline::Direction, + style::ScriptGroup, + }, + Axis, Edge, Segment, +}; + +/// Links segments to edges, using feature analysis for selection. +/// +/// See +pub(crate) fn compute_edges( + axis: &mut Axis, + metrics: &ScaledAxisMetrics, + top_to_bottom_hinting: bool, + y_scale: i32, + group: ScriptGroup, +) { + axis.edges.clear(); + let scale = metrics.scale; + // This is always passed as 0 in functions that take hinting direction + // in CJK + // See + let top_to_bottom_hinting = if axis.dim == Axis::HORIZONTAL || group != ScriptGroup::Default { + false + } else { + top_to_bottom_hinting + }; + // Ignore horizontal segments less than 1 pixel in length + let segment_length_threshold = if axis.dim == Axis::HORIZONTAL { + fixed_div(64, y_scale) + } else { + 0 + }; + // Also ignore segments with a width delta larger than 0.5 pixels + let segment_width_threshold = fixed_div(32, scale); + // Ensure that edge distance threshold is less than or equal to + // 0.25 pixels + let initial_threshold = metrics.width_metrics.edge_distance_threshold; + const EDGE_DISTANCE_THRESHOLD_MAX: i32 = 64 / 4; + let edge_distance_threshold = if group == ScriptGroup::Default { + fixed_div( + fixed_mul(initial_threshold, scale).min(EDGE_DISTANCE_THRESHOLD_MAX), + scale, + ) + } else { + // CJK uses a slightly different computation here + // See + let threshold = fixed_mul(initial_threshold, scale); + if threshold > EDGE_DISTANCE_THRESHOLD_MAX { + fixed_div(EDGE_DISTANCE_THRESHOLD_MAX, scale) + } else { + initial_threshold + } + }; + // Now build the sorted table of edges by looping over all segments + // to find a matching edge, adding a new one if not found. + // We can't iterate segments because we make mutable calls on `axis` + // below which causes overlapping borrows + for segment_ix in 0..axis.segments.len() { + let segment = &axis.segments[segment_ix]; + if group == ScriptGroup::Default { + // Ignore segments that are too short, too wide or direction-less + if (segment.height as i32) < segment_length_threshold + || (segment.delta as i32 > segment_width_threshold) + || segment.dir == Direction::None + { + continue; + } + // Ignore serif edges that are smaller than 1.5 pixels + if segment.serif_ix.is_some() + && (2 * segment.height as i32) < (3 * segment_length_threshold) + { + continue; + } + } + // Look for a corresponding edge for this segment + let mut best_dist = i32::MAX; + let mut best_edge_ix = None; + for edge_ix in 0..axis.edges.len() { + let edge = &axis.edges[edge_ix]; + let dist = (segment.pos as i32 - edge.fpos as i32).abs(); + if dist < edge_distance_threshold && edge.dir == segment.dir && dist < best_dist { + if group == ScriptGroup::Default { + best_edge_ix = Some(edge_ix); + break; + } + // For CJK, we add some additional checks + // See + if let Some(link) = segment.link(&axis.segments).copied() { + // Check whether all linked segments of the candidate edge + // can make a single edge + let first_ix = edge.first_ix as usize; + let mut seg1 = &axis.segments[first_ix]; + let mut dist2 = 0; + loop { + if let Some(link1) = seg1.link(&axis.segments).copied() { + dist2 = (link.pos as i32 - link1.pos as i32).abs(); + if dist2 >= edge_distance_threshold { + break; + } + } + if seg1.edge_next_ix == Some(first_ix as u16) { + break; + } + if let Some(next) = seg1.next_in_edge(&axis.segments) { + seg1 = next; + } else { + break; + } + } + if dist2 >= edge_distance_threshold { + continue; + } + } + best_dist = dist; + best_edge_ix = Some(edge_ix); + } + } + if let Some(edge_ix) = best_edge_ix { + axis.append_segment_to_edge(segment_ix, edge_ix); + } else { + // We couldn't find an edge, so add a new one for this segment + let opos = fixed_mul(segment.pos as i32, scale); + let edge = Edge { + fpos: segment.pos, + opos, + pos: opos, + dir: segment.dir, + first_ix: segment_ix as u16, + last_ix: segment_ix as u16, + ..Default::default() + }; + axis.insert_edge(edge, top_to_bottom_hinting); + axis.segments[segment_ix].edge_next_ix = Some(segment_ix as u16); + } + } + if group == ScriptGroup::Default { + // Loop again to find single point segments without a direction and + // associate them with an existing edge if possible + for segment_ix in 0..axis.segments.len() { + let segment = &axis.segments[segment_ix]; + if segment.dir != Direction::None { + continue; + } + // Try to find an edge that coincides with this segment within the + // threshold + if let Some(edge_ix) = axis + .edges + .iter() + .enumerate() + .filter_map(|(ix, edge)| { + ((segment.pos as i32 - edge.fpos as i32).abs() < edge_distance_threshold) + .then_some(ix) + }) + .next() + { + // We found an edge, link everything up + axis.append_segment_to_edge(segment_ix, edge_ix); + } + } + } + link_segments_to_edges(axis); + compute_edge_properties(axis); +} + +/// Edges get reordered as they're built so we need to assign edge indices to +/// segments in a second pass. +fn link_segments_to_edges(axis: &mut Axis) { + let segments = axis.segments.as_mut_slice(); + for edge_ix in 0..axis.edges.len() { + let edge = &axis.edges[edge_ix]; + let mut ix = edge.first_ix as usize; + let last_ix = edge.last_ix as usize; + loop { + let segment = &mut segments[ix]; + segment.edge_ix = Some(edge_ix as u16); + if ix == last_ix { + break; + } + ix = segment + .edge_next_ix + .map(|ix| ix as usize) + .unwrap_or(last_ix); + } + } +} + +/// Compute the edge properties based on the series of segments that make +/// up the edge. +/// +/// See +fn compute_edge_properties(axis: &mut Axis) { + let edges = axis.edges.as_mut_slice(); + let segments = axis.segments.as_slice(); + for edge_ix in 0..edges.len() { + let mut roundness = 0; + let mut straightness = 0; + let edge = edges[edge_ix]; + let mut segment_ix = edge.first_ix as usize; + let last_segment_ix = edge.last_ix as usize; + loop { + // This loop can modify the current edge, so make sure we + // reload it here + let edge = edges[edge_ix]; + let segment = &segments[segment_ix]; + let next_segment_ix = segment.edge_next_ix; + // Check roundness + if segment.flags & Segment::ROUND != 0 { + roundness += 1; + } else { + straightness += 1; + } + // Check for serifs + let is_serif = if let Some(serif_ix) = segment.serif_ix { + let serif = &segments[serif_ix as usize]; + serif.edge_ix.is_some() && serif.edge_ix != Some(edge_ix as u16) + } else { + false + }; + // Check for links + if is_serif + || (segment.link_ix.is_some() + && segments[segment.link_ix.unwrap() as usize] + .edge_ix + .is_some()) + { + let (edge2_ix, segment2_ix) = if is_serif { + (edge.serif_ix, segment.serif_ix) + } else { + (edge.link_ix, segment.link_ix) + }; + let edge2_ix = if let (Some(edge2_ix), Some(segment2_ix)) = (edge2_ix, segment2_ix) + { + let edge2 = &edges[edge2_ix as usize]; + let edge_delta = (edge.fpos as i32 - edge2.fpos as i32).abs(); + let segment2 = &segments[segment2_ix as usize]; + let segment_delta = (segment.pos as i32 - segment2.pos as i32).abs(); + if segment_delta < edge_delta { + segment2.edge_ix + } else { + Some(edge2_ix) + } + } else if let Some(segment2_ix) = segment2_ix { + segments[segment2_ix as usize].edge_ix + } else { + edge2_ix + }; + if is_serif { + edges[edge_ix].serif_ix = edge2_ix; + edges[edge2_ix.unwrap() as usize].flags |= Edge::SERIF; + } else { + edges[edge_ix].link_ix = edge2_ix; + } + } + if segment_ix == last_segment_ix { + break; + } + segment_ix = next_segment_ix + .map(|ix| ix as usize) + .unwrap_or(last_segment_ix); + } + let edge = &mut edges[edge_ix]; + edge.flags = Edge::NORMAL; + if roundness > 0 && roundness >= straightness { + edge.flags |= Edge::ROUND; + } + // Drop serifs for linked edges + if edge.serif_ix.is_some() && edge.link_ix.is_some() { + edge.serif_ix = None; + } + } +} + +/// Compute all edges which lie within blue zones. +/// +/// For Latin, this is only done for the vertical axis. +/// +/// See +pub(crate) fn compute_blue_edges( + axis: &mut Axis, + scale: &Scale, + unscaled_blues: &[UnscaledBlue], + blues: &[ScaledBlue], + group: ScriptGroup, +) { + // For the default script group, don't compute blues in the horizontal + // direction + // See + if axis.dim != Axis::VERTICAL && group == ScriptGroup::Default { + return; + } + let axis_scale = if axis.dim == Axis::HORIZONTAL { + scale.x_scale + } else { + scale.y_scale + }; + // Initial threshold + let initial_best_dest = fixed_mul(scale.units_per_em / 40, axis_scale).min(64 / 2); + for edge in &mut axis.edges { + let mut best_blue = None; + let mut best_is_neutral = false; + // Initial threshold as a fraction of em size with a max distance + // of 0.5 pixels + let mut best_dist = initial_best_dest; + for (unscaled_blue, blue) in unscaled_blues.iter().zip(blues) { + // Ignore inactive blue zones + if !blue.is_active { + continue; + } + let is_top = blue.zones.is_top_like(); + let is_neutral = blue.zones.is_neutral(); + let is_major_dir = edge.dir == axis.major_dir; + // Both directions are handled for neutral blues + if is_top ^ is_major_dir || is_neutral { + // Compare to reference position + let (ref_pos, matching_blue) = if group == ScriptGroup::Default { + (unscaled_blue.position, blue.position) + } else { + // For CJK, we take the blue with the smallest delta + // from the edge + // See + if (edge.fpos as i32 - unscaled_blue.position).abs() + > (edge.fpos as i32 - unscaled_blue.overshoot).abs() + { + (unscaled_blue.overshoot, blue.overshoot) + } else { + (unscaled_blue.position, blue.position) + } + }; + let dist = fixed_mul((edge.fpos as i32 - ref_pos).abs(), axis_scale); + if dist < best_dist { + best_dist = dist; + best_blue = Some(matching_blue); + best_is_neutral = is_neutral; + } + if group == ScriptGroup::Default { + // Now compare to overshoot position for the default script + // group + // See + if edge.flags & Edge::ROUND != 0 && dist != 0 && !is_neutral { + let is_under_ref = (edge.fpos as i32) < unscaled_blue.position; + if is_top ^ is_under_ref { + let dist = fixed_mul( + (edge.fpos as i32 - unscaled_blue.overshoot).abs(), + axis_scale, + ); + if dist < best_dist { + best_dist = dist; + best_blue = Some(blue.overshoot); + best_is_neutral = is_neutral; + } + } + } + } + } + } + if let Some(best_blue) = best_blue { + edge.blue_edge = Some(best_blue); + if best_is_neutral { + edge.flags |= Edge::NEUTRAL; + } + } + } +} + +#[cfg(test)] +mod tests { + use super::{ + super::super::{ + metrics::{self, ScaledWidth}, + outline::Outline, + shape::{Shaper, ShaperMode}, + style, + }, + super::segments, + *, + }; + use crate::{attribute::Style, MetadataProvider}; + use raw::{types::GlyphId, FontRef, TableProvider}; + + #[test] + fn edges_default() { + let expected_h_edges = [ + Edge { + fpos: 15, + opos: 15, + pos: 15, + flags: Edge::ROUND, + dir: Direction::Up, + blue_edge: None, + link_ix: Some(3), + serif_ix: None, + scale: 0, + first_ix: 1, + last_ix: 1, + }, + Edge { + fpos: 123, + opos: 126, + pos: 126, + flags: 0, + dir: Direction::Up, + blue_edge: None, + link_ix: Some(2), + serif_ix: None, + scale: 0, + first_ix: 0, + last_ix: 0, + }, + Edge { + fpos: 186, + opos: 190, + pos: 190, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: Some(1), + serif_ix: None, + scale: 0, + first_ix: 4, + last_ix: 4, + }, + Edge { + fpos: 205, + opos: 210, + pos: 210, + flags: Edge::ROUND, + dir: Direction::Down, + blue_edge: None, + link_ix: Some(0), + serif_ix: None, + scale: 0, + first_ix: 3, + last_ix: 3, + }, + ]; + let expected_v_edges = [ + Edge { + fpos: -240, + opos: -246, + pos: -246, + flags: 0, + dir: Direction::Left, + blue_edge: Some(ScaledWidth { + scaled: -246, + fitted: -256, + }), + link_ix: None, + serif_ix: Some(1), + scale: 0, + first_ix: 3, + last_ix: 3, + }, + Edge { + fpos: 481, + opos: 493, + pos: 493, + flags: 0, + dir: Direction::Left, + blue_edge: None, + link_ix: Some(2), + serif_ix: None, + scale: 0, + first_ix: 0, + last_ix: 0, + }, + Edge { + fpos: 592, + opos: 606, + pos: 606, + flags: Edge::ROUND | Edge::SERIF, + dir: Direction::Right, + blue_edge: Some(ScaledWidth { + scaled: 606, + fitted: 576, + }), + link_ix: Some(1), + serif_ix: None, + scale: 0, + first_ix: 2, + last_ix: 2, + }, + Edge { + fpos: 647, + opos: 663, + pos: 663, + flags: 0, + dir: Direction::Right, + blue_edge: None, + link_ix: None, + serif_ix: Some(2), + scale: 0, + first_ix: 1, + last_ix: 1, + }, + ]; + check_edges( + font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS, + GlyphId::new(9), + style::StyleClass::HEBR, + &expected_h_edges, + &expected_v_edges, + ); + } + + #[test] + fn edges_cjk() { + let expected_h_edges = [ + Edge { + fpos: 138, + opos: 141, + pos: 141, + flags: 0, + dir: Direction::Up, + blue_edge: None, + link_ix: Some(1), + serif_ix: None, + scale: 0, + first_ix: 8, + last_ix: 8, + }, + Edge { + fpos: 201, + opos: 206, + pos: 206, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: Some(0), + serif_ix: None, + scale: 0, + first_ix: 7, + last_ix: 7, + }, + Edge { + fpos: 458, + opos: 469, + pos: 469, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 2, + last_ix: 2, + }, + Edge { + fpos: 569, + opos: 583, + pos: 583, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 6, + last_ix: 6, + }, + Edge { + fpos: 670, + opos: 686, + pos: 686, + flags: 0, + dir: Direction::Up, + blue_edge: None, + link_ix: Some(6), + serif_ix: None, + scale: 0, + first_ix: 1, + last_ix: 1, + }, + Edge { + fpos: 693, + opos: 710, + pos: 710, + flags: 0, + dir: Direction::Up, + blue_edge: None, + link_ix: None, + serif_ix: Some(7), + scale: 0, + first_ix: 4, + last_ix: 4, + }, + Edge { + fpos: 731, + opos: 749, + pos: 749, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: Some(4), + serif_ix: None, + scale: 0, + first_ix: 0, + last_ix: 0, + }, + Edge { + fpos: 849, + opos: 869, + pos: 869, + flags: 0, + dir: Direction::Up, + blue_edge: None, + link_ix: Some(8), + serif_ix: None, + scale: 0, + first_ix: 5, + last_ix: 5, + }, + Edge { + fpos: 911, + opos: 933, + pos: 933, + flags: 0, + dir: Direction::Down, + blue_edge: None, + link_ix: Some(7), + serif_ix: None, + scale: 0, + first_ix: 3, + last_ix: 3, + }, + ]; + let expected_v_edges = [ + Edge { + fpos: -78, + opos: -80, + pos: -80, + flags: Edge::ROUND, + dir: Direction::Left, + blue_edge: Some(ScaledWidth { + scaled: -80, + fitted: -64, + }), + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 8, + last_ix: 8, + }, + Edge { + fpos: 3, + opos: 3, + pos: 3, + flags: Edge::ROUND, + dir: Direction::Right, + blue_edge: None, + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 4, + last_ix: 4, + }, + Edge { + fpos: 133, + opos: 136, + pos: 136, + flags: Edge::ROUND, + dir: Direction::Left, + blue_edge: None, + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 2, + last_ix: 2, + }, + Edge { + fpos: 547, + opos: 560, + pos: 560, + flags: 0, + dir: Direction::Left, + blue_edge: None, + link_ix: None, + serif_ix: Some(5), + scale: 0, + first_ix: 6, + last_ix: 6, + }, + Edge { + fpos: 576, + opos: 590, + pos: 590, + flags: 0, + dir: Direction::Right, + blue_edge: None, + link_ix: Some(5), + serif_ix: None, + scale: 0, + first_ix: 5, + last_ix: 5, + }, + Edge { + fpos: 576, + opos: 590, + pos: 590, + flags: 0, + dir: Direction::Left, + blue_edge: None, + link_ix: Some(4), + serif_ix: None, + scale: 0, + first_ix: 7, + last_ix: 7, + }, + Edge { + fpos: 729, + opos: 746, + pos: 746, + flags: 0, + dir: Direction::Left, + blue_edge: None, + link_ix: Some(7), + serif_ix: None, + scale: 0, + first_ix: 1, + last_ix: 1, + }, + Edge { + fpos: 758, + opos: 776, + pos: 776, + flags: 0, + dir: Direction::Right, + blue_edge: None, + link_ix: Some(6), + serif_ix: None, + scale: 0, + first_ix: 0, + last_ix: 3, + }, + Edge { + fpos: 788, + opos: 807, + pos: 807, + flags: Edge::ROUND, + dir: Direction::Left, + blue_edge: None, + link_ix: None, + serif_ix: None, + scale: 0, + first_ix: 9, + last_ix: 9, + }, + ]; + check_edges( + font_test_data::NOTOSERIFTC_AUTOHINT_METRICS, + GlyphId::new(9), + style::StyleClass::HANI, + &expected_h_edges, + &expected_v_edges, + ); + } + + fn check_edges( + font_data: &[u8], + glyph_id: GlyphId, + style_class: usize, + expected_h_edges: &[Edge], + expected_v_edges: &[Edge], + ) { + let font = FontRef::new(font_data).unwrap(); + let shaper = Shaper::new(&font, ShaperMode::Nominal); + let class = &style::STYLE_CLASSES[style_class]; + let unscaled_metrics = + metrics::compute_unscaled_style_metrics(&shaper, Default::default(), class); + let scale = metrics::Scale::new( + 16.0, + font.head().unwrap().units_per_em() as i32, + Style::Normal, + Default::default(), + class.script.group, + ); + let scaled_metrics = metrics::scale_style_metrics(&unscaled_metrics, scale); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(glyph_id).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axes = [ + Axis::new(Axis::HORIZONTAL, outline.orientation), + Axis::new(Axis::VERTICAL, outline.orientation), + ]; + for (dim, axis) in axes.iter_mut().enumerate() { + segments::compute_segments(&mut outline, axis, class.script.group); + segments::link_segments( + &outline, + axis, + scaled_metrics.axes[dim].scale, + class.script.group, + unscaled_metrics.axes[dim].max_width(), + ); + compute_edges( + axis, + &scaled_metrics.axes[dim], + class.script.hint_top_to_bottom, + scaled_metrics.axes[1].scale, + class.script.group, + ); + compute_blue_edges( + axis, + &scale, + &unscaled_metrics.axes[dim].blues, + &scaled_metrics.axes[dim].blues, + class.script.group, + ); + } + assert_eq!(axes[Axis::HORIZONTAL].edges.as_slice(), expected_h_edges); + assert_eq!(axes[Axis::VERTICAL].edges.as_slice(), expected_v_edges); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,246 @@ +//! Topology analysis of segments and edges. + +mod edges; +mod segments; + +use super::{ + metrics::ScaledWidth, + outline::{Direction, Orientation, Point}, +}; +use crate::collections::SmallVec; + +pub(crate) use edges::{compute_blue_edges, compute_edges}; +pub(crate) use segments::{compute_segments, link_segments}; + +/// Maximum number of segments and edges stored inline. +/// +/// See +const MAX_INLINE_SEGMENTS: usize = 18; +const MAX_INLINE_EDGES: usize = 12; + +/// Either horizontal or vertical. +/// +/// A type alias because it's used as an index. +pub type Dimension = usize; + +/// Segments and edges for one dimension of an outline. +/// +/// See +#[derive(Clone, Default, Debug)] +pub struct Axis { + /// Either horizontal or vertical. + pub dim: Dimension, + /// Depends on dimension and outline orientation. + pub major_dir: Direction, + /// Collection of segments for the axis. + pub segments: SmallVec, + /// Collection of edges for the axis. + pub edges: SmallVec, +} + +impl Axis { + /// X coordinates, i.e. vertical segments and edges. + pub const HORIZONTAL: Dimension = 0; + /// Y coordinates, i.e. horizontal segments and edges. + pub const VERTICAL: Dimension = 1; +} + +impl Axis { + #[cfg(test)] + pub fn new(dim: Dimension, orientation: Option) -> Self { + let mut axis = Self::default(); + axis.reset(dim, orientation); + axis + } + + pub fn reset(&mut self, dim: Dimension, orientation: Option) { + self.dim = dim; + self.major_dir = match (dim, orientation) { + (Self::HORIZONTAL, Some(Orientation::Clockwise)) => Direction::Down, + (Self::VERTICAL, Some(Orientation::Clockwise)) => Direction::Right, + (Self::HORIZONTAL, _) => Direction::Up, + (Self::VERTICAL, _) => Direction::Left, + _ => Direction::None, + }; + self.segments.clear(); + self.edges.clear(); + } +} + +impl Axis { + /// Inserts the given edge into the sorted edge list. + /// + /// See + pub fn insert_edge(&mut self, edge: Edge, top_to_bottom_hinting: bool) { + self.edges.push(edge); + let edges = self.edges.as_mut_slice(); + // If this is the first edge, we're done. + if edges.len() == 1 { + return; + } + // Now move it into place + let mut ix = edges.len() - 1; + while ix > 0 { + let prev_ix = ix - 1; + let prev_fpos = edges[prev_ix].fpos; + if (top_to_bottom_hinting && prev_fpos > edge.fpos) + || (!top_to_bottom_hinting && prev_fpos < edge.fpos) + { + break; + } + // Edges with the same position and minor direction should appear + // before those with the major direction + if prev_fpos == edge.fpos && edge.dir == self.major_dir { + break; + } + let prev_edge = edges[prev_ix]; + edges[ix] = prev_edge; + ix -= 1; + } + edges[ix] = edge; + } + + /// Links the given segment and edge. + pub fn append_segment_to_edge(&mut self, segment_ix: usize, edge_ix: usize) { + let edge = &mut self.edges[edge_ix]; + let first_ix = edge.first_ix; + let last_ix = edge.last_ix; + edge.last_ix = segment_ix as u16; + let segment = &mut self.segments[segment_ix]; + segment.edge_next_ix = Some(first_ix); + self.segments[last_ix as usize].edge_next_ix = Some(segment_ix as u16); + } +} + +/// Sequence of points with a single dominant direction. +/// +/// See +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] +pub(crate) struct Segment { + /// Flags describing the properties of the segment. + pub flags: u8, + /// Dominant direction of the segment. + pub dir: Direction, + /// Position of the segment. + pub pos: i16, + /// Deviation from segment position. + pub delta: i16, + /// Minimum coordinate of the segment. + pub min_coord: i16, + /// Maximum coordinate of the segment. + pub max_coord: i16, + /// Hinted segment height. + pub height: i16, + /// Used during stem matching. + pub score: i32, + /// Used during stem matching. + pub len: i32, + /// Index of best candidate for a stem link. + pub link_ix: Option, + /// Index of best candidate for a serif link. + pub serif_ix: Option, + /// Index of first point in the outline. + pub first_ix: u16, + /// Index of last point in the outline. + pub last_ix: u16, + /// Index of edge that is associated with the segment. + pub edge_ix: Option, + /// Index of next segment in edge's segment list. + pub edge_next_ix: Option, +} + +/// Segment flags. +/// +/// Note: these are the same as edge flags. +/// +/// See +impl Segment { + pub const NORMAL: u8 = 0; + pub const ROUND: u8 = 1; + pub const SERIF: u8 = 2; + pub const DONE: u8 = 4; + pub const NEUTRAL: u8 = 8; +} + +impl Segment { + pub fn first(&self) -> usize { + self.first_ix as usize + } + + pub fn first_point<'a>(&self, points: &'a [Point]) -> &'a Point { + &points[self.first()] + } + + pub fn last(&self) -> usize { + self.last_ix as usize + } + + pub fn last_point<'a>(&self, points: &'a [Point]) -> &'a Point { + &points[self.last()] + } + + pub fn edge<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { + edges.get(self.edge_ix.map(|ix| ix as usize)?) + } + + /// Returns the next segment in this segment's parent edge. + pub fn next_in_edge<'a>(&self, segments: &'a [Segment]) -> Option<&'a Segment> { + segments.get(self.edge_next_ix.map(|ix| ix as usize)?) + } + + pub fn link<'a>(&self, segments: &'a [Segment]) -> Option<&'a Segment> { + segments.get(self.link_ix.map(|ix| ix as usize)?) + } +} + +/// Sequence of segments used for grid-fitting. +/// +/// See +#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)] +pub(crate) struct Edge { + /// Original, unscaled position in font units. + pub fpos: i16, + /// Original, scaled position. + pub opos: i32, + /// Current position. + pub pos: i32, + /// Edge flags. + pub flags: u8, + /// Edge direction. + pub dir: Direction, + /// Present if this is a blue edge. + pub blue_edge: Option, + /// Index of linked edge. + pub link_ix: Option, + /// Index of primary edge for serif. + pub serif_ix: Option, + /// Used to speed up edge interpolation. + pub scale: i32, + /// Index of first segment in edge. + pub first_ix: u16, + /// Index of last segment in edge. + pub last_ix: u16, +} + +/// Edge flags. +/// +/// Note: these are the same as segment flags. +/// +/// See +impl Edge { + pub const NORMAL: u8 = Segment::NORMAL; + pub const ROUND: u8 = Segment::ROUND; + pub const SERIF: u8 = Segment::SERIF; + pub const DONE: u8 = Segment::DONE; + pub const NEUTRAL: u8 = Segment::NEUTRAL; +} + +impl Edge { + pub fn link<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { + edges.get(self.link_ix.map(|ix| ix as usize)?) + } + + pub fn serif<'a>(&self, edges: &'a [Edge]) -> Option<&'a Edge> { + edges.get(self.serif_ix.map(|ix| ix as usize)?) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1071 @@ +//! Segment computation and linking. +//! +//! A segment is a series of at least two consecutive points that are +//! appropriately aligned along a coordinate axis. +//! +//! The linking stage associates pairs of segments to form stems and +//! identifies serifs with a post-process pass. + +use super::super::{ + derived_constant, + metrics::fixed_div, + outline::Outline, + style::ScriptGroup, + topo::{Axis, Dimension, Segment}, +}; +use raw::tables::glyf::PointFlags; + +// Bounds for score, position and coordinate values. +// See +const MAX_SCORE: i32 = 32000; +const MIN_SCORE: i32 = -32000; + +/// Computes segments for the Latin writing system. +/// +/// See +pub(crate) fn compute_segments( + outline: &mut Outline, + axis: &mut Axis, + _group: ScriptGroup, +) -> bool { + assign_point_uvs(outline, axis.dim); + if !build_segments(outline, axis) { + return false; + } + adjust_segment_heights(outline, axis); + // This is never actually executed due to a bug in FreeType + // See point 2 at + // if group != ScriptGroup::Default { + // _detect_round_segments_cjk(outline, axis); + // } + true +} + +/// Link segments to form stems and serifs. +/// +/// If `max_width` is provided, use it to refine the scoring function. +/// +/// See +pub(crate) fn link_segments( + outline: &Outline, + axis: &mut Axis, + scale: i32, + group: ScriptGroup, + max_width: Option, +) { + if group == ScriptGroup::Default { + link_segments_default(outline, axis, max_width); + } else { + link_segments_cjk(outline, axis, scale) + } +} + +/// Link segments to form stems and serifs. +/// +/// If `max_width` is provided, use it to refine the scoring function. +/// +/// See +fn link_segments_default(outline: &Outline, axis: &mut Axis, max_width: Option) { + let max_width = max_width.unwrap_or_default(); + // Heuristic value to set up a minimum for overlapping + let len_threshold = derived_constant(outline.units_per_em, 8).max(1); + // Heuristic value to weight lengths + let len_score = derived_constant(outline.units_per_em, 6000); + // Heuristic value to weight distances (not a latin constant since + // it works on multiples of stem width) + let dist_score = 3000; + // Compare each segment to the others.. O(n^2) + let segments = axis.segments.as_mut_slice(); + for ix1 in 0..segments.len() { + let seg1 = segments[ix1]; + if seg1.dir != axis.major_dir { + continue; + } + let pos1 = seg1.pos as i32; + // Search for stems having opposite directions with seg1 to the + // "left" of seg2 + for ix2 in 0..segments.len() { + let seg1 = segments[ix1]; + let seg2 = segments[ix2]; + let pos2 = seg2.pos as i32; + if seg1.dir.is_opposite(seg2.dir) && pos2 > pos1 { + // Compute distance between the segments + // Note: the min/max functions chosen here are intentional + let min = seg1.min_coord.max(seg2.min_coord) as i32; + let max = seg1.max_coord.min(seg2.max_coord) as i32; + // Compute maximum coordinate difference or how much they + // overlap + let len = max - min; + if len >= len_threshold { + // verbatim from FreeType: + // "The score is the sum of two demerits indicating the + // `badness' of a fit, measured along the segments' main axis + // and orthogonal to it, respectively. + // + // - The less overlapping along the main axis, the worse it + // is, causing a larger demerit. + // + // - The nearer the orthogonal distance to a stem width, the + // better it is, causing a smaller demerit. For simplicity, + // however, we only increase the demerit for values that + // exceed the largest stem width." + // See + let dist = pos2 - pos1; + let dist_demerit = if max_width != 0 { + // Distance demerits are based on multiples of max_width + let delta = (dist << 10) / max_width - (1 << 10); + if delta > 10_000 { + MAX_SCORE + } else if delta > 0 { + delta * delta / dist_score + } else { + 0 + } + } else { + dist + }; + let score = dist_demerit + len_score / len; + if score < seg1.score { + let seg1 = &mut segments[ix1]; + seg1.score = score; + seg1.link_ix = Some(ix2 as u16); + } + if score < seg2.score { + let seg2 = &mut segments[ix2]; + seg2.score = score; + seg2.link_ix = Some(ix1 as u16); + } + } + } + } + } + // Now compute "serif" segments + // See + for ix1 in 0..segments.len() { + let Some(ix2) = segments[ix1].link_ix else { + continue; + }; + let seg2_link = segments[ix2 as usize].link_ix; + if seg2_link != Some(ix1 as u16) { + let seg1 = &mut segments[ix1]; + seg1.link_ix = None; + seg1.serif_ix = seg2_link; + } + } +} + +/// Link segments to form stems and serifs for the CJK script group. +/// +/// See +fn link_segments_cjk(outline: &Outline, axis: &mut Axis, scale: i32) { + // Heuristic value to set up a minimum for overlapping + let len_threshold = derived_constant(outline.units_per_em, 8); + let dist_threshold = fixed_div(64 * 3, scale); + // Compare each segment to the others.. O(n^2) + let segments = axis.segments.as_mut_slice(); + for ix1 in 0..segments.len() { + let seg1 = segments[ix1]; + if seg1.dir != axis.major_dir { + continue; + } + let pos1 = seg1.pos as i32; + // Search for stems having opposite directions with seg1 to the + // "left" of seg2 + for ix2 in 0..segments.len() { + let seg1 = segments[ix1]; + let seg2 = segments[ix2]; + if ix1 == ix2 || !seg1.dir.is_opposite(seg2.dir) { + continue; + } + let pos2 = seg2.pos as i32; + let dist = pos2 - pos1; + if dist < 0 { + continue; + } + // Compute distance between the segments + // Note: the min/max functions chosen here are intentional + let min = seg1.min_coord.max(seg2.min_coord) as i32; + let max = seg1.max_coord.min(seg2.max_coord) as i32; + // Compute maximum coordinate difference or how much they + // overlap + let len = max - min; + if len >= len_threshold { + let check_seg = |seg: &Segment| { + // Some more magic heuristics... + // See + (dist * 8 < seg.score * 9) && (dist * 8 < seg.score * 7 || seg.len < len) + }; + if check_seg(&seg1) { + let seg = &mut segments[ix1]; + seg.score = dist; + seg.len = len; + seg.link_ix = Some(ix2 as _); + } + if check_seg(&seg2) { + let seg = &mut segments[ix2]; + seg.score = dist; + seg.len = len; + seg.link_ix = Some(ix1 as _); + } + } + } + } + // Now compute "serif" segments + // See + for ix1 in 0..segments.len() { + let seg1 = segments[ix1]; + if seg1.score >= dist_threshold { + continue; + } + let Some(link1) = seg1.link(segments).copied() else { + continue; + }; + // Unwrap is fine because we checked for existence above + let link1_ix = seg1.link_ix.unwrap() as usize; + if link1.link_ix != Some(ix1 as u16) || link1.pos <= seg1.pos { + continue; + } + for ix2 in 0..segments.len() { + let seg2 = segments[ix2]; + if seg2.pos > seg1.pos || ix1 == ix2 { + continue; + } + let Some(link2) = seg2.link(segments).copied() else { + continue; + }; + if link2.link_ix != Some(ix2 as u16) || link2.pos < link1.pos { + continue; + } + if seg1.pos == seg2.pos && link1.pos == link2.pos { + continue; + } + if seg2.score <= seg1.score || seg1.score * 4 <= seg2.score { + continue; + } + if seg1.len >= seg2.len * 3 { + // Again, we definitely have a valid link2 + let link2_ix = seg2.link_ix.unwrap() as usize; + for seg in segments.iter_mut() { + let link_ix = seg.link_ix; + if link_ix == Some(ix2 as u16) { + seg.link_ix = None; + seg.serif_ix = Some(link1_ix as u16); + } else if link_ix == Some(link2_ix as u16) { + seg.link_ix = None; + seg.serif_ix = Some(ix1 as u16); + } + } + } else { + segments[ix1].link_ix = None; + segments[link1_ix].link_ix = None; + break; + } + } + } + for ix1 in 0..segments.len() { + let seg1 = segments[ix1]; + let Some(seg2) = seg1.link(segments).copied() else { + continue; + }; + if seg2.link_ix != Some(ix1 as u16) { + segments[ix1].link_ix = None; + if seg2.score < dist_threshold || seg1.score < seg2.score * 4 { + segments[ix1].serif_ix = seg2.link_ix; + } + } + } +} + +/// Set the (u, v) values to font unit coords for each point depending +/// on the axis dimension. +/// +/// See +fn assign_point_uvs(outline: &mut Outline, dim: Dimension) { + if dim == Axis::HORIZONTAL { + for point in &mut outline.points { + point.u = point.fx; + point.v = point.fy; + } + } else { + for point in &mut outline.points { + point.u = point.fy; + point.v = point.fx; + } + } +} + +/// Build the set of segments for each contour. +/// +/// See +fn build_segments(outline: &mut Outline, axis: &mut Axis) -> bool { + let flat_threshold = outline.units_per_em / 14; + axis.segments.clear(); + let major_dir = axis.major_dir.normalize(); + let mut segment_dir = major_dir; + let points = outline.points.as_mut_slice(); + for contour in &outline.contours { + let is_single_point_contour = contour.range().len() == 1; + let mut point_ix = contour.first(); + let mut last_ix = contour.prev(point_ix); + let mut state = State::default(); + let mut prev_state = state; + let mut prev_segment_ix: Option = None; + let mut segment_ix = 0; + // Check if we're starting on an edge and if so, find + // the starting point + if points[point_ix].out_dir.is_same_axis(major_dir) + && points[last_ix].out_dir.is_same_axis(major_dir) + { + last_ix = point_ix; + loop { + point_ix = contour.prev(point_ix); + if !points[point_ix].out_dir.is_same_axis(major_dir) { + point_ix = contour.next(point_ix); + break; + } + if point_ix == last_ix { + break; + } + } + } + last_ix = point_ix; + let mut on_edge = false; + let mut passed = false; + loop { + if on_edge { + // Get min and max position + let point = points[point_ix]; + state.min_pos = state.min_pos.min(point.u); + state.max_pos = state.max_pos.max(point.u); + // Get min and max coordinate and flags + let v = point.v; + if v < state.min_coord { + state.min_coord = v; + state.min_flags = point.flags; + } + if v > state.max_coord { + state.max_coord = v; + state.max_flags = point.flags; + } + // Get min and max coord of on curve points + if point.is_on_curve() { + state.min_on_coord = state.min_on_coord.min(point.v); + state.max_on_coord = state.max_on_coord.max(point.v); + } + if point.out_dir != segment_dir || point_ix == last_ix { + if prev_segment_ix.is_none() + || axis.segments[segment_ix].first_ix + != axis.segments[prev_segment_ix.unwrap()].last_ix + { + // The points are different signifying that we are + // leaving an edge, so create a new segment + let segment = &mut axis.segments[segment_ix]; + segment.last_ix = point_ix as u16; + state.apply_to_segment(segment, flat_threshold); + prev_segment_ix = Some(segment_ix); + prev_state = state; + } else { + // The points are the same, so merge the segments + let prev_segment = &mut axis.segments[prev_segment_ix.unwrap()]; + if prev_segment.last_point(points).in_dir == point.in_dir { + // We have identical directions; unify segments + // and update constraints + state.min_pos = prev_state.min_pos.min(state.min_pos); + state.max_pos = prev_state.max_pos.max(state.max_pos); + if prev_state.min_coord < state.min_coord { + state.min_coord = prev_state.min_coord; + state.min_flags = prev_state.min_flags; + } + if prev_state.max_coord > state.max_coord { + state.max_coord = prev_state.max_coord; + state.max_flags = prev_state.max_flags; + } + state.min_on_coord = prev_state.min_on_coord.min(state.min_on_coord); + state.max_on_coord = prev_state.max_on_coord.max(state.max_on_coord); + prev_segment.last_ix = point_ix as u16; + state.apply_to_segment(prev_segment, flat_threshold); + } else { + // We have different directions; use the + // properties of the longer segment + if (prev_state.max_coord - prev_state.min_coord).abs() + > (state.max_coord - state.min_coord).abs() + { + // Discard current segment + prev_state.min_pos = prev_state.min_pos.min(state.min_pos); + prev_state.max_pos = prev_state.max_pos.max(state.max_pos); + prev_segment.last_ix = point_ix as u16; + prev_segment.pos = + ((prev_state.min_pos + prev_state.max_pos) >> 1) as i16; + prev_segment.delta = + ((prev_state.max_pos - prev_state.min_pos) >> 1) as i16; + } else { + // Discard previous segment + state.min_pos = state.min_pos.min(prev_state.min_pos); + state.max_pos = state.max_pos.max(prev_state.max_pos); + let mut segment = axis.segments[segment_ix]; + segment.last_ix = point_ix as u16; + state.apply_to_segment(&mut segment, flat_threshold); + axis.segments[prev_segment_ix.unwrap()] = segment; + prev_state = state; + } + } + axis.segments.pop(); + } + on_edge = false; + } + } + if point_ix == last_ix { + if passed { + break; + } + passed = true; + } + let point = points[point_ix]; + if !on_edge && (point.out_dir.is_same_axis(major_dir) || is_single_point_contour) { + if axis.segments.len() > 1000 { + axis.segments.clear(); + return false; + } + segment_ix = axis.segments.len(); + segment_dir = point.out_dir; + let mut segment = Segment { + dir: segment_dir, + first_ix: point_ix as u16, + last_ix: point_ix as u16, + score: MAX_SCORE, + ..Default::default() + }; + state.min_pos = point.u; + state.max_pos = point.u; + state.min_coord = point.v; + state.max_coord = point.v; + state.min_flags = point.flags; + state.max_flags = point.flags; + if !point.is_on_curve() { + state.min_on_coord = MAX_SCORE; + state.max_on_coord = MIN_SCORE; + } else { + state.min_on_coord = point.v; + state.max_on_coord = point.v; + } + on_edge = true; + if is_single_point_contour { + segment.pos = state.min_pos as i16; + if !point.is_on_curve() { + segment.flags |= Segment::ROUND; + } + segment.min_coord = point.v as i16; + segment.max_coord = point.v as i16; + segment.height = 0; + on_edge = false; + } + axis.segments.push(segment); + } + point_ix = contour.next(point_ix); + } + } + true +} + +/// Slightly increase the height of segments when it makes sense to better +/// detect and ignore serifs. +/// +/// See +fn adjust_segment_heights(outline: &mut Outline, axis: &mut Axis) { + let points = outline.points.as_slice(); + for segment in &mut axis.segments { + let first = segment.first_point(points); + let last = segment.last_point(points); + fn adjust_height(segment: &mut Segment, v1: i32, v2: i32) { + segment.height = (segment.height as i32 + ((v1 - v2) >> 1)) as i16; + } + let prev = &points[first.prev()]; + let next = &points[last.next()]; + if first.v < last.v { + if prev.v < first.v { + adjust_height(segment, first.v, prev.v); + } + if next.v > last.v { + adjust_height(segment, next.v, last.v); + } + } else { + if prev.v > first.v { + adjust_height(segment, prev.v, first.v); + } + if next.v < last.v { + adjust_height(segment, last.v, next.v); + } + } + } +} + +/// Performs the additional step of detecting round segments for the CJK script +/// group. +/// +/// See +fn _detect_round_segments_cjk(outline: &mut Outline, axis: &mut Axis) { + let points = outline.points.as_slice(); + // A segment is considered round if it doesn't have successive on-curve + // points + for segment in &mut axis.segments { + segment.flags &= !Segment::ROUND; + let mut point_ix = segment.first(); + let last_ix = segment.last(); + let first_point = &points[point_ix]; + let mut is_prev_on_curve = first_point.is_on_curve(); + point_ix = first_point.next(); + loop { + let point = &points[point_ix]; + let is_on_curve = point.is_on_curve(); + if is_prev_on_curve && is_on_curve { + // Two on-curves in a row means we're not a round segment + break; + } + is_prev_on_curve = is_on_curve; + point_ix = point.next(); + if point_ix == last_ix { + // We've reached the last point without two successive + // on-curves so we're round + segment.flags |= Segment::ROUND; + break; + } + } + } +} + +/// Capture current and previous state while computing segments. +/// +/// Values measured along a segment (point.v) are called "coordinates" and +/// values orthogonal to it (point.u) are called "positions" +#[derive(Copy, Clone)] +struct State { + min_pos: i32, + max_pos: i32, + min_coord: i32, + max_coord: i32, + min_flags: PointFlags, + max_flags: PointFlags, + min_on_coord: i32, + max_on_coord: i32, +} + +impl Default for State { + fn default() -> Self { + // + Self { + min_pos: MAX_SCORE, + max_pos: MIN_SCORE, + min_coord: MAX_SCORE, + max_coord: MIN_SCORE, + min_flags: PointFlags::default(), + max_flags: PointFlags::default(), + min_on_coord: MAX_SCORE, + max_on_coord: MIN_SCORE, + } + } +} + +impl State { + fn apply_to_segment(&self, segment: &mut Segment, flat_threshold: i32) { + segment.pos = ((self.min_pos + self.max_pos) >> 1) as i16; + segment.delta = ((self.max_pos - self.min_pos) >> 1) as i16; + // A segment is round if either end point is a + // control and the length of the on points in + // between fits within a heuristic limit. + if (!self.min_flags.is_on_curve() || !self.max_flags.is_on_curve()) + && (self.max_on_coord - self.min_on_coord) < flat_threshold + { + segment.flags |= Segment::ROUND; + } + segment.min_coord = self.min_coord as i16; + segment.max_coord = self.max_coord as i16; + segment.height = segment.max_coord - segment.min_coord; + } +} + +#[cfg(test)] +mod tests { + use super::{super::super::outline::Direction, *}; + use crate::MetadataProvider; + use raw::{types::GlyphId, FontRef}; + + #[test] + fn horizontal_segments() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::new(8)).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axis = Axis::new(Axis::HORIZONTAL, outline.orientation); + compute_segments(&mut outline, &mut axis, ScriptGroup::Default); + link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); + let segments = retain_segment_test_fields(&axis.segments); + let expected = [ + Segment { + flags: 0, + dir: Direction::Up, + pos: 55, + delta: 0, + min_coord: 26, + max_coord: 360, + height: 372, + link_ix: Some(3), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 112, + delta: 0, + min_coord: 481, + max_coord: 504, + height: 34, + link_ix: Some(2), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 168, + delta: 0, + min_coord: 483, + max_coord: 504, + height: 26, + link_ix: Some(1), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 109, + delta: 0, + min_coord: 109, + max_coord: 366, + height: 288, + link_ix: Some(0), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 453, + delta: 0, + min_coord: 169, + max_coord: 432, + height: 304, + link_ix: Some(7), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Up, + pos: 62, + delta: 0, + min_coord: 517, + max_coord: 566, + height: 76, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Down, + pos: 103, + delta: 0, + min_coord: 619, + max_coord: 647, + height: 41, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 507, + delta: 0, + min_coord: 40, + max_coord: 485, + height: 498, + link_ix: Some(4), + serif_ix: None, + ..Default::default() + }, + ]; + assert_eq!(segments, &expected); + } + + #[test] + fn vertical_segments() { + let font = FontRef::new(font_test_data::NOTOSERIFHEBREW_AUTOHINT_METRICS).unwrap(); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::new(8)).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axis = Axis::new(Axis::VERTICAL, outline.orientation); + compute_segments(&mut outline, &mut axis, ScriptGroup::Default); + link_segments(&outline, &mut axis, 0, ScriptGroup::Default, None); + let segments = retain_segment_test_fields(&axis.segments); + let expected = [ + Segment { + flags: 0, + dir: Direction::Left, + pos: 0, + delta: 0, + min_coord: 85, + max_coord: 470, + height: 418, + link_ix: Some(2), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 504, + delta: 0, + min_coord: 112, + max_coord: 168, + height: 56, + link_ix: Some(3), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 109, + delta: 0, + min_coord: 109, + max_coord: 427, + height: 327, + link_ix: Some(0), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Left, + pos: 483, + delta: 0, + min_coord: 86, + max_coord: 400, + height: 352, + link_ix: Some(1), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 647, + delta: 0, + min_coord: 76, + max_coord: 103, + height: 29, + link_ix: None, + serif_ix: Some(1), + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 592, + delta: 0, + min_coord: 131, + max_coord: 437, + height: 346, + link_ix: None, + serif_ix: Some(1), + ..Default::default() + }, + ]; + assert_eq!(segments, &expected); + } + + #[test] + fn cjk_horizontal_segments() { + let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::new(9)).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axis = Axis::new(Axis::HORIZONTAL, outline.orientation); + compute_segments(&mut outline, &mut axis, ScriptGroup::Cjk); + link_segments(&outline, &mut axis, 67109, ScriptGroup::Cjk, None); + let segments = retain_segment_test_fields(&axis.segments); + let expected = [ + Segment { + flags: 0, + dir: Direction::Down, + pos: 731, + delta: 0, + min_coord: 155, + max_coord: 676, + height: 524, + link_ix: Some(1), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 670, + delta: 0, + min_coord: 133, + max_coord: 712, + height: 579, + link_ix: Some(0), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 458, + delta: 0, + min_coord: 741, + max_coord: 757, + height: 88, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 911, + delta: 0, + min_coord: -9, + max_coord: 791, + height: 821, + link_ix: Some(5), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 693, + delta: 0, + min_coord: -7, + max_coord: 9, + height: 18, + link_ix: None, + serif_ix: Some(5), + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 849, + delta: 0, + min_coord: 11, + max_coord: 829, + height: 823, + link_ix: Some(3), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 569, + delta: 0, + min_coord: 547, + max_coord: 576, + height: 29, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Down, + pos: 201, + delta: 0, + min_coord: -57, + max_coord: 540, + height: 599, + link_ix: Some(8), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Up, + pos: 138, + delta: 0, + min_coord: -78, + max_coord: 543, + height: 640, + link_ix: Some(7), + serif_ix: None, + ..Default::default() + }, + ]; + assert_eq!(segments, &expected); + } + + #[test] + fn cjk_vertical_segments() { + let font = FontRef::new(font_test_data::NOTOSERIFTC_AUTOHINT_METRICS).unwrap(); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::new(9)).unwrap(); + let mut outline = Outline::default(); + outline.fill(&glyph, Default::default()).unwrap(); + let mut axis = Axis::new(Axis::VERTICAL, outline.orientation); + compute_segments(&mut outline, &mut axis, ScriptGroup::Cjk); + link_segments(&outline, &mut axis, 67109, ScriptGroup::Cjk, None); + let segments = retain_segment_test_fields(&axis.segments); + let expected = [ + Segment { + flags: 0, + dir: Direction::Right, + pos: 758, + delta: 0, + min_coord: 280, + max_coord: 545, + height: 288, + link_ix: Some(1), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Left, + pos: 729, + delta: 0, + min_coord: 288, + max_coord: 674, + height: 391, + link_ix: Some(0), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Left, + pos: 133, + delta: 0, + min_coord: 670, + max_coord: 693, + height: 34, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 757, + delta: 0, + min_coord: 393, + max_coord: 458, + height: 70, + link_ix: None, + serif_ix: Some(0), + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Right, + pos: 3, + delta: 2, + min_coord: 727, + max_coord: 838, + height: 133, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Right, + pos: 576, + delta: 0, + min_coord: 397, + max_coord: 569, + height: 177, + link_ix: Some(7), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Left, + pos: 547, + delta: 0, + min_coord: 387, + max_coord: 569, + height: 182, + link_ix: None, + serif_ix: Some(7), + ..Default::default() + }, + Segment { + flags: 0, + dir: Direction::Left, + pos: 576, + delta: 0, + min_coord: 536, + max_coord: 546, + height: 10, + link_ix: Some(5), + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Left, + pos: -78, + delta: 0, + min_coord: 138, + max_coord: 161, + height: 34, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + Segment { + flags: 1, + dir: Direction::Left, + pos: 788, + delta: 0, + min_coord: 262, + max_coord: 294, + height: 46, + link_ix: None, + serif_ix: None, + ..Default::default() + }, + ]; + assert_eq!(segments, &expected); + } + + // Retain the fields that are valid and comparable after + // the segment pass. + fn retain_segment_test_fields(segments: &[Segment]) -> Vec { + segments + .iter() + .map(|segment| Segment { + flags: segment.flags, + dir: segment.dir, + pos: segment.pos, + delta: segment.delta, + min_coord: segment.min_coord, + max_coord: segment.max_coord, + height: segment.height, + link_ix: segment.link_ix, + serif_ix: segment.serif_ix, + ..Default::default() + }) + .collect() + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1502 @@ +//! CFF hinting. + +use read_fonts::{ + tables::postscript::{charstring::CommandSink, dict::Blues}, + types::Fixed, +}; + +// "Default values for OS/2 typoAscender/Descender.." +// See +const ICF_TOP: Fixed = Fixed::from_i32(880); +const ICF_BOTTOM: Fixed = Fixed::from_i32(-120); + +// +const MAX_BLUES: usize = 7; +const MAX_OTHER_BLUES: usize = 5; +const MAX_BLUE_ZONES: usize = MAX_BLUES + MAX_OTHER_BLUES; + +// +const MAX_HINTS: usize = 96; + +// One bit per stem hint +// +const HINT_MASK_SIZE: usize = (MAX_HINTS + 7) / 8; + +// Constant for hint adjustment and em box hint placement. +// +const MIN_COUNTER: Fixed = Fixed::from_bits(0x8000); + +// +const EPSILON: Fixed = Fixed::from_bits(1); + +/// Parameters used to generate the stem and counter zones for the hinting +/// algorithm. +#[derive(Clone)] +pub(crate) struct HintParams { + pub blues: Blues, + pub family_blues: Blues, + pub other_blues: Blues, + pub family_other_blues: Blues, + pub blue_scale: Fixed, + pub blue_shift: Fixed, + pub blue_fuzz: Fixed, + pub language_group: i32, +} + +impl Default for HintParams { + fn default() -> Self { + Self { + blues: Blues::default(), + other_blues: Blues::default(), + family_blues: Blues::default(), + family_other_blues: Blues::default(), + // See + blue_scale: Fixed::from_f64(0.039625), + blue_shift: Fixed::from_i32(7), + blue_fuzz: Fixed::ONE, + language_group: 0, + } + } +} + +/// See +#[derive(Copy, Clone, PartialEq, Default, Debug)] +struct BlueZone { + is_bottom: bool, + cs_bottom_edge: Fixed, + cs_top_edge: Fixed, + cs_flat_edge: Fixed, + ds_flat_edge: Fixed, +} + +/// Hinting state for a PostScript subfont. +/// +/// Note that hinter states depend on the scale, subfont index and +/// variation coordinates of a glyph. They can be retained and reused +/// if those values remain the same. +#[derive(Copy, Clone, PartialEq, Default)] +pub(crate) struct HintState { + scale: Fixed, + blue_scale: Fixed, + blue_shift: Fixed, + blue_fuzz: Fixed, + language_group: i32, + suppress_overshoot: bool, + do_em_box_hints: bool, + boost: Fixed, + darken_y: Fixed, + zones: [BlueZone; MAX_BLUE_ZONES], + zone_count: usize, +} + +impl HintState { + pub fn new(params: &HintParams, scale: Fixed) -> Self { + let mut state = Self { + scale, + blue_scale: params.blue_scale, + blue_shift: params.blue_shift, + blue_fuzz: params.blue_fuzz, + language_group: params.language_group, + suppress_overshoot: false, + do_em_box_hints: false, + boost: Fixed::ZERO, + darken_y: Fixed::ZERO, + zones: [BlueZone::default(); MAX_BLUE_ZONES], + zone_count: 0, + }; + state.build_zones(params); + state + } + + fn zones(&self) -> &[BlueZone] { + &self.zones[..self.zone_count] + } + + /// Initialize zones from the set of blues values. + /// + /// See + fn build_zones(&mut self, params: &HintParams) { + self.do_em_box_hints = false; + // + match (self.language_group, params.blues.values().len()) { + (1, 2) => { + let blues = params.blues.values(); + if blues[0].0 < ICF_BOTTOM + && blues[0].1 < ICF_BOTTOM + && blues[1].0 > ICF_TOP + && blues[1].1 > ICF_TOP + { + // FreeType generates synthetic hints here. We'll do it + // later when building the hint map. + self.do_em_box_hints = true; + return; + } + } + (1, 0) => { + self.do_em_box_hints = true; + return; + } + _ => {} + } + let mut zones = [BlueZone::default(); MAX_BLUE_ZONES]; + let mut max_zone_height = Fixed::ZERO; + let mut zone_ix = 0usize; + // Copy blues and other blues to a combined array of top and bottom zones. + for blue in params.blues.values().iter().take(MAX_BLUES) { + // FreeType loads blues as integers and then expands to 16.16 + // at initialization. We load them as 16.16 so floor them here + // to ensure we match. + // + let bottom = blue.0.floor(); + let top = blue.1.floor(); + let zone_height = top - bottom; + if zone_height < Fixed::ZERO { + // Reject zones with negative height + continue; + } + max_zone_height = max_zone_height.max(zone_height); + let zone = &mut zones[zone_ix]; + zone.cs_bottom_edge = bottom; + zone.cs_top_edge = top; + if zone_ix == 0 { + // First blue value is bottom zone + zone.is_bottom = true; + zone.cs_flat_edge = top; + } else { + // Remaining blue values are top zones + zone.is_bottom = false; + // Adjust both edges of top zone upward by twice darkening amount + zone.cs_top_edge += twice(self.darken_y); + zone.cs_bottom_edge += twice(self.darken_y); + zone.cs_flat_edge = zone.cs_bottom_edge; + } + zone_ix += 1; + } + for blue in params.other_blues.values().iter().take(MAX_OTHER_BLUES) { + let bottom = blue.0.floor(); + let top = blue.1.floor(); + let zone_height = top - bottom; + if zone_height < Fixed::ZERO { + // Reject zones with negative height + continue; + } + max_zone_height = max_zone_height.max(zone_height); + let zone = &mut zones[zone_ix]; + // All "other" blues are bottom zone + zone.is_bottom = true; + zone.cs_bottom_edge = bottom; + zone.cs_top_edge = top; + zone.cs_flat_edge = top; + zone_ix += 1; + } + // Adjust for family blues + let units_per_pixel = Fixed::ONE / self.scale; + for zone in &mut zones[..zone_ix] { + let flat = zone.cs_flat_edge; + let mut min_diff = Fixed::MAX; + if zone.is_bottom { + // In a bottom zone, the top edge is the flat edge. + // Search family other blues for bottom zones. Look for the + // closest edge that is within the one pixel threshold. + for blue in params.family_other_blues.values() { + let family_flat = blue.1; + let diff = (flat - family_flat).abs(); + if diff < min_diff && diff < units_per_pixel { + zone.cs_flat_edge = family_flat; + min_diff = diff; + if diff == Fixed::ZERO { + break; + } + } + } + // Check the first member of family blues, which is a bottom + // zone + if !params.family_blues.values().is_empty() { + let family_flat = params.family_blues.values()[0].1; + let diff = (flat - family_flat).abs(); + if diff < min_diff && diff < units_per_pixel { + zone.cs_flat_edge = family_flat; + } + } + } else { + // In a top zone, the bottom edge is the flat edge. + // Search family blues for top zones, skipping the first, which + // is a bottom zone. Look for closest family edge that is + // within the one pixel threshold. + for blue in params.family_blues.values().iter().skip(1) { + let family_flat = blue.0 + twice(self.darken_y); + let diff = (flat - family_flat).abs(); + if diff < min_diff && diff < units_per_pixel { + zone.cs_flat_edge = family_flat; + min_diff = diff; + if diff == Fixed::ZERO { + break; + } + } + } + } + } + if max_zone_height > Fixed::ZERO && self.blue_scale > (Fixed::ONE / max_zone_height) { + // Clamp at maximum scale + self.blue_scale = Fixed::ONE / max_zone_height; + } + // Suppress overshoot and boost blue zones at small sizes + if self.scale < self.blue_scale { + self.suppress_overshoot = true; + self.boost = + Fixed::from_f64(0.6) - Fixed::from_f64(0.6).mul_div(self.scale, self.blue_scale); + // boost must remain less than 0.5, or baseline could go negative + self.boost = self.boost.min(Fixed::from_bits(0x7FFF)); + } + if self.darken_y != Fixed::ZERO { + self.boost = Fixed::ZERO; + } + // Set device space alignment for each zone; apply boost amount before + // rounding flat edge + let scale = self.scale; + let boost = self.boost; + for zone in &mut zones[..zone_ix] { + let boost = if zone.is_bottom { -boost } else { boost }; + zone.ds_flat_edge = (zone.cs_flat_edge * scale + boost).round(); + } + self.zones = zones; + self.zone_count = zone_ix; + } + + /// Check whether a hint is captured by one of the blue zones. + /// + /// See + fn capture(&self, bottom_edge: &mut Hint, top_edge: &mut Hint) -> bool { + // We use some wrapping arithmetic on this value below to avoid panics + // on overflow and match FreeType's behavior + // See + let fuzz = self.blue_fuzz; + let mut captured = false; + let mut adjustment = Fixed::ZERO; + for zone in self.zones() { + if zone.is_bottom + && bottom_edge.is_bottom() + && zone.cs_bottom_edge.wrapping_sub(fuzz) <= bottom_edge.cs_coord + && bottom_edge.cs_coord <= zone.cs_top_edge.wrapping_add(fuzz) + { + // Bottom edge captured by bottom zone. + adjustment = if self.suppress_overshoot { + zone.ds_flat_edge + } else if zone.cs_top_edge.wrapping_sub(bottom_edge.cs_coord) >= self.blue_shift { + // Guarantee minimum of 1 pixel overshoot + bottom_edge + .ds_coord + .round() + .min(zone.ds_flat_edge - Fixed::ONE) + } else { + bottom_edge.ds_coord.round() + }; + adjustment -= bottom_edge.ds_coord; + captured = true; + break; + } + if !zone.is_bottom + && top_edge.is_top() + && zone.cs_bottom_edge.wrapping_sub(fuzz) <= top_edge.cs_coord + && top_edge.cs_coord <= zone.cs_top_edge.wrapping_add(fuzz) + { + // Top edge captured by top zone. + adjustment = if self.suppress_overshoot { + zone.ds_flat_edge + } else if top_edge.cs_coord.wrapping_sub(zone.cs_bottom_edge) >= self.blue_shift { + // Guarantee minimum of 1 pixel overshoot + top_edge + .ds_coord + .round() + .max(zone.ds_flat_edge + Fixed::ONE) + } else { + top_edge.ds_coord.round() + }; + adjustment -= top_edge.ds_coord; + captured = true; + break; + } + } + if captured { + // Move both edges and mark them as "locked" + if bottom_edge.is_valid() { + bottom_edge.ds_coord += adjustment; + bottom_edge.lock(); + } + if top_edge.is_valid() { + top_edge.ds_coord += adjustment; + top_edge.lock(); + } + } + captured + } +} + +/// +#[derive(Copy, Clone, Default)] +struct StemHint { + /// If true, device space position is valid + is_used: bool, + // Character space position + min: Fixed, + max: Fixed, + // Device space position after first use + ds_min: Fixed, + ds_max: Fixed, +} + +// Hint flags +const GHOST_BOTTOM: u8 = 0x1; +const GHOST_TOP: u8 = 0x2; +const PAIR_BOTTOM: u8 = 0x4; +const PAIR_TOP: u8 = 0x8; +const LOCKED: u8 = 0x10; +const SYNTHETIC: u8 = 0x20; + +/// +#[derive(Copy, Clone, PartialEq, Default, Debug)] +struct Hint { + flags: u8, + /// Index in original stem hint array (if not synthetic) + index: u8, + cs_coord: Fixed, + ds_coord: Fixed, + scale: Fixed, +} + +impl Hint { + fn is_valid(&self) -> bool { + self.flags != 0 + } + + fn is_bottom(&self) -> bool { + self.flags & (GHOST_BOTTOM | PAIR_BOTTOM) != 0 + } + + fn is_top(&self) -> bool { + self.flags & (GHOST_TOP | PAIR_TOP) != 0 + } + + fn is_pair(&self) -> bool { + self.flags & (PAIR_BOTTOM | PAIR_TOP) != 0 + } + + fn is_pair_top(&self) -> bool { + self.flags & PAIR_TOP != 0 + } + + fn is_locked(&self) -> bool { + self.flags & LOCKED != 0 + } + + fn is_synthetic(&self) -> bool { + self.flags & SYNTHETIC != 0 + } + + fn lock(&mut self) { + self.flags |= LOCKED + } + + /// Hint initialization from an incoming stem hint. + /// + /// See + fn setup( + &mut self, + stem: &StemHint, + index: u8, + origin: Fixed, + scale: Fixed, + darken_y: Fixed, + is_bottom: bool, + ) { + // "Ghost hints" are used to align a single edge rather than a + // stem-- think the top and bottom edges of an uppercase + // sans-serif I. + // These are encoded internally with stem hints of width -21 + // and -20 for bottom and top hints, respectively. + const GHOST_BOTTOM_WIDTH: Fixed = Fixed::from_i32(-21); + const GHOST_TOP_WIDTH: Fixed = Fixed::from_i32(-20); + let width = stem.max - stem.min; + if width == GHOST_BOTTOM_WIDTH { + if is_bottom { + self.cs_coord = stem.max; + self.flags = GHOST_BOTTOM; + } else { + self.flags = 0; + } + } else if width == GHOST_TOP_WIDTH { + if !is_bottom { + self.cs_coord = stem.min; + self.flags = GHOST_TOP; + } else { + self.flags = 0; + } + } else if width < Fixed::ZERO { + // If width < 0, this is an inverted pair. We follow FreeType and + // swap the coordinates + if is_bottom { + self.cs_coord = stem.max; + self.flags = PAIR_BOTTOM; + } else { + self.cs_coord = stem.min; + self.flags = PAIR_TOP; + } + } else { + // This is a normal pair + if is_bottom { + self.cs_coord = stem.min; + self.flags = PAIR_BOTTOM; + } else { + self.cs_coord = stem.max; + self.flags = PAIR_TOP; + } + } + if self.is_top() { + // For top hints, adjust character space position up by twice the + // darkening amount + self.cs_coord += twice(darken_y); + } + self.cs_coord += origin; + self.scale = scale; + self.index = index; + // If original stem hint was used, copy the position + if self.flags != 0 && stem.is_used { + if self.is_top() { + self.ds_coord = stem.ds_max; + } else { + self.ds_coord = stem.ds_min; + } + self.lock(); + } else { + self.ds_coord = self.cs_coord * scale; + } + } +} + +/// Collection of adjusted hint edges. +/// +/// +#[derive(Copy, Clone)] +struct HintMap { + edges: [Hint; MAX_HINTS], + len: usize, + is_valid: bool, + scale: Fixed, +} + +impl HintMap { + fn new(scale: Fixed) -> Self { + Self { + edges: [Hint::default(); MAX_HINTS], + len: 0, + is_valid: false, + scale, + } + } + + fn clear(&mut self) { + self.len = 0; + self.is_valid = false; + } + + /// Transform character space coordinate to device space. + /// + /// Based on + fn transform(&self, coord: Fixed) -> Fixed { + if self.len == 0 { + return coord * self.scale; + } + let limit = self.len - 1; + let mut i = 0; + while i < limit && coord >= self.edges[i + 1].cs_coord { + i += 1; + } + while i > 0 && coord < self.edges[i].cs_coord { + i -= 1; + } + let first_edge = &self.edges[0]; + if i == 0 && coord < first_edge.cs_coord { + // Special case for points below first edge: use uniform scale + ((coord - first_edge.cs_coord) * self.scale) + first_edge.ds_coord + } else { + // Use highest edge where cs_coord >= edge.cs_coord + let edge = &self.edges[i]; + ((coord - edge.cs_coord) * edge.scale) + edge.ds_coord + } + } + + /// Insert hint edges into map, sorted by character space coordinate. + /// + /// Based on + fn insert(&mut self, bottom: &Hint, top: &Hint, initial: Option<&HintMap>) { + let (is_pair, mut first_edge) = if !bottom.is_valid() { + // Bottom is invalid: insert only top edge + (false, *top) + } else if !top.is_valid() { + // Top is invalid: insert only bottom edge + (false, *bottom) + } else { + // We have a valid pair! + (true, *bottom) + }; + let mut second_edge = *top; + if is_pair && top.cs_coord < bottom.cs_coord { + // Paired edges must be in proper order. FT just ignores the hint. + return; + } + let edge_count = if is_pair { 2 } else { 1 }; + if self.len + edge_count > MAX_HINTS { + // Won't fit. Again, ignore. + return; + } + // Find insertion index that keeps the edge list sorted + let mut insert_ix = 0; + while insert_ix < self.len { + if self.edges[insert_ix].cs_coord >= first_edge.cs_coord { + break; + } + insert_ix += 1; + } + // Discard hints that overlap in character space + if insert_ix < self.len { + let current = &self.edges[insert_ix]; + // Existing edge is the same + if (current.cs_coord == first_edge.cs_coord) + // Pair straddles the next edge + || (is_pair && current.cs_coord <= second_edge.cs_coord) + // Inserting between paired edges + || current.is_pair_top() + { + return; + } + } + // Recompute device space locations using initial hint map + if !first_edge.is_locked() { + if let Some(initial) = initial { + if is_pair { + // Preserve stem width: position center of stem with + // initial hint map and two edges with nominal scale + // + let mid = + initial.transform(midpoint(first_edge.cs_coord, second_edge.cs_coord)); + let half_width = half(second_edge.cs_coord - first_edge.cs_coord) * self.scale; + first_edge.ds_coord = mid - half_width; + second_edge.ds_coord = mid + half_width; + } else { + first_edge.ds_coord = initial.transform(first_edge.cs_coord); + } + } + } + // Now discard hints that overlap in device space: + if insert_ix > 0 && first_edge.ds_coord < self.edges[insert_ix - 1].ds_coord { + // Inserting after an existing edge + return; + } + if insert_ix < self.len + && ((is_pair && second_edge.ds_coord > self.edges[insert_ix].ds_coord) + || first_edge.ds_coord > self.edges[insert_ix].ds_coord) + { + // Inserting before an existing edge + return; + } + // If we're inserting in the middle, make room in the edge array + if insert_ix != self.len { + let mut src_index = self.len - 1; + let mut dst_index = self.len + edge_count - 1; + loop { + self.edges[dst_index] = self.edges[src_index]; + if src_index == insert_ix { + break; + } + src_index -= 1; + dst_index -= 1; + } + } + self.edges[insert_ix] = first_edge; + if is_pair { + self.edges[insert_ix + 1] = second_edge; + } + self.len += edge_count; + } + + /// Adjust hint pairs so that one of the two edges is on a pixel boundary. + /// + /// Based on + fn adjust(&mut self) { + let mut saved = [(0usize, Fixed::ZERO); MAX_HINTS]; + let mut saved_count = 0usize; + let mut i = 0; + // From FT with adjustments for variable names: + // "First pass is bottom-up (font hint order) without look-ahead. + // Locked edges are already adjusted. + // Unlocked edges begin with ds_coord from `initial_map'. + // Save edges that are not optimally adjusted in `saved' array, + // and process them in second pass." + let limit = self.len; + while i < limit { + let is_pair = self.edges[i].is_pair(); + let j = if is_pair { i + 1 } else { i }; + if !self.edges[i].is_locked() { + // We can adjust hint edges that are not locked + let frac_down = self.edges[i].ds_coord.fract(); + let frac_up = self.edges[j].ds_coord.fract(); + // There are four possibilities. We compute them all. + // (moves down are negative) + let down_move_down = Fixed::ZERO - frac_down; + let up_move_down = Fixed::ZERO - frac_up; + let down_move_up = if frac_down == Fixed::ZERO { + Fixed::ZERO + } else { + Fixed::ONE - frac_down + }; + let up_move_up = if frac_up == Fixed::ZERO { + Fixed::ZERO + } else { + Fixed::ONE - frac_up + }; + // Smallest move up + let move_up = down_move_up.min(up_move_up); + // Smallest move down + let move_down = down_move_down.max(up_move_down); + let mut save_edge = false; + let adjustment; + // Check for room to move up: + // 1. We're at the top of the array, or + // 2. The next edge is at or above the proposed move up + if j >= self.len - 1 + || self.edges[j + 1].ds_coord + >= (self.edges[j].ds_coord + move_up + MIN_COUNTER) + { + // Also check for room to move down... + if i == 0 + || self.edges[i - 1].ds_coord + <= (self.edges[i].ds_coord + move_down - MIN_COUNTER) + { + // .. and move the smallest distance + adjustment = if -move_down < move_up { + move_down + } else { + move_up + }; + } else { + adjustment = move_up; + } + } else if i == 0 + || self.edges[i - 1].ds_coord + <= (self.edges[i].ds_coord + move_down - MIN_COUNTER) + { + // We can move down + adjustment = move_down; + // True if the move is not optimum + save_edge = move_up < -move_down; + } else { + // We can't move either way without overlapping + adjustment = Fixed::ZERO; + save_edge = true; + } + // Capture non-optimal adjustments and save them for a second + // pass. This is only possible if the edge above is unlocked + // and can be moved. + if save_edge && j < self.len - 1 && !self.edges[j + 1].is_locked() { + // (index, desired adjustment) + saved[saved_count] = (j, move_up - adjustment); + saved_count += 1; + } + // Apply the adjustment + self.edges[i].ds_coord += adjustment; + if is_pair { + self.edges[j].ds_coord += adjustment; + } + } + // Compute the new edge scale + if i > 0 && self.edges[i].cs_coord != self.edges[i - 1].cs_coord { + let a = self.edges[i]; + let b = self.edges[i - 1]; + self.edges[i - 1].scale = (a.ds_coord - b.ds_coord) / (a.cs_coord - b.cs_coord); + } + if is_pair { + if self.edges[j].cs_coord != self.edges[j - 1].cs_coord { + let a = self.edges[j]; + let b = self.edges[j - 1]; + self.edges[j - 1].scale = (a.ds_coord - b.ds_coord) / (a.cs_coord - b.cs_coord); + } + i += 1; + } + i += 1; + } + // Second pass tries to move non-optimal edges up if the first + // pass created room + for (j, adjustment) in saved[..saved_count].iter().copied().rev() { + if self.edges[j + 1].ds_coord >= (self.edges[j].ds_coord + adjustment + MIN_COUNTER) { + self.edges[j].ds_coord += adjustment; + if self.edges[j].is_pair() { + self.edges[j - 1].ds_coord += adjustment; + } + } + } + } + + /// Builds a hintmap from hints and mask. + /// + /// If `initial_map` is invalid, this recurses one level to initialize + /// it. If `is_initial` is true, simply build the initial map. + /// + /// Based on + fn build( + &mut self, + state: &HintState, + mask: Option, + mut initial_map: Option<&mut HintMap>, + stems: &mut [StemHint], + origin: Fixed, + is_initial: bool, + ) { + let scale = state.scale; + let darken_y = Fixed::ZERO; + if !is_initial { + if let Some(initial_map) = &mut initial_map { + if !initial_map.is_valid { + // Note: recursive call here to build the initial map if it + // is provided and invalid + initial_map.build(state, Some(HintMask::all()), None, stems, origin, true); + } + } + } + let initial_map = initial_map.map(|x| x as &HintMap); + self.clear(); + // If the mask is missing or invalid, assume all hints are active + let mut mask = mask.unwrap_or_else(HintMask::all); + if !mask.is_valid { + mask = HintMask::all(); + } + if state.do_em_box_hints { + // FreeType generates these during blues initialization. Do + // it here just to avoid carrying the extra state in the + // already large HintState struct. + // + let mut bottom = Hint::default(); + bottom.cs_coord = ICF_BOTTOM - EPSILON; + bottom.ds_coord = (bottom.cs_coord * scale).round() - MIN_COUNTER; + bottom.scale = scale; + bottom.flags = GHOST_BOTTOM | LOCKED | SYNTHETIC; + let mut top = Hint::default(); + top.cs_coord = ICF_TOP + EPSILON + twice(state.darken_y); + top.ds_coord = (top.cs_coord * scale).round() + MIN_COUNTER; + top.scale = scale; + top.flags = GHOST_TOP | LOCKED | SYNTHETIC; + let invalid = Hint::default(); + self.insert(&bottom, &invalid, initial_map); + self.insert(&invalid, &top, initial_map); + } + let mut tmp_mask = mask; + // FreeType iterates over the hint mask with some fancy bit logic. We + // do the simpler thing and loop over the stems. + // + for (i, stem) in stems.iter().enumerate() { + if !tmp_mask.get(i) { + continue; + } + let hint_ix = i as u8; + let mut bottom = Hint::default(); + let mut top = Hint::default(); + bottom.setup(stem, hint_ix, origin, scale, darken_y, true); + top.setup(stem, hint_ix, origin, scale, darken_y, false); + // Insert hints that are locked or captured by a blue zone + if bottom.is_locked() || top.is_locked() || state.capture(&mut bottom, &mut top) { + if is_initial { + self.insert(&bottom, &top, None); + } else { + self.insert(&bottom, &top, initial_map); + } + // Avoid processing this hint in the second pass + tmp_mask.clear(i); + } + } + if is_initial { + // Heuristic: insert a point at (0, 0) if it's not covered by a + // mapping. Ensures a lock at baseline for glyphs missing a + // baseline hint. + if self.len == 0 + || self.edges[0].cs_coord > Fixed::ZERO + || self.edges[self.len - 1].cs_coord < Fixed::ZERO + { + let edge = Hint { + flags: GHOST_BOTTOM | LOCKED | SYNTHETIC, + scale, + ..Default::default() + }; + let invalid = Hint::default(); + self.insert(&edge, &invalid, None); + } + } else { + // Insert hints that were skipped in the first pass + for (i, stem) in stems.iter().enumerate() { + if !tmp_mask.get(i) { + continue; + } + let hint_ix = i as u8; + let mut bottom = Hint::default(); + let mut top = Hint::default(); + bottom.setup(stem, hint_ix, origin, scale, darken_y, true); + top.setup(stem, hint_ix, origin, scale, darken_y, false); + self.insert(&bottom, &top, initial_map); + } + } + // Adjust edges that are not locked to blue zones + self.adjust(); + if !is_initial { + // Save position of edges that were used by the hint map. + for edge in &self.edges[..self.len] { + if edge.is_synthetic() { + continue; + } + let stem = &mut stems[edge.index as usize]; + if edge.is_top() { + stem.ds_max = edge.ds_coord; + } else { + stem.ds_min = edge.ds_coord; + } + stem.is_used = true; + } + } + self.is_valid = true; + } +} + +/// Bitmask that specifies which hints are currently active. +/// +/// "Each bit of the mask, starting with the most-significant bit of +/// the first byte, represents the corresponding hint zone in the +/// order in which the hints were declared at the beginning of +/// the charstring." +/// +/// See +/// Also +#[derive(Copy, Clone, PartialEq, Default)] +struct HintMask { + mask: [u8; HINT_MASK_SIZE], + is_valid: bool, +} + +impl HintMask { + fn new(bytes: &[u8]) -> Option { + let len = bytes.len(); + if len > HINT_MASK_SIZE { + return None; + } + let mut mask = Self::default(); + mask.mask[..len].copy_from_slice(&bytes[..len]); + mask.is_valid = true; + Some(mask) + } + + fn all() -> Self { + Self { + mask: [0xFF; HINT_MASK_SIZE], + is_valid: true, + } + } + + fn clear(&mut self, bit: usize) { + self.mask[bit >> 3] &= !msb_mask(bit); + } + + fn get(&self, bit: usize) -> bool { + self.mask[bit >> 3] & msb_mask(bit) != 0 + } +} + +/// Returns a bit mask for the selected bit with the +/// most significant bit at index 0. +fn msb_mask(bit: usize) -> u8 { + 1 << (7 - (bit & 0x7)) +} + +pub(super) struct HintingSink<'a, S> { + state: &'a HintState, + sink: &'a mut S, + stem_hints: [StemHint; MAX_HINTS], + stem_count: u8, + mask: HintMask, + initial_map: HintMap, + map: HintMap, + /// Most recent move_to in character space. + start_point: Option<[Fixed; 2]>, + /// Most recent line_to. First two elements are coords in character + /// space and the last two are in device space. + pending_line: Option<[Fixed; 4]>, +} + +impl<'a, S: CommandSink> HintingSink<'a, S> { + pub fn new(state: &'a HintState, sink: &'a mut S) -> Self { + let scale = state.scale; + Self { + state, + sink, + stem_hints: [StemHint::default(); MAX_HINTS], + stem_count: 0, + mask: HintMask::all(), + initial_map: HintMap::new(scale), + map: HintMap::new(scale), + start_point: None, + pending_line: None, + } + } + + pub fn finish(&mut self) { + self.maybe_close_subpath(); + } + + fn maybe_close_subpath(&mut self) { + // This requires some explanation. The hint mask can be modified + // during charstring evaluation which changes the set of hints that + // are applied. FreeType ensures that the closing line for any subpath + // is transformed with the same hint map as the starting point for the + // subpath. This is done by stashing a copy of the hint map that is + // active when a new subpath is started. Unlike FreeType, we make use + // of close elements, so we can cheat a bit here and avoid the + // extra hintmap. If we're closing an open subpath and have a pending + // line and the line is not equal to the start point in character + // space, then we emit the saved device space coordinates for the + // line. If the coordinates do match in character space, we omit + // that line. The unconditional close command ensures that the + // start and end points coincide. + // Note: this doesn't apply to subpaths that end in cubics. + match (self.start_point.take(), self.pending_line.take()) { + (Some(start), Some([cs_x, cs_y, ds_x, ds_y])) => { + if start != [cs_x, cs_y] { + self.sink.line_to(ds_x, ds_y); + } + self.sink.close(); + } + (Some(_), _) => self.sink.close(), + _ => {} + } + } + + fn flush_pending_line(&mut self) { + if let Some([_, _, x, y]) = self.pending_line.take() { + self.sink.line_to(x, y); + } + } + + fn hint(&mut self, coord: Fixed) -> Fixed { + if !self.map.is_valid { + self.build_hint_map(Some(self.mask), Fixed::ZERO); + } + trunc(self.map.transform(coord)) + } + + fn scale(&self, coord: Fixed) -> Fixed { + trunc(coord * self.state.scale) + } + + fn add_stem(&mut self, min: Fixed, max: Fixed) { + let index = self.stem_count as usize; + if index >= MAX_HINTS || self.map.is_valid { + return; + } + let stem = &mut self.stem_hints[index]; + stem.min = min; + stem.max = max; + stem.is_used = false; + stem.ds_min = Fixed::ZERO; + stem.ds_max = Fixed::ZERO; + self.stem_count = index as u8 + 1; + } + + fn build_hint_map(&mut self, mask: Option, origin: Fixed) { + self.map.build( + self.state, + mask, + Some(&mut self.initial_map), + &mut self.stem_hints[..self.stem_count as usize], + origin, + false, + ); + } +} + +impl CommandSink for HintingSink<'_, S> { + fn hstem(&mut self, min: Fixed, max: Fixed) { + self.add_stem(min, max); + } + + fn hint_mask(&mut self, mask: &[u8]) { + // For invalid hint masks, FreeType assumes all hints are active. + // See + let mask = HintMask::new(mask).unwrap_or_else(HintMask::all); + if mask != self.mask { + self.mask = mask; + self.map.is_valid = false; + } + } + + fn counter_mask(&mut self, mask: &[u8]) { + // For counter masks, we build a temporary hint map "just to + // place and lock those stems participating in the counter + // mask." Building the map modifies the stem hint array as a + // side effect. + // See + let mask = HintMask::new(mask).unwrap_or_else(HintMask::all); + let mut map = HintMap::new(self.state.scale); + map.build( + self.state, + Some(mask), + Some(&mut self.initial_map), + &mut self.stem_hints[..self.stem_count as usize], + Fixed::ZERO, + false, + ); + } + + fn move_to(&mut self, x: Fixed, y: Fixed) { + self.maybe_close_subpath(); + self.start_point = Some([x, y]); + let x = self.scale(x); + let y = self.hint(y); + self.sink.move_to(x, y); + } + + fn line_to(&mut self, x: Fixed, y: Fixed) { + self.flush_pending_line(); + let ds_x = self.scale(x); + let ds_y = self.hint(y); + self.pending_line = Some([x, y, ds_x, ds_y]); + } + + fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { + self.flush_pending_line(); + let cx1 = self.scale(cx1); + let cy1 = self.hint(cy1); + let cx2 = self.scale(cx2); + let cy2 = self.hint(cy2); + let x = self.scale(x); + let y = self.hint(y); + self.sink.curve_to(cx1, cy1, cx2, cy2, x, y); + } + + fn close(&mut self) { + // We emit close commands based on the sequence of moves. + // See `maybe_close_subpath` + } +} + +/// FreeType converts from 16.16 to 26.6 by truncation. We keep our +/// values in 16.16 so simply zero the low 10 bits to match the +/// precision when converting to f32. +fn trunc(value: Fixed) -> Fixed { + Fixed::from_bits(value.to_bits() & !0x3FF) +} + +fn half(value: Fixed) -> Fixed { + Fixed::from_bits(value.to_bits() / 2) +} + +fn twice(value: Fixed) -> Fixed { + Fixed::from_bits(value.to_bits().wrapping_mul(2)) +} + +/// Computes midpoint between `a` and `b`, avoiding overflow if the sum +/// of the high 16 bits exceeds `i16::MAX`. +fn midpoint(a: Fixed, b: Fixed) -> Fixed { + a + half(b - a) +} + +#[cfg(test)] +mod tests { + use read_fonts::{tables::postscript::charstring::CommandSink, types::F2Dot14, FontRef}; + + use super::{ + BlueZone, Blues, Fixed, Hint, HintMap, HintMask, HintParams, HintState, HintingSink, + StemHint, GHOST_BOTTOM, GHOST_TOP, HINT_MASK_SIZE, LOCKED, PAIR_BOTTOM, PAIR_TOP, + }; + + fn make_hint_state() -> HintState { + fn make_blues(values: &[f64]) -> Blues { + Blues::new(values.iter().copied().map(Fixed::from_f64)) + } + // + // + // + // + // + let params = HintParams { + blues: make_blues(&[ + -15.0, 0.0, 536.0, 547.0, 571.0, 582.0, 714.0, 726.0, 760.0, 772.0, + ]), + other_blues: make_blues(&[-255.0, -240.0]), + blue_scale: Fixed::from_f64(0.05), + blue_shift: Fixed::from_i32(7), + blue_fuzz: Fixed::ZERO, + ..Default::default() + }; + HintState::new(¶ms, Fixed::ONE / Fixed::from_i32(64)) + } + + #[test] + fn scaled_blue_zones() { + let state = make_hint_state(); + assert!(!state.do_em_box_hints); + assert_eq!(state.zone_count, 6); + assert_eq!(state.boost, Fixed::from_bits(27035)); + assert!(state.suppress_overshoot); + // FreeType generates the following zones: + let expected_zones = &[ + // csBottomEdge -983040 int + // csTopEdge 0 int + // csFlatEdge 0 int + // dsFlatEdge 0 int + // bottomZone 1 '\x1' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(-983040), + is_bottom: true, + ..Default::default() + }, + // csBottomEdge 35127296 int + // csTopEdge 35848192 int + // csFlatEdge 35127296 int + // dsFlatEdge 589824 int + // bottomZone 0 '\0' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(35127296), + cs_top_edge: Fixed::from_bits(35848192), + cs_flat_edge: Fixed::from_bits(35127296), + ds_flat_edge: Fixed::from_bits(589824), + is_bottom: false, + }, + // csBottomEdge 37421056 int + // csTopEdge 38141952 int + // csFlatEdge 37421056 int + // dsFlatEdge 589824 int + // bottomZone 0 '\0' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(37421056), + cs_top_edge: Fixed::from_bits(38141952), + cs_flat_edge: Fixed::from_bits(37421056), + ds_flat_edge: Fixed::from_bits(589824), + is_bottom: false, + }, + // csBottomEdge 46792704 int + // csTopEdge 47579136 int + // csFlatEdge 46792704 int + // dsFlatEdge 786432 int + // bottomZone 0 '\0' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(46792704), + cs_top_edge: Fixed::from_bits(47579136), + cs_flat_edge: Fixed::from_bits(46792704), + ds_flat_edge: Fixed::from_bits(786432), + is_bottom: false, + }, + // csBottomEdge 49807360 int + // csTopEdge 50593792 int + // csFlatEdge 49807360 int + // dsFlatEdge 786432 int + // bottomZone 0 '\0' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(49807360), + cs_top_edge: Fixed::from_bits(50593792), + cs_flat_edge: Fixed::from_bits(49807360), + ds_flat_edge: Fixed::from_bits(786432), + is_bottom: false, + }, + // csBottomEdge -16711680 int + // csTopEdge -15728640 int + // csFlatEdge -15728640 int + // dsFlatEdge -262144 int + // bottomZone 1 '\x1' unsigned char + BlueZone { + cs_bottom_edge: Fixed::from_bits(-16711680), + cs_top_edge: Fixed::from_bits(-15728640), + cs_flat_edge: Fixed::from_bits(-15728640), + ds_flat_edge: Fixed::from_bits(-262144), + is_bottom: true, + }, + ]; + assert_eq!(state.zones(), expected_zones); + } + + #[test] + fn blue_zone_capture() { + let state = make_hint_state(); + let bottom_edge = Hint { + flags: PAIR_BOTTOM, + ds_coord: Fixed::from_f64(2.3), + ..Default::default() + }; + let top_edge = Hint { + flags: PAIR_TOP, + // This value chosen to fit within the first "top" blue zone + cs_coord: Fixed::from_bits(35127297), + ds_coord: Fixed::from_f64(2.3), + ..Default::default() + }; + // Capture both + { + let (mut bottom_edge, mut top_edge) = (bottom_edge, top_edge); + assert!(state.capture(&mut bottom_edge, &mut top_edge)); + assert!(bottom_edge.is_locked()); + assert!(top_edge.is_locked()); + } + // Capture none + { + // Used to guarantee the edges are below all blue zones and will + // not be captured + let min_cs_coord = Fixed::MIN; + let mut bottom_edge = Hint { + cs_coord: min_cs_coord, + ..bottom_edge + }; + let mut top_edge = Hint { + cs_coord: min_cs_coord, + ..top_edge + }; + assert!(!state.capture(&mut bottom_edge, &mut top_edge)); + assert!(!bottom_edge.is_locked()); + assert!(!top_edge.is_locked()); + } + // Capture bottom, ignore invalid top + { + let mut bottom_edge = bottom_edge; + let mut top_edge = Hint { + // Empty flags == invalid hint + flags: 0, + ..top_edge + }; + assert!(state.capture(&mut bottom_edge, &mut top_edge)); + assert!(bottom_edge.is_locked()); + assert!(!top_edge.is_locked()); + } + // Capture top, ignore invalid bottom + { + let mut bottom_edge = Hint { + // Empty flags == invalid hint + flags: 0, + ..bottom_edge + }; + let mut top_edge = top_edge; + assert!(state.capture(&mut bottom_edge, &mut top_edge)); + assert!(!bottom_edge.is_locked()); + assert!(top_edge.is_locked()); + } + } + + #[test] + fn hint_mask_ops() { + const MAX_BITS: usize = HINT_MASK_SIZE * 8; + let all_bits = HintMask::all(); + for i in 0..MAX_BITS { + assert!(all_bits.get(i)); + } + let odd_bits = HintMask::new(&[0b01010101; HINT_MASK_SIZE]).unwrap(); + for i in 0..MAX_BITS { + assert_eq!(i & 1 != 0, odd_bits.get(i)); + } + let mut cleared_bits = odd_bits; + for i in 0..MAX_BITS { + if i & 1 != 0 { + cleared_bits.clear(i); + } + } + assert_eq!(cleared_bits.mask, HintMask::default().mask); + } + + #[test] + fn hint_mapping() { + let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); + let cff_font = super::super::Outlines::new(&font).unwrap(); + let state = cff_font + .subfont(0, Some(8.0), &[F2Dot14::from_f32(-1.0); 2]) + .unwrap() + .hint_state; + let mut initial_map = HintMap::new(state.scale); + let mut map = HintMap::new(state.scale); + // Stem hints from Cantarell-VF.otf glyph id 2 + let mut stems = [ + StemHint { + min: Fixed::from_bits(1376256), + max: Fixed::ZERO, + ..Default::default() + }, + StemHint { + min: Fixed::from_bits(16318464), + max: Fixed::from_bits(17563648), + ..Default::default() + }, + StemHint { + min: Fixed::from_bits(45481984), + max: Fixed::from_bits(44171264), + ..Default::default() + }, + ]; + map.build( + &state, + Some(HintMask::all()), + Some(&mut initial_map), + &mut stems, + Fixed::ZERO, + false, + ); + // FT generates the following hint map: + // + // index csCoord dsCoord scale flags + // 0 0.00 0.00 526 gbL + // 1 249.00 250.14 524 pb + // 1 268.00 238.22 592 pt + // 2 694.00 750.41 524 gtL + let expected_edges = [ + Hint { + index: 0, + cs_coord: Fixed::from_f64(0.0), + ds_coord: Fixed::from_f64(0.0), + scale: Fixed::from_bits(526), + flags: GHOST_BOTTOM | LOCKED, + }, + Hint { + index: 1, + cs_coord: Fixed::from_bits(16318464), + ds_coord: Fixed::from_bits(131072), + scale: Fixed::from_bits(524), + flags: PAIR_BOTTOM, + }, + Hint { + index: 1, + cs_coord: Fixed::from_bits(17563648), + ds_coord: Fixed::from_bits(141028), + scale: Fixed::from_bits(592), + flags: PAIR_TOP, + }, + Hint { + index: 2, + cs_coord: Fixed::from_bits(45481984), + ds_coord: Fixed::from_bits(393216), + scale: Fixed::from_bits(524), + flags: GHOST_TOP | LOCKED, + }, + ]; + assert_eq!(expected_edges, &map.edges[..map.len]); + // And FT generates the following mappings + let mappings = [ + // (coord in font units, expected hinted coord in device space) in 16.16 + (0, 0), // 0 -> 0 + (44302336, 382564), // 676 -> 5.828125 + (45481984, 393216), // 694 -> 6 + (16318464, 131072), // 249 -> 2 + (17563648, 141028), // 268 -> 2.140625 + (49676288, 426752), // 758 -> 6.5 + (56754176, 483344), // 866 -> 7.375 + (57868288, 492252), // 883 -> 7.5 + (50069504, 429896), // 764 -> 6.546875 + ]; + for (coord, expected) in mappings { + assert_eq!( + map.transform(Fixed::from_bits(coord)), + Fixed::from_bits(expected) + ); + } + } + + #[test] + fn midpoint_avoids_overflow() { + // We encountered an overflow in the HintMap::insert midpoint + // calculation for glyph id 950 at size 74 in + // KawkabMono-Bold v0.501 . + // Test that our midpoint function doesn't overflow when the sum of + // the high 16 bits of the two values exceeds i16::MAX. + let a = i16::MAX as i32; + let b = a - 1; + assert!(a + b > i16::MAX as i32); + let mid = super::midpoint(Fixed::from_i32(a), Fixed::from_i32(b)); + assert_eq!((a + b) / 2, mid.to_bits() >> 16); + } + + /// HintingSink is mostly pass-through. This test captures the logic + /// around omission of pending lines that match subpath start. + /// See HintingSink::maybe_close_subpath for details. + #[test] + fn hinting_sink_omits_closing_line_that_matches_start() { + let state = HintState { + scale: Fixed::ONE, + ..Default::default() + }; + let mut path = Path::default(); + let mut sink = HintingSink::new(&state, &mut path); + let move1_2 = [Fixed::from_f64(1.0), Fixed::from_f64(2.0)]; + let line2_3 = [Fixed::from_f64(2.0), Fixed::from_f64(3.0)]; + let line1_2 = [Fixed::from_f64(1.0), Fixed::from_f64(2.0)]; + let line3_4 = [Fixed::from_f64(3.0), Fixed::from_f64(4.0)]; + let curve = [ + Fixed::from_f64(3.0), + Fixed::from_f64(4.0), + Fixed::from_f64(5.0), + Fixed::from_f64(6.0), + Fixed::from_f64(1.0), + Fixed::from_f64(2.0), + ]; + // First subpath, closing line matches start + sink.move_to(move1_2[0], move1_2[1]); + sink.line_to(line2_3[0], line2_3[1]); + sink.line_to(line1_2[0], line1_2[1]); + // Second subpath, closing line does not match start + sink.move_to(move1_2[0], move1_2[1]); + sink.line_to(line2_3[0], line2_3[1]); + sink.line_to(line3_4[0], line3_4[1]); + // Third subpath, ends with cubic. Still emits a close command + // even though end point matches start. + sink.move_to(move1_2[0], move1_2[1]); + sink.line_to(line2_3[0], line2_3[1]); + sink.curve_to(curve[0], curve[1], curve[2], curve[3], curve[4], curve[5]); + sink.finish(); + // Subpaths always end with a close command. If a final line coincides + // with the start of a subpath, it is omitted. + assert_eq!( + &path.0, + &[ + // First subpath + MoveTo(move1_2), + LineTo(line2_3), + // line1_2 is omitted + Close, + // Second subpath + MoveTo(move1_2), + LineTo(line2_3), + LineTo(line3_4), + Close, + // Third subpath + MoveTo(move1_2), + LineTo(line2_3), + CurveTo(curve), + Close, + ] + ); + } + + #[derive(Copy, Clone, PartialEq, Debug)] + enum Command { + MoveTo([Fixed; 2]), + LineTo([Fixed; 2]), + CurveTo([Fixed; 6]), + Close, + } + + use Command::*; + + #[derive(Default)] + struct Path(Vec); + + impl CommandSink for Path { + fn move_to(&mut self, x: Fixed, y: Fixed) { + self.0.push(MoveTo([x, y])); + } + fn line_to(&mut self, x: Fixed, y: Fixed) { + self.0.push(LineTo([x, y])); + } + fn curve_to(&mut self, cx0: Fixed, cy0: Fixed, cx1: Fixed, cy1: Fixed, x: Fixed, y: Fixed) { + self.0.push(CurveTo([cx0, cy0, cx1, cy1, x, y])); + } + fn close(&mut self) { + self.0.push(Close); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,852 @@ +//! Support for scaling CFF outlines. + +mod hint; + +use super::{GlyphHMetrics, OutlinePen}; +use hint::{HintParams, HintState, HintingSink}; +use raw::FontRef; +use read_fonts::{ + tables::{ + postscript::{ + charstring::{self, CommandSink}, + dict, BlendState, Error, FdSelect, Index, + }, + variations::ItemVariationStore, + }, + types::{F2Dot14, Fixed, GlyphId}, + FontData, FontRead, ReadError, TableProvider, +}; +use std::ops::Range; + +/// Type for loading, scaling and hinting outlines in CFF/CFF2 tables. +/// +/// The skrifa crate provides a higher level interface for this that handles +/// caching and abstracting over the different outline formats. Consider using +/// that if detailed control over resources is not required. +/// +/// # Subfonts +/// +/// CFF tables can contain multiple logical "subfonts" which determine the +/// state required for processing some subset of glyphs. This state is +/// accessed using the [`FDArray and FDSelect`](https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf#page=28) +/// operators to select an appropriate subfont for any given glyph identifier. +/// This process is exposed on this type with the +/// [`subfont_index`](Self::subfont_index) method to retrieve the subfont +/// index for the requested glyph followed by using the +/// [`subfont`](Self::subfont) method to create an appropriately configured +/// subfont for that glyph. +#[derive(Clone)] +pub(crate) struct Outlines<'a> { + pub(crate) font: FontRef<'a>, + pub(crate) glyph_metrics: GlyphHMetrics<'a>, + offset_data: FontData<'a>, + global_subrs: Index<'a>, + top_dict: TopDict<'a>, + version: u16, + units_per_em: u16, +} + +impl<'a> Outlines<'a> { + /// Creates a new scaler for the given font. + /// + /// This will choose an underlying CFF2 or CFF table from the font, in that + /// order. + pub fn new(font: &FontRef<'a>) -> Option { + let units_per_em = font.head().ok()?.units_per_em(); + Self::from_cff2(font, units_per_em).or_else(|| Self::from_cff(font, units_per_em)) + } + + pub fn from_cff(font: &FontRef<'a>, units_per_em: u16) -> Option { + let cff1 = font.cff().ok()?; + let glyph_metrics = GlyphHMetrics::new(font)?; + // "The Name INDEX in the CFF data must contain only one entry; + // that is, there must be only one font in the CFF FontSet" + // So we always pass 0 for Top DICT index when reading from an + // OpenType font. + // + let top_dict_data = cff1.top_dicts().get(0).ok()?; + let top_dict = TopDict::new(cff1.offset_data().as_bytes(), top_dict_data, false).ok()?; + Some(Self { + font: font.clone(), + glyph_metrics, + offset_data: cff1.offset_data(), + global_subrs: cff1.global_subrs().into(), + top_dict, + version: 1, + units_per_em, + }) + } + + pub fn from_cff2(font: &FontRef<'a>, units_per_em: u16) -> Option { + let cff2 = font.cff2().ok()?; + let glyph_metrics = GlyphHMetrics::new(font)?; + let table_data = cff2.offset_data().as_bytes(); + let top_dict = TopDict::new(table_data, cff2.top_dict_data(), true).ok()?; + Some(Self { + font: font.clone(), + glyph_metrics, + offset_data: cff2.offset_data(), + global_subrs: cff2.global_subrs().into(), + top_dict, + version: 2, + units_per_em, + }) + } + + pub fn is_cff2(&self) -> bool { + self.version == 2 + } + + pub fn units_per_em(&self) -> u16 { + self.units_per_em + } + + /// Returns the number of available glyphs. + pub fn glyph_count(&self) -> usize { + self.top_dict.charstrings.count() as usize + } + + /// Returns the number of available subfonts. + pub fn subfont_count(&self) -> u32 { + // All CFF fonts have at least one logical subfont. + self.top_dict.font_dicts.count().max(1) + } + + /// Returns the subfont (or Font DICT) index for the given glyph + /// identifier. + pub fn subfont_index(&self, glyph_id: GlyphId) -> u32 { + // For CFF tables, an FDSelect index will be present for CID-keyed + // fonts. Otherwise, the Top DICT will contain an entry for the + // "global" Private DICT. + // See + // + // CFF2 tables always contain a Font DICT and an FDSelect is only + // present if the size of the DICT is greater than 1. + // See + // + // In both cases, we return a subfont index of 0 when FDSelect is missing. + self.top_dict + .fd_select + .as_ref() + .and_then(|select| select.font_index(glyph_id)) + .unwrap_or(0) as u32 + } + + /// Creates a new subfont for the given index, size, normalized + /// variation coordinates and hinting state. + /// + /// The index of a subfont for a particular glyph can be retrieved with + /// the [`subfont_index`](Self::subfont_index) method. + pub fn subfont( + &self, + index: u32, + size: Option, + coords: &[F2Dot14], + ) -> Result { + let private_dict_range = self.private_dict_range(index)?; + let blend_state = self + .top_dict + .var_store + .clone() + .map(|store| BlendState::new(store, coords, 0)) + .transpose()?; + let private_dict = PrivateDict::new(self.offset_data, private_dict_range, blend_state)?; + let scale = match size { + Some(ppem) if self.units_per_em > 0 => { + // Note: we do an intermediate scale to 26.6 to ensure we + // match FreeType + Some( + Fixed::from_bits((ppem * 64.) as i32) + / Fixed::from_bits(self.units_per_em as i32), + ) + } + _ => None, + }; + // When hinting, use a modified scale factor + // + let hint_scale = Fixed::from_bits((scale.unwrap_or(Fixed::ONE).to_bits() + 32) / 64); + let hint_state = HintState::new(&private_dict.hint_params, hint_scale); + Ok(Subfont { + is_cff2: self.is_cff2(), + scale, + subrs_offset: private_dict.subrs_offset, + hint_state, + store_index: private_dict.store_index, + }) + } + + /// Loads and scales an outline for the given subfont instance, glyph + /// identifier and normalized variation coordinates. + /// + /// Before calling this method, use [`subfont_index`](Self::subfont_index) + /// to retrieve the subfont index for the desired glyph and then + /// [`subfont`](Self::subfont) to create an instance of the subfont for a + /// particular size and location in variation space. + /// Creating subfont instances is not free, so this process is exposed in + /// discrete steps to allow for caching. + /// + /// The result is emitted to the specified pen. + pub fn draw( + &self, + subfont: &Subfont, + glyph_id: GlyphId, + coords: &[F2Dot14], + hint: bool, + pen: &mut impl OutlinePen, + ) -> Result<(), Error> { + let charstring_data = self.top_dict.charstrings.get(glyph_id.to_u32() as usize)?; + let subrs = subfont.subrs(self)?; + let blend_state = subfont.blend_state(self, coords)?; + let mut pen_sink = PenSink::new(pen); + let mut simplifying_adapter = NopFilteringSink::new(&mut pen_sink); + // Only apply hinting if we have a scale + if hint && subfont.scale.is_some() { + let mut hinting_adapter = + HintingSink::new(&subfont.hint_state, &mut simplifying_adapter); + charstring::evaluate( + charstring_data, + self.global_subrs.clone(), + subrs, + blend_state, + &mut hinting_adapter, + )?; + hinting_adapter.finish(); + } else { + let mut scaling_adapter = + ScalingSink26Dot6::new(&mut simplifying_adapter, subfont.scale); + charstring::evaluate( + charstring_data, + self.global_subrs.clone(), + subrs, + blend_state, + &mut scaling_adapter, + )?; + } + simplifying_adapter.finish(); + Ok(()) + } + + fn private_dict_range(&self, subfont_index: u32) -> Result, Error> { + if self.top_dict.font_dicts.count() != 0 { + // If we have a font dict array, extract the private dict range + // from the font dict at the given index. + let font_dict_data = self.top_dict.font_dicts.get(subfont_index as usize)?; + let mut range = None; + for entry in dict::entries(font_dict_data, None) { + if let dict::Entry::PrivateDictRange(r) = entry? { + range = Some(r); + break; + } + } + range + } else { + // Use the private dict range from the top dict. + // Note: "A Private DICT is required but may be specified as having + // a length of 0 if there are no non-default values to be stored." + // + let range = self.top_dict.private_dict_range.clone(); + Some(range.start as usize..range.end as usize) + } + .ok_or(Error::MissingPrivateDict) + } +} + +/// Specifies local subroutines and hinting parameters for some subset of +/// glyphs in a CFF or CFF2 table. +/// +/// This type is designed to be cacheable to avoid re-evaluating the private +/// dict every time a charstring is processed. +/// +/// For variable fonts, this is dependent on a location in variation space. +#[derive(Clone)] +pub(crate) struct Subfont { + is_cff2: bool, + scale: Option, + subrs_offset: Option, + pub(crate) hint_state: HintState, + store_index: u16, +} + +impl Subfont { + /// Returns the local subroutine index. + pub fn subrs<'a>(&self, scaler: &Outlines<'a>) -> Result>, Error> { + if let Some(subrs_offset) = self.subrs_offset { + let offset_data = scaler.offset_data.as_bytes(); + let index_data = offset_data.get(subrs_offset..).unwrap_or_default(); + Ok(Some(Index::new(index_data, self.is_cff2)?)) + } else { + Ok(None) + } + } + + /// Creates a new blend state for the given normalized variation + /// coordinates. + pub fn blend_state<'a>( + &self, + scaler: &Outlines<'a>, + coords: &'a [F2Dot14], + ) -> Result>, Error> { + if let Some(var_store) = scaler.top_dict.var_store.clone() { + Ok(Some(BlendState::new(var_store, coords, self.store_index)?)) + } else { + Ok(None) + } + } +} + +/// Entries that we parse from the Private DICT to support charstring +/// evaluation. +#[derive(Default)] +struct PrivateDict { + hint_params: HintParams, + subrs_offset: Option, + store_index: u16, +} + +impl PrivateDict { + fn new( + data: FontData, + range: Range, + blend_state: Option>, + ) -> Result { + let private_dict_data = data.read_array(range.clone())?; + let mut dict = Self::default(); + for entry in dict::entries(private_dict_data, blend_state) { + use dict::Entry::*; + match entry? { + BlueValues(values) => dict.hint_params.blues = values, + FamilyBlues(values) => dict.hint_params.family_blues = values, + OtherBlues(values) => dict.hint_params.other_blues = values, + FamilyOtherBlues(values) => dict.hint_params.family_blues = values, + BlueScale(value) => dict.hint_params.blue_scale = value, + BlueShift(value) => dict.hint_params.blue_shift = value, + BlueFuzz(value) => dict.hint_params.blue_fuzz = value, + LanguageGroup(group) => dict.hint_params.language_group = group, + // Subrs offset is relative to the private DICT + SubrsOffset(offset) => { + dict.subrs_offset = Some( + range + .start + .checked_add(offset) + .ok_or(ReadError::OutOfBounds)?, + ) + } + VariationStoreIndex(index) => dict.store_index = index, + _ => {} + } + } + Ok(dict) + } +} + +/// Entries that we parse from the Top DICT that are required to support +/// charstring evaluation. +#[derive(Clone, Default)] +struct TopDict<'a> { + charstrings: Index<'a>, + font_dicts: Index<'a>, + fd_select: Option>, + private_dict_range: Range, + var_store: Option>, +} + +impl<'a> TopDict<'a> { + fn new(table_data: &'a [u8], top_dict_data: &'a [u8], is_cff2: bool) -> Result { + let mut items = TopDict::default(); + for entry in dict::entries(top_dict_data, None) { + match entry? { + dict::Entry::CharstringsOffset(offset) => { + items.charstrings = + Index::new(table_data.get(offset..).unwrap_or_default(), is_cff2)?; + } + dict::Entry::FdArrayOffset(offset) => { + items.font_dicts = + Index::new(table_data.get(offset..).unwrap_or_default(), is_cff2)?; + } + dict::Entry::FdSelectOffset(offset) => { + items.fd_select = Some(FdSelect::read(FontData::new( + table_data.get(offset..).unwrap_or_default(), + ))?); + } + dict::Entry::PrivateDictRange(range) => { + items.private_dict_range = range.start as u32..range.end as u32; + } + dict::Entry::VariationStoreOffset(offset) if is_cff2 => { + // IVS is preceded by a 2 byte length, but ensure that + // we don't overflow + // See + let offset = offset.checked_add(2).ok_or(ReadError::OutOfBounds)?; + items.var_store = Some(ItemVariationStore::read(FontData::new( + table_data.get(offset..).unwrap_or_default(), + ))?); + } + _ => {} + } + } + Ok(items) + } +} + +/// Command sink that sends the results of charstring evaluation to +/// an [OutlinePen]. +struct PenSink<'a, P>(&'a mut P); + +impl<'a, P> PenSink<'a, P> { + fn new(pen: &'a mut P) -> Self { + Self(pen) + } +} + +impl

    CommandSink for PenSink<'_, P> +where + P: OutlinePen, +{ + fn move_to(&mut self, x: Fixed, y: Fixed) { + self.0.move_to(x.to_f32(), y.to_f32()); + } + + fn line_to(&mut self, x: Fixed, y: Fixed) { + self.0.line_to(x.to_f32(), y.to_f32()); + } + + fn curve_to(&mut self, cx0: Fixed, cy0: Fixed, cx1: Fixed, cy1: Fixed, x: Fixed, y: Fixed) { + self.0.curve_to( + cx0.to_f32(), + cy0.to_f32(), + cx1.to_f32(), + cy1.to_f32(), + x.to_f32(), + y.to_f32(), + ); + } + + fn close(&mut self) { + self.0.close(); + } +} + +/// Command sink adapter that applies a scaling factor. +/// +/// This assumes a 26.6 scaling factor packed into a Fixed and thus, +/// this is not public and exists only to match FreeType's exact +/// scaling process. +struct ScalingSink26Dot6<'a, S> { + inner: &'a mut S, + scale: Option, +} + +impl<'a, S> ScalingSink26Dot6<'a, S> { + fn new(sink: &'a mut S, scale: Option) -> Self { + Self { scale, inner: sink } + } + + fn scale(&self, coord: Fixed) -> Fixed { + // The following dance is necessary to exactly match FreeType's + // application of scaling factors. This seems to be the result + // of merging the contributed Adobe code while not breaking the + // FreeType public API. + // + // The first two steps apply to both scaled and unscaled outlines: + // + // 1. Multiply by 1/64 + // + let a = coord * Fixed::from_bits(0x0400); + // 2. Truncate the bottom 10 bits. Combined with the division by 64, + // converts to font units. + // + let b = Fixed::from_bits(a.to_bits() >> 10); + if let Some(scale) = self.scale { + // Scaled case: + // 3. Multiply by the original scale factor (to 26.6) + // + let c = b * scale; + // 4. Convert from 26.6 to 16.16 + Fixed::from_bits(c.to_bits() << 10) + } else { + // Unscaled case: + // 3. Convert from integer to 16.16 + Fixed::from_bits(b.to_bits() << 16) + } + } +} + +impl CommandSink for ScalingSink26Dot6<'_, S> { + fn hstem(&mut self, y: Fixed, dy: Fixed) { + self.inner.hstem(y, dy); + } + + fn vstem(&mut self, x: Fixed, dx: Fixed) { + self.inner.vstem(x, dx); + } + + fn hint_mask(&mut self, mask: &[u8]) { + self.inner.hint_mask(mask); + } + + fn counter_mask(&mut self, mask: &[u8]) { + self.inner.counter_mask(mask); + } + + fn move_to(&mut self, x: Fixed, y: Fixed) { + self.inner.move_to(self.scale(x), self.scale(y)); + } + + fn line_to(&mut self, x: Fixed, y: Fixed) { + self.inner.line_to(self.scale(x), self.scale(y)); + } + + fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { + self.inner.curve_to( + self.scale(cx1), + self.scale(cy1), + self.scale(cx2), + self.scale(cy2), + self.scale(x), + self.scale(y), + ); + } + + fn close(&mut self) { + self.inner.close(); + } +} + +/// Command sink adapter that suppresses degenerate move and line commands. +/// +/// FreeType avoids emitting empty contours and zero length lines to prevent +/// artifacts when stem darkening is enabled. We don't support stem darkening +/// because it's not enabled by any of our clients but we remove the degenerate +/// elements regardless to match the output. +/// +/// See +struct NopFilteringSink<'a, S> { + start: Option<(Fixed, Fixed)>, + last: Option<(Fixed, Fixed)>, + pending_move: Option<(Fixed, Fixed)>, + inner: &'a mut S, +} + +impl<'a, S> NopFilteringSink<'a, S> +where + S: CommandSink, +{ + fn new(inner: &'a mut S) -> Self { + Self { + start: None, + last: None, + pending_move: None, + inner, + } + } + + fn flush_pending_move(&mut self) { + if let Some((x, y)) = self.pending_move.take() { + if let Some((last_x, last_y)) = self.start { + if self.last != self.start { + self.inner.line_to(last_x, last_y); + } + } + self.start = Some((x, y)); + self.last = None; + self.inner.move_to(x, y); + } + } + + pub fn finish(&mut self) { + if let Some((x, y)) = self.start { + if self.last != self.start { + self.inner.line_to(x, y); + } + self.inner.close(); + } + } +} + +impl CommandSink for NopFilteringSink<'_, S> +where + S: CommandSink, +{ + fn hstem(&mut self, y: Fixed, dy: Fixed) { + self.inner.hstem(y, dy); + } + + fn vstem(&mut self, x: Fixed, dx: Fixed) { + self.inner.vstem(x, dx); + } + + fn hint_mask(&mut self, mask: &[u8]) { + self.inner.hint_mask(mask); + } + + fn counter_mask(&mut self, mask: &[u8]) { + self.inner.counter_mask(mask); + } + + fn move_to(&mut self, x: Fixed, y: Fixed) { + self.pending_move = Some((x, y)); + } + + fn line_to(&mut self, x: Fixed, y: Fixed) { + if self.pending_move == Some((x, y)) { + return; + } + self.flush_pending_move(); + if self.last == Some((x, y)) || (self.last.is_none() && self.start == Some((x, y))) { + return; + } + self.inner.line_to(x, y); + self.last = Some((x, y)); + } + + fn curve_to(&mut self, cx1: Fixed, cy1: Fixed, cx2: Fixed, cy2: Fixed, x: Fixed, y: Fixed) { + self.flush_pending_move(); + self.last = Some((x, y)); + self.inner.curve_to(cx1, cy1, cx2, cy2, x, y); + } + + fn close(&mut self) { + if self.pending_move.is_none() { + self.inner.close(); + self.start = None; + self.last = None; + } + } +} + +#[cfg(test)] +mod tests { + use super::{super::pen::SvgPen, *}; + use crate::{ + outline::{HintingInstance, HintingOptions}, + prelude::{LocationRef, Size}, + MetadataProvider, + }; + use raw::tables::cff2::Cff2; + use read_fonts::{test_helpers::BeBuffer, FontRef}; + + #[test] + fn unscaled_scaling_sink_produces_integers() { + let nothing = &mut (); + let sink = ScalingSink26Dot6::new(nothing, None); + for coord in [50.0, 50.1, 50.125, 50.5, 50.9] { + assert_eq!(sink.scale(Fixed::from_f64(coord)).to_f32(), 50.0); + } + } + + #[test] + fn scaled_scaling_sink() { + let ppem = 20.0; + let upem = 1000.0; + // match FreeType scaling with intermediate conversion to 26.6 + let scale = Fixed::from_bits((ppem * 64.) as i32) / Fixed::from_bits(upem as i32); + let nothing = &mut (); + let sink = ScalingSink26Dot6::new(nothing, Some(scale)); + let inputs = [ + // input coord, expected scaled output + (0.0, 0.0), + (8.0, 0.15625), + (16.0, 0.3125), + (32.0, 0.640625), + (72.0, 1.4375), + (128.0, 2.5625), + ]; + for (coord, expected) in inputs { + assert_eq!( + sink.scale(Fixed::from_f64(coord)).to_f32(), + expected, + "scaling coord {coord}" + ); + } + } + + #[test] + fn read_cff_static() { + let font = FontRef::new(font_test_data::NOTO_SERIF_DISPLAY_TRIMMED).unwrap(); + let cff = Outlines::new(&font).unwrap(); + assert!(!cff.is_cff2()); + assert!(cff.top_dict.var_store.is_none()); + assert!(cff.top_dict.font_dicts.count() == 0); + assert!(!cff.top_dict.private_dict_range.is_empty()); + assert!(cff.top_dict.fd_select.is_none()); + assert_eq!(cff.subfont_count(), 1); + assert_eq!(cff.subfont_index(GlyphId::new(1)), 0); + assert_eq!(cff.global_subrs.count(), 17); + } + + #[test] + fn read_cff2_static() { + let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); + let cff = Outlines::new(&font).unwrap(); + assert!(cff.is_cff2()); + assert!(cff.top_dict.var_store.is_some()); + assert!(cff.top_dict.font_dicts.count() != 0); + assert!(cff.top_dict.private_dict_range.is_empty()); + assert!(cff.top_dict.fd_select.is_none()); + assert_eq!(cff.subfont_count(), 1); + assert_eq!(cff.subfont_index(GlyphId::new(1)), 0); + assert_eq!(cff.global_subrs.count(), 0); + } + + #[test] + fn read_example_cff2_table() { + let cff2 = Cff2::read(FontData::new(font_test_data::cff2::EXAMPLE)).unwrap(); + let top_dict = + TopDict::new(cff2.offset_data().as_bytes(), cff2.top_dict_data(), true).unwrap(); + assert!(top_dict.var_store.is_some()); + assert!(top_dict.font_dicts.count() != 0); + assert!(top_dict.private_dict_range.is_empty()); + assert!(top_dict.fd_select.is_none()); + assert_eq!(cff2.global_subrs().count(), 0); + } + + #[test] + fn cff2_variable_outlines_match_freetype() { + compare_glyphs( + font_test_data::CANTARELL_VF_TRIMMED, + font_test_data::CANTARELL_VF_TRIMMED_GLYPHS, + ); + } + + #[test] + fn cff_static_outlines_match_freetype() { + compare_glyphs( + font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, + font_test_data::NOTO_SERIF_DISPLAY_TRIMMED_GLYPHS, + ); + } + + #[test] + fn unhinted_ends_with_close() { + let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); + let glyph = font.outline_glyphs().get(GlyphId::new(1)).unwrap(); + let mut svg = SvgPen::default(); + glyph.draw(Size::unscaled(), &mut svg).unwrap(); + assert!(svg.to_string().ends_with('Z')); + } + + #[test] + fn hinted_ends_with_close() { + let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); + let glyphs = font.outline_glyphs(); + let hinter = HintingInstance::new( + &glyphs, + Size::unscaled(), + LocationRef::default(), + HintingOptions::default(), + ) + .unwrap(); + let glyph = glyphs.get(GlyphId::new(1)).unwrap(); + let mut svg = SvgPen::default(); + glyph.draw(&hinter, &mut svg).unwrap(); + assert!(svg.to_string().ends_with('Z')); + } + + /// Ensure we don't reject an empty Private DICT + #[test] + fn empty_private_dict() { + let font = FontRef::new(font_test_data::MATERIAL_ICONS_SUBSET).unwrap(); + let outlines = super::Outlines::new(&font).unwrap(); + assert!(outlines.top_dict.private_dict_range.is_empty()); + assert!(outlines.private_dict_range(0).unwrap().is_empty()); + } + + /// Fuzzer caught add with overflow when computing subrs offset. + /// See + #[test] + fn subrs_offset_overflow() { + // A private DICT with an overflowing subrs offset + let private_dict = BeBuffer::new() + .push(0u32) // pad so that range doesn't start with 0 and we overflow + .push(29u8) // integer operator + .push(-1i32) // integer value + .push(19u8) // subrs offset operator + .to_vec(); + // Just don't panic with overflow + assert!( + PrivateDict::new(FontData::new(&private_dict), 4..private_dict.len(), None).is_err() + ); + } + + // Fuzzer caught add with overflow when computing offset to + // var store. + // See + #[test] + fn top_dict_ivs_offset_overflow() { + // A top DICT with a var store offset of -1 which will cause an + // overflow + let top_dict = BeBuffer::new() + .push(29u8) // integer operator + .push(-1i32) // integer value + .push(24u8) // var store offset operator + .to_vec(); + // Just don't panic with overflow + assert!(TopDict::new(&[], &top_dict, true).is_err()); + } + + /// Actually apply a scale when the computed scale factor is + /// equal to Fixed::ONE. + /// + /// Specifically, when upem = 512 and ppem = 8, this results in + /// a scale factor of 65536 which was being interpreted as an + /// unscaled draw request. + #[test] + fn proper_scaling_when_factor_equals_fixed_one() { + let font = FontRef::new(font_test_data::MATERIAL_ICONS_SUBSET).unwrap(); + assert_eq!(font.head().unwrap().units_per_em(), 512); + let glyphs = font.outline_glyphs(); + let glyph = glyphs.get(GlyphId::new(1)).unwrap(); + let mut svg = SvgPen::with_precision(6); + glyph + .draw((Size::new(8.0), LocationRef::default()), &mut svg) + .unwrap(); + // This was initially producing unscaled values like M405.000... + assert!(svg.starts_with("M6.328125,7.000000 L1.671875,7.000000")); + } + + /// For the given font data and extracted outlines, parse the extracted + /// outline data into a set of expected values and compare these with the + /// results generated by the scaler. + /// + /// This will compare all outlines at various sizes and (for variable + /// fonts), locations in variation space. + fn compare_glyphs(font_data: &[u8], expected_outlines: &str) { + use super::super::testing; + let font = FontRef::new(font_data).unwrap(); + let expected_outlines = testing::parse_glyph_outlines(expected_outlines); + let outlines = super::Outlines::new(&font).unwrap(); + let mut path = testing::Path::default(); + for expected_outline in &expected_outlines { + if expected_outline.size == 0.0 && !expected_outline.coords.is_empty() { + continue; + } + let size = (expected_outline.size != 0.0).then_some(expected_outline.size); + path.elements.clear(); + let subfont = outlines + .subfont( + outlines.subfont_index(expected_outline.glyph_id), + size, + &expected_outline.coords, + ) + .unwrap(); + outlines + .draw( + &subfont, + expected_outline.glyph_id, + &expected_outline.coords, + false, + &mut path, + ) + .unwrap(); + if path.elements != expected_outline.path { + panic!( + "mismatch in glyph path for id {} (size: {}, coords: {:?}): path: {:?} expected_path: {:?}", + expected_outline.glyph_id, + expected_outline.size, + expected_outline.coords, + &path.elements, + &expected_outline.path + ); + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,86 @@ +//! Error types associated with outlines. + +use core::fmt; +use read_fonts::types::GlyphId; + +pub use read_fonts::{tables::postscript::Error as CffError, ReadError}; + +pub use super::glyf::HintError; +pub use super::path::ToPathError; + +/// Errors that may occur when drawing glyphs. +#[derive(Clone, Debug)] +pub enum DrawError { + /// No viable sources were available. + NoSources, + /// The requested glyph was not present in the font. + GlyphNotFound(GlyphId), + /// Exceeded memory limits when loading a glyph. + InsufficientMemory, + /// Exceeded a recursion limit when loading a glyph. + RecursionLimitExceeded(GlyphId), + /// Error occurred during hinting. + HintingFailed(HintError), + /// An anchor point had invalid indices. + InvalidAnchorPoint(GlyphId, u16), + /// Error occurred while loading a PostScript (CFF/CFF2) glyph. + PostScript(CffError), + /// Conversion from outline to path failed. + ToPath(ToPathError), + /// Error occurred when reading font data. + Read(ReadError), + /// HarfBuzz style drawing with hints is not supported + // Error rather than silently returning unhinted per f2f discussion. + HarfBuzzHintingUnsupported, +} + +impl From for DrawError { + fn from(value: HintError) -> Self { + Self::HintingFailed(value) + } +} + +impl From for DrawError { + fn from(e: ToPathError) -> Self { + Self::ToPath(e) + } +} + +impl From for DrawError { + fn from(e: ReadError) -> Self { + Self::Read(e) + } +} + +impl From for DrawError { + fn from(value: CffError) -> Self { + Self::PostScript(value) + } +} + +impl fmt::Display for DrawError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::NoSources => write!(f, "No glyph sources are available for the given font"), + Self::GlyphNotFound(gid) => write!(f, "Glyph {gid} was not found in the given font"), + Self::InsufficientMemory => write!(f, "exceeded memory limits"), + Self::RecursionLimitExceeded(gid) => write!( + f, + "Recursion limit ({}) exceeded when loading composite component {gid}", + super::GLYF_COMPOSITE_RECURSION_LIMIT, + ), + Self::HintingFailed(e) => write!(f, "{e}"), + Self::InvalidAnchorPoint(gid, index) => write!( + f, + "Invalid anchor point index ({index}) for composite glyph {gid}", + ), + Self::PostScript(e) => write!(f, "{e}"), + Self::ToPath(e) => write!(f, "{e}"), + Self::Read(e) => write!(f, "{e}"), + Self::HarfBuzzHintingUnsupported => write!( + f, + "HarfBuzz style paths with hinting is not (yet?) supported" + ), + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,387 @@ +use core::ops::RangeInclusive; + +use raw::tables::glyf::PointCoord; +use read_fonts::{ + tables::glyf::{PointFlags, PointMarker}, + tables::gvar::{GlyphDelta, Gvar}, + tables::variations::TupleVariation, + types::{F2Dot14, Fixed, GlyphId, Point}, + ReadError, +}; + +use super::PHANTOM_POINT_COUNT; + +#[derive(Copy, Clone, Debug)] +pub(super) enum AvailableVarMetrics { + /// Full variable metrics with advances and side-bearings. + All, + /// Variable advances but not side-bearings. + Advances, + /// No variable metrics table. + None, +} + +/// Compute a set of deltas for the component offsets of a composite glyph. +/// +/// Interpolation is meaningless for component offsets so this is a +/// specialized function that skips the expensive bits. +pub(super) fn composite_glyph( + gvar: &Gvar, + glyph_id: GlyphId, + coords: &[F2Dot14], + deltas: &mut [Point], +) -> Result<(), ReadError> { + compute_deltas_for_glyph(gvar, glyph_id, coords, deltas, |scalar, tuple, deltas| { + for tuple_delta in tuple.deltas() { + let ix = tuple_delta.position as usize; + if let Some(delta) = deltas.get_mut(ix) { + *delta += tuple_delta.apply_scalar(scalar); + } + } + Ok(()) + })?; + Ok(()) +} + +pub(super) struct SimpleGlyph<'a, C: PointCoord> { + pub points: &'a [Point], + pub flags: &'a mut [PointFlags], + pub contours: &'a [u16], +} + +/// Compute a set of deltas for the points in a simple glyph. +/// +/// This function will use interpolation to infer missing deltas for tuples +/// that contain sparse sets. The `iup_buffer` buffer is temporary storage +/// used for this and the length must be >= glyph.points.len(). +pub(super) fn simple_glyph( + gvar: &Gvar, + glyph_id: GlyphId, + coords: &[F2Dot14], + var_metrics: AvailableVarMetrics, + glyph: SimpleGlyph, + iup_buffer: &mut [Point], + deltas: &mut [Point], +) -> Result<(), ReadError> +where + C: PointCoord, + D: PointCoord, + D: From, +{ + if iup_buffer.len() < glyph.points.len() || glyph.points.len() < PHANTOM_POINT_COUNT { + return Err(ReadError::InvalidArrayLen); + } + for delta in deltas.iter_mut() { + *delta = Default::default(); + } + if gvar.glyph_variation_data(glyph_id).is_err() { + // Empty variation data for a glyph is not an error. + return Ok(()); + }; + let SimpleGlyph { + points, + flags, + contours, + } = glyph; + // Determine which phantom points to modify based on the presence and + // content of the HVAR table. + let actual_len = match var_metrics { + // Modify LSB and advance + AvailableVarMetrics::None => points.len() - 2, + // Modify only LSB + AvailableVarMetrics::Advances => points.len() - 3, + // Modify nothing + AvailableVarMetrics::All => points.len() - PHANTOM_POINT_COUNT, + }; + let deltas = &mut deltas[..actual_len]; + compute_deltas_for_glyph(gvar, glyph_id, coords, deltas, |scalar, tuple, deltas| { + // Infer missing deltas by interpolation. + // Prepare our working buffer by converting the points to 16.16 + // and clearing the HAS_DELTA flags. + for ((flag, point), iup_point) in flags.iter_mut().zip(points).zip(&mut iup_buffer[..]) { + *iup_point = point.map(D::from); + flag.clear_marker(PointMarker::HAS_DELTA); + } + for tuple_delta in tuple.deltas() { + let ix = tuple_delta.position as usize; + if let (Some(flag), Some(point)) = (flags.get_mut(ix), iup_buffer.get_mut(ix)) { + flag.set_marker(PointMarker::HAS_DELTA); + *point += tuple_delta.apply_scalar(scalar); + } + } + interpolate_deltas(points, flags, contours, &mut iup_buffer[..]) + .ok_or(ReadError::OutOfBounds)?; + for ((delta, point), iup_point) in deltas.iter_mut().zip(points).zip(iup_buffer.iter()) { + *delta += *iup_point - point.map(D::from); + } + Ok(()) + })?; + Ok(()) +} + +/// The common parts of simple and complex glyph processing +fn compute_deltas_for_glyph( + gvar: &Gvar, + glyph_id: GlyphId, + coords: &[F2Dot14], + deltas: &mut [Point], + mut apply_tuple_missing_deltas_fn: impl FnMut( + Fixed, + TupleVariation, + &mut [Point], + ) -> Result<(), ReadError>, +) -> Result<(), ReadError> +where + C: PointCoord, + D: PointCoord, + D: From, +{ + for delta in deltas.iter_mut() { + *delta = Default::default(); + } + let Ok(var_data) = gvar.glyph_variation_data(glyph_id) else { + // Empty variation data for a glyph is not an error. + return Ok(()); + }; + for (tuple, scalar) in var_data.active_tuples_at(coords) { + // Fast path: tuple contains all points, we can simply accumulate + // the deltas directly. + if tuple.has_deltas_for_all_points() { + for (delta, tuple_delta) in deltas.iter_mut().zip(tuple.deltas()) { + *delta += tuple_delta.apply_scalar(scalar); + } + } else { + // Slow path is, annoyingly, different for simple vs composite + // so let the caller handle it + apply_tuple_missing_deltas_fn(scalar, tuple, deltas)?; + } + } + Ok(()) +} + +/// Interpolate points without delta values, similar to the IUP hinting +/// instruction. +/// +/// Modeled after the FreeType implementation: +/// +fn interpolate_deltas( + points: &[Point], + flags: &[PointFlags], + contours: &[u16], + out_points: &mut [Point], +) -> Option<()> +where + C: PointCoord, + D: PointCoord, + D: From, +{ + let mut jiggler = Jiggler { points, out_points }; + let mut point_ix = 0usize; + for &end_point_ix in contours { + let end_point_ix = end_point_ix as usize; + let first_point_ix = point_ix; + // Search for first point that has a delta. + while point_ix <= end_point_ix && !flags.get(point_ix)?.has_marker(PointMarker::HAS_DELTA) { + point_ix += 1; + } + // If we didn't find any deltas, no variations in the current tuple + // apply, so skip it. + if point_ix > end_point_ix { + continue; + } + let first_delta_ix = point_ix; + let mut cur_delta_ix = point_ix; + point_ix += 1; + // Search for next point that has a delta... + while point_ix <= end_point_ix { + if flags.get(point_ix)?.has_marker(PointMarker::HAS_DELTA) { + // ... and interpolate intermediate points. + jiggler.interpolate( + cur_delta_ix + 1..=point_ix - 1, + RefPoints(cur_delta_ix, point_ix), + )?; + cur_delta_ix = point_ix; + } + point_ix += 1; + } + // If we only have a single delta, shift the contour. + if cur_delta_ix == first_delta_ix { + jiggler.shift(first_point_ix..=end_point_ix, cur_delta_ix)?; + } else { + // Otherwise, handle remaining points at beginning and end of + // contour. + jiggler.interpolate( + cur_delta_ix + 1..=end_point_ix, + RefPoints(cur_delta_ix, first_delta_ix), + )?; + if first_delta_ix > 0 { + jiggler.interpolate( + first_point_ix..=first_delta_ix - 1, + RefPoints(cur_delta_ix, first_delta_ix), + )?; + } + } + } + Some(()) +} + +struct RefPoints(usize, usize); + +struct Jiggler<'a, C, D> +where + C: PointCoord, + D: PointCoord, + D: From, +{ + points: &'a [Point], + out_points: &'a mut [Point], +} + +impl Jiggler<'_, C, D> +where + C: PointCoord, + D: PointCoord, + D: From, +{ + /// Shift the coordinates of all points in the specified range using the + /// difference given by the point at `ref_ix`. + /// + /// Modeled after the FreeType implementation: + fn shift(&mut self, range: RangeInclusive, ref_ix: usize) -> Option<()> { + let ref_in = self.points.get(ref_ix)?.map(D::from); + let ref_out = self.out_points.get(ref_ix)?; + let delta = *ref_out - ref_in; + if delta.x == D::zeroed() && delta.y == D::zeroed() { + return Some(()); + } + // Apply the reference point delta to the entire range excluding the + // reference point itself which would apply the delta twice. + for out_point in self.out_points.get_mut(*range.start()..ref_ix)? { + *out_point += delta; + } + for out_point in self.out_points.get_mut(ref_ix + 1..=*range.end())? { + *out_point += delta; + } + Some(()) + } + + /// Interpolate the coordinates of all points in the specified range using + /// `ref1_ix` and `ref2_ix` as the reference point indices. + /// + /// Modeled after the FreeType implementation: + /// + /// For details on the algorithm, see: + fn interpolate(&mut self, range: RangeInclusive, ref_points: RefPoints) -> Option<()> { + if range.is_empty() { + return Some(()); + } + // FreeType uses pointer tricks to handle x and y coords with a single piece of code. + // Try a macro instead. + macro_rules! interp_coord { + ($coord:ident) => { + let RefPoints(mut ref1_ix, mut ref2_ix) = ref_points; + if self.points.get(ref1_ix)?.$coord > self.points.get(ref2_ix)?.$coord { + core::mem::swap(&mut ref1_ix, &mut ref2_ix); + } + let in1 = D::from(self.points.get(ref1_ix)?.$coord); + let in2 = D::from(self.points.get(ref2_ix)?.$coord); + let out1 = self.out_points.get(ref1_ix)?.$coord; + let out2 = self.out_points.get(ref2_ix)?.$coord; + // If the reference points have the same coordinate but different delta, + // inferred delta is zero. Otherwise interpolate. + if in1 != in2 || out1 == out2 { + let scale = if in1 != in2 { + (out2 - out1) / (in2 - in1) + } else { + D::zeroed() + }; + let d1 = out1 - in1; + let d2 = out2 - in2; + for (point, out_point) in self + .points + .get(range.clone())? + .iter() + .zip(self.out_points.get_mut(range.clone())?) + { + let mut out = D::from(point.$coord); + if out <= in1 { + out += d1; + } else if out >= in2 { + out += d2; + } else { + out = out1 + (out - in1) * scale; + } + out_point.$coord = out; + } + } + }; + } + interp_coord!(x); + interp_coord!(y); + Some(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn make_points(tuples: &[(i32, i32)]) -> Vec> { + tuples.iter().map(|&(x, y)| Point::new(x, y)).collect() + } + + fn make_working_points_and_flags( + points: &[Point], + deltas: &[Point], + ) -> (Vec>, Vec) { + let working_points = points + .iter() + .zip(deltas) + .map(|(point, delta)| point.map(Fixed::from_i32) + delta.map(Fixed::from_i32)) + .collect(); + let flags = deltas + .iter() + .map(|delta| { + let mut flags = PointFlags::default(); + if delta.x != 0 || delta.y != 0 { + flags.set_marker(PointMarker::HAS_DELTA); + } + flags + }) + .collect(); + (working_points, flags) + } + + #[test] + fn shift() { + let points = make_points(&[(245, 630), (260, 700), (305, 680)]); + // Single delta triggers a full contour shift. + let deltas = make_points(&[(20, -10), (0, 0), (0, 0)]); + let (mut working_points, flags) = make_working_points_and_flags(&points, &deltas); + interpolate_deltas(&points, &flags, &[2], &mut working_points).unwrap(); + let expected = &[ + Point::new(265, 620).map(Fixed::from_i32), + Point::new(280, 690).map(Fixed::from_i32), + Point::new(325, 670).map(Fixed::from_i32), + ]; + assert_eq!(&working_points, expected); + } + + #[test] + fn interpolate() { + // Test taken from the spec: + // https://learn.microsoft.com/en-us/typography/opentype/spec/gvar#inferred-deltas-for-un-referenced-point-numbers + // with a minor adjustment to account for the precision of our fixed point math. + let points = make_points(&[(245, 630), (260, 700), (305, 680)]); + let deltas = make_points(&[(28, -62), (0, 0), (-42, -57)]); + let (mut working_points, flags) = make_working_points_and_flags(&points, &deltas); + interpolate_deltas(&points, &flags, &[2], &mut working_points).unwrap(); + assert_eq!( + working_points[1], + Point::new( + Fixed::from_f64(260.0 + 10.4999237060547), + Fixed::from_f64(700.0 - 57.0) + ) + ); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,97 @@ +//! Tracking function call state. + +use super::{definition::Definition, error::HintErrorKind, program::Program}; + +// FreeType provides a call stack with a depth of 32. +// See +const MAX_DEPTH: usize = 32; + +/// Record of an active invocation of a function or instruction +/// definition. +/// +/// See +#[derive(Copy, Clone, Default)] +pub struct CallRecord { + pub caller_program: Program, + pub return_pc: usize, + pub current_count: u32, + pub definition: Definition, +} + +/// Tracker for nested active function or instruction calls. +#[derive(Default)] +pub struct CallStack { + records: [CallRecord; MAX_DEPTH], + len: usize, +} + +impl CallStack { + pub fn clear(&mut self) { + self.len = 0; + } + + pub fn push(&mut self, record: CallRecord) -> Result<(), HintErrorKind> { + let top = self + .records + .get_mut(self.len) + .ok_or(HintErrorKind::CallStackOverflow)?; + *top = record; + self.len += 1; + Ok(()) + } + + pub fn peek(&self) -> Option<&CallRecord> { + self.records.get(self.len.checked_sub(1)?) + } + + pub fn pop(&mut self) -> Result { + let record = *self.peek().ok_or(HintErrorKind::CallStackUnderflow)?; + self.len -= 1; + Ok(record) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn stack_overflow() { + let mut stack = CallStack::default(); + for i in 0..MAX_DEPTH { + stack.push(record_with_key(i)).unwrap(); + } + assert!(matches!( + stack.push(CallRecord::default()), + Err(HintErrorKind::CallStackOverflow) + )); + } + + #[test] + fn stack_underflow() { + assert!(matches!( + CallStack::default().pop(), + Err(HintErrorKind::CallStackUnderflow) + )); + } + + #[test] + fn stack_push_pop() { + let mut stack = CallStack::default(); + for i in 0..MAX_DEPTH { + stack.push(record_with_key(i)).unwrap(); + } + for i in (0..MAX_DEPTH).rev() { + assert_eq!(stack.pop().unwrap().definition.key(), i as i32); + } + } + + fn record_with_key(key: usize) -> CallRecord { + CallRecord { + caller_program: Program::Glyph, + return_pc: 0, + current_count: 1, + definition: Definition::new(Program::Font, 0..0, key as i32), + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,157 @@ +//! Copy-on-write buffer for CVT and storage area. + +/// Backing store for the CVT and storage area. +/// +/// The CVT and storage area are initialized in the control value program +/// with values that are relevant to a particular size and hinting +/// configuration. However, some fonts contain code in glyph programs +/// that write to these buffers. Any modifications made in a glyph program +/// should not affect future glyphs and thus should not persist beyond +/// execution of that program. To solve this problem, a copy of the buffer +/// is made on the first write in a glyph program and all changes are +/// discarded on completion. +/// +/// For more context, see +/// +/// # Implementation notes +/// +/// The current implementation defers the copy but not the allocation. This +/// is to support the guarantee of no heap allocation when operating on user +/// provided memory. Investigation of hinted Noto fonts suggests that writing +/// to CVT/Storage in glyph programs is common for ttfautohinted fonts so the +/// speculative allocation is likely worthwhile. +pub struct CowSlice<'a> { + data: &'a [i32], + data_mut: &'a mut [i32], + /// True if we've initialized the mutable slice + use_mut: bool, +} + +impl<'a> CowSlice<'a> { + /// Creates a new copy-on-write slice with the given buffers. + /// + /// The `data` buffer is expected to contain the initial data and the content + /// of `data_mut` is ignored unless the [`set`](Self::set) method is called + /// in which case a copy will be made from `data` to `data_mut` and the + /// mutable buffer will be used for all further access. + /// + /// Returns [`CowSliceSizeMismatchError`] if `data.len() != data_mut.len()`. + pub fn new( + data: &'a [i32], + data_mut: &'a mut [i32], + ) -> Result { + if data.len() != data_mut.len() { + return Err(CowSliceSizeMismatchError(data.len(), data_mut.len())); + } + Ok(Self { + data, + data_mut, + use_mut: false, + }) + } + + /// Creates a new copy-on-write slice with the given mutable buffer. + /// + /// This avoids an extra copy and allocation in contexts where the data is + /// already assumed to be mutable (i.e. when executing `fpgm` and `prep` + /// programs). + pub fn new_mut(data_mut: &'a mut [i32]) -> Self { + Self { + use_mut: true, + data: &[], + data_mut, + } + } + + /// Returns the value at the given index. + /// + /// If mutable data has been initialized, reads from that buffer. Otherwise + /// reads from the immutable buffer. + pub fn get(&self, index: usize) -> Option { + if self.use_mut { + self.data_mut.get(index).copied() + } else { + self.data.get(index).copied() + } + } + + /// Writes a value to the given index. + /// + /// If the mutable buffer hasn't been initialized, first performs a full + /// buffer copy. + pub fn set(&mut self, index: usize, value: i32) -> Option<()> { + // Copy from immutable to mutable buffer if we haven't already + if !self.use_mut { + self.data_mut.copy_from_slice(self.data); + self.use_mut = true; + } + *self.data_mut.get_mut(index)? = value; + Some(()) + } + + pub fn len(&self) -> usize { + if self.use_mut { + self.data_mut.len() + } else { + self.data.len() + } + } +} + +/// Error returned when the sizes of the immutable and mutable buffers +/// mismatch when constructing a [`CowSlice`]. +#[derive(Clone, Debug)] +pub struct CowSliceSizeMismatchError(usize, usize); + +impl std::fmt::Display for CowSliceSizeMismatchError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "size mismatch for immutable and mutable buffers: data.len() = {}, data_mut.len() = {}", + self.0, self.1 + ) + } +} + +#[cfg(test)] +mod tests { + use super::{CowSlice, CowSliceSizeMismatchError}; + + #[test] + fn size_mismatch_error() { + let data_mut = &mut [0, 0]; + let result = CowSlice::new(&[1, 2, 3], data_mut); + assert!(matches!(result, Err(CowSliceSizeMismatchError(3, 2)))) + } + + #[test] + fn copy_on_write() { + let data = std::array::from_fn::<_, 16, _>(|i| i as i32); + let mut data_mut = [0i32; 16]; + let mut slice = CowSlice::new(&data, &mut data_mut).unwrap(); + // Not mutable yet + assert!(!slice.use_mut); + for i in 0..data.len() { + assert_eq!(slice.get(i).unwrap(), i as i32); + } + // Modify all values + for i in 0..data.len() { + let value = slice.get(i).unwrap(); + slice.set(i, value * 2).unwrap(); + } + // Now we're mutable + assert!(slice.use_mut); + for i in 0..data.len() { + assert_eq!(slice.get(i).unwrap(), i as i32 * 2); + } + } + + #[test] + fn out_of_bounds() { + let data_mut = &mut [1, 2]; + let slice = CowSlice::new_mut(data_mut); + assert_eq!(slice.get(0), Some(1)); + assert_eq!(slice.get(1), Some(2)); + assert_eq!(slice.get(2), None); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,34 @@ +//! Control value table. + +use super::{cow_slice::CowSlice, error::HintErrorKind, F26Dot6}; + +/// Backing store for the control value table. +/// +/// This is just a wrapper for [`CowSlice`] that converts out of bounds +/// accesses to appropriate errors. +pub struct Cvt<'a>(CowSlice<'a>); + +impl Cvt<'_> { + pub fn get(&self, index: usize) -> Result { + self.0 + .get(index) + .map(F26Dot6::from_bits) + .ok_or(HintErrorKind::InvalidCvtIndex(index)) + } + + pub fn set(&mut self, index: usize, value: F26Dot6) -> Result<(), HintErrorKind> { + self.0 + .set(index, value.to_bits()) + .ok_or(HintErrorKind::InvalidCvtIndex(index)) + } + + pub fn len(&self) -> usize { + self.0.len() + } +} + +impl<'a> From> for Cvt<'a> { + fn from(value: CowSlice<'a>) -> Self { + Self(value) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,265 @@ +//! Management of function and instruction definitions. + +use core::ops::Range; + +use super::{error::HintErrorKind, program::Program}; + +/// Code range and properties for a function or instruction definition. +// Note: this type is designed to support allocation from user memory +// so make sure the fields are all tightly packed and only use integral +// types. +// See +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[repr(C)] +pub struct Definition { + start: u32, + end: u32, + /// The function number for an FDEF or opcode for an IDEF. + key: i32, + _pad: u16, + program: u8, + is_active: u8, +} + +impl Definition { + /// Creates a new definition with the given program, code range and + /// key. + /// + /// The key is either a function number or opcode for function and + /// instruction definitions respectively. + pub fn new(program: Program, code_range: Range, key: i32) -> Self { + Self { + program: program as u8, + // Table sizes are specified in u32 so valid ranges will + // always fit. + start: code_range.start as u32, + end: code_range.end as u32, + key, + _pad: 0, + is_active: 1, + } + } + + /// Returns the program that contains this definition. + pub fn program(&self) -> Program { + match self.program { + 0 => Program::Font, + 1 => Program::ControlValue, + _ => Program::Glyph, + } + } + + /// Returns the function number or opcode. + #[cfg(test)] + pub fn key(&self) -> i32 { + self.key + } + + /// Returns the byte range of the code for this definition in the source + /// program. + pub fn code_range(&self) -> Range { + self.start as usize..self.end as usize + } + + /// Returns true if this definition entry has been defined by a program. + pub fn is_active(&self) -> bool { + self.is_active != 0 + } +} + +/// Map of function number or opcode to code definitions. +/// +/// The `Ref` vs `Mut` distinction exists because these can be modified +/// from the font and control value programs but not from a glyph program. +/// In addition, hinting instance state is immutable once initialized so +/// this captures that in a type safe way. +pub enum DefinitionMap<'a> { + Ref(&'a [Definition]), + Mut(&'a mut [Definition]), +} + +impl DefinitionMap<'_> { + /// Attempts to allocate a new definition entry with the given key. + /// + /// Overriding a definition is legal, so if an existing active entry + /// is found with the same key, that one will be returned. Otherwise, + /// an inactive entry will be chosen. + pub fn allocate(&mut self, key: i32) -> Result<&mut Definition, HintErrorKind> { + let Self::Mut(defs) = self else { + return Err(HintErrorKind::DefinitionInGlyphProgram); + }; + // First, see if we can use key as an index. + // + // For function definitions in well-behaved fonts (that is, where + // function numbers fall within 0..max_function_defs) this will + // always work. + // + // For instruction definitions, this will likely never work + // because the number of instruction definitions is usually small + // (nearly always 0) and the available opcodes are in the higher + // ranges of u8 space. + let ix = if defs + .get(key as usize) + .filter(|def| !def.is_active() || def.key == key) + .is_some() + { + // If the entry is inactive or the key matches, we're good. + key as usize + } else { + // Otherwise, walk backward looking for an active entry with + // a matching key. Keep track of the inactive entry with the + // highest index. + let mut last_inactive_ix = None; + for (i, def) in defs.iter().enumerate().rev() { + if def.is_active() { + if def.key == key { + last_inactive_ix = Some(i); + break; + } + } else if last_inactive_ix.is_none() { + last_inactive_ix = Some(i); + } + } + last_inactive_ix.ok_or(HintErrorKind::TooManyDefinitions)? + }; + let def = defs.get_mut(ix).ok_or(HintErrorKind::TooManyDefinitions)?; + *def = Definition::new(Program::Font, 0..0, key); + Ok(def) + } + + /// Returns the definition with the given key. + pub fn get(&self, key: i32) -> Result<&Definition, HintErrorKind> { + let defs = match self { + Self::Mut(defs) => *defs, + Self::Ref(defs) => *defs, + }; + // Fast path, try to use key as index. + if let Some(def) = defs.get(key as usize) { + if def.is_active() && def.key == key { + return Ok(def); + } + } + // Otherwise, walk backward doing a linear search. + for def in defs.iter().rev() { + if def.is_active() && def.key == key { + return Ok(def); + } + } + Err(HintErrorKind::InvalidDefinition(key as _)) + } + + /// Returns a reference to the underlying definition slice. + #[cfg(test)] + fn as_slice(&self) -> &[Definition] { + match self { + Self::Ref(defs) => defs, + Self::Mut(defs) => defs, + } + } + + /// If the map is mutable, resets all definitions to the default + /// value. + pub fn reset(&mut self) { + if let Self::Mut(defs) = self { + defs.fill(Default::default()) + } + } +} + +/// State containing font defined functions and instructions. +pub struct DefinitionState<'a> { + pub functions: DefinitionMap<'a>, + pub instructions: DefinitionMap<'a>, +} + +impl<'a> DefinitionState<'a> { + pub fn new(functions: DefinitionMap<'a>, instructions: DefinitionMap<'a>) -> Self { + Self { + functions, + instructions, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn too_many_and_invalid() { + let mut buf = vec![Default::default(); 32]; + let mut map = DefinitionMap::Mut(&mut buf); + for i in 0..32 { + map.allocate(i).unwrap(); + } + assert!(matches!( + map.allocate(33), + Err(HintErrorKind::TooManyDefinitions) + )); + assert!(matches!( + map.get(33), + Err(HintErrorKind::InvalidDefinition(33)) + )); + } + + /// Test dense allocation where all keys map directly to indices. This is + /// the case for function definitions in well behaved fonts. + #[test] + fn allocate_dense() { + let mut buf = vec![Default::default(); 32]; + let mut map = DefinitionMap::Mut(&mut buf); + for i in 0..32 { + map.allocate(i).unwrap(); + } + for (i, def) in map.as_slice().iter().enumerate() { + let key = i as i32; + map.get(key).unwrap(); + assert_eq!(def.key, key); + } + } + + /// Test sparse allocation where keys never map to indices. This is + /// generally the case for instruction definitions and would apply + /// to fonts with function definition numbers that all fall outside + /// the range 0..max_function_defs. + #[test] + fn allocate_sparse() { + let mut buf = vec![Default::default(); 3]; + let mut map = DefinitionMap::Mut(&mut buf); + let keys = [42, 88, 107]; + for key in keys { + map.allocate(key).unwrap(); + } + for key in keys { + assert_eq!(map.get(key).unwrap().key, key); + } + } + + /// Test mixed allocation where some keys map to indices and others are + /// subject to fallback allocation. This would be the case for fonts + /// with function definition numbers where some fall inside the range + /// 0..max_function_defs but others don't. + #[test] + fn allocate_mixed() { + let mut buf = vec![Default::default(); 10]; + let mut map = DefinitionMap::Mut(&mut buf); + let keys = [ + 0, 1, 2, 3, // Directly mapped to indices + 123456, -42, -5555, // Fallback allocated + 5, // Also directly mapped + 7, // Would be direct but blocked by prior fallback + ]; + for key in keys { + map.allocate(key).unwrap(); + } + // Check backing store directly to ensure the expected allocation + // pattern. + let expected = [0, 1, 2, 3, 0, 5, 7, -5555, -42, 123456]; + let mapped_keys: Vec<_> = map.as_slice().iter().map(|def| def.key).collect(); + assert_eq!(&expected, mapped_keys.as_slice()); + // Check that all keys are mapped + for key in keys { + assert_eq!(map.get(key).unwrap().key, key); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,244 @@ +//! Arithmetic and math instructions. +//! +//! Implements 10 instructions. +//! +//! See + +use super::{super::math, Engine, HintErrorKind, OpResult}; + +impl Engine<'_> { + /// ADD[] (0x60) + /// + /// Pops: n1, n2 (F26Dot6) + /// Pushes: (n2 + n1) + /// + /// Pops n1 and n2 off the stack and pushes the sum of the two elements + /// onto the stack. + /// + /// See + /// and + pub(super) fn op_add(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok(a.wrapping_add(b))) + } + + /// SUB[] (0x61) + /// + /// Pops: n1, n2 (F26Dot6) + /// Pushes: (n2 - n1) + /// + /// Pops n1 and n2 off the stack and pushes the difference of the two + /// elements onto the stack. + /// + /// See + /// and + pub(super) fn op_sub(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok(a.wrapping_sub(b))) + } + + /// DIV[] (0x62) + /// + /// Pops: n1, n2 (F26Dot6) + /// Pushes: (n2 / n1) + /// + /// Pops n1 and n2 off the stack and pushes onto the stack the quotient + /// obtained by dividing n2 by n1. Note that this truncates rather than + /// rounds the value. + /// + /// See + /// and + pub(super) fn op_div(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| { + if b == 0 { + Err(HintErrorKind::DivideByZero) + } else { + Ok(math::mul_div_no_round(a, 64, b)) + } + }) + } + + /// MUL[] (0x63) + /// + /// Pops: n1, n2 (F26Dot6) + /// Pushes: (n2 * n1) + /// + /// Pops n1 and n2 off the stack and pushes onto the stack the product of + /// the two elements. + /// + /// See + /// and + pub(super) fn op_mul(&mut self) -> OpResult { + self.value_stack + .apply_binary(|a, b| Ok(math::mul_div(a, b, 64))) + } + + /// ABS[] (0x64) + /// + /// Pops: n + /// Pushes: |n|: absolute value of n (F26Dot6) + /// + /// Pops n off the stack and pushes onto the stack the absolute value of n. + /// + /// See + /// and + pub(super) fn op_abs(&mut self) -> OpResult { + self.value_stack.apply_unary(|n| Ok(n.wrapping_abs())) + } + + /// NEG[] (0x65) + /// + /// Pops: n1 + /// Pushes: -n1: negation of n1 (F26Dot6) + /// + /// This instruction pops n1 off the stack and pushes onto the stack the + /// negated value of n1. + /// + /// See + /// and + pub(super) fn op_neg(&mut self) -> OpResult { + self.value_stack.apply_unary(|n1| Ok(n1.wrapping_neg())) + } + + /// FLOOR[] (0x66) + /// + /// Pops: n1: number whose floor is desired (F26Dot6) + /// Pushes: n: floor of n1 (F26Dot6) + /// + /// Pops n1 and returns n, the greatest integer value less than or equal to n1. + /// + /// See + /// and + pub(super) fn op_floor(&mut self) -> OpResult { + self.value_stack.apply_unary(|n1| Ok(math::floor(n1))) + } + + /// CEILING[] (0x67) + /// + /// Pops: n1: number whose ceiling is desired (F26Dot6) + /// Pushes: n: ceiling of n1 (F26Dot6) + /// + /// Pops n1 and returns n, the least integer value greater than or equal to n1. + /// + /// See + /// and + pub(super) fn op_ceiling(&mut self) -> OpResult { + self.value_stack.apply_unary(|n1| Ok(math::ceil(n1))) + } + + /// MAX[] (0x8B) + /// + /// Pops: e1, e2 + /// Pushes: maximum of e1 and e2 + /// + /// Pops two elements, e1 and e2, from the stack and pushes the larger of + /// these two quantities onto the stack. + /// + /// See + /// and + pub(super) fn op_max(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok(a.max(b))) + } + + /// MIN[] (0x8C) + /// + /// Pops: e1, e2 + /// Pushes: minimum of e1 and e2 + /// + /// Pops two elements, e1 and e2, from the stack and pushes the smaller + /// of these two quantities onto the stack. + /// + /// See + /// and + pub(super) fn op_min(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok(a.min(b))) + } +} + +#[cfg(test)] +mod tests { + use super::{super::MockEngine, math, HintErrorKind}; + + /// Test the binary operations that don't require fixed point + /// arithmetic. + #[test] + fn simple_binops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + for b in -10..=10 { + let input = &[a, b]; + engine.test_exec(input, a + b, |engine| { + engine.op_add().unwrap(); + }); + engine.test_exec(input, a - b, |engine| { + engine.op_sub().unwrap(); + }); + engine.test_exec(input, a.max(b), |engine| { + engine.op_max().unwrap(); + }); + engine.test_exec(input, a.min(b), |engine| { + engine.op_min().unwrap(); + }); + } + } + } + + /// Test the unary operations that don't require fixed point + /// arithmetic. + #[test] + fn simple_unops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + let input = &[a]; + engine.test_exec(input, -a, |engine| { + engine.op_neg().unwrap(); + }); + engine.test_exec(input, a.abs(), |engine| { + engine.op_abs().unwrap(); + }); + } + } + + #[test] + fn f26dot6_binops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + for b in -10..=10 { + let a = a * 64 + 30; + let b = b * 64 - 30; + let input = &[a, b]; + engine.test_exec(input, math::mul_div(a, b, 64), |engine| { + engine.op_mul().unwrap(); + }); + if b != 0 { + engine.test_exec(input, math::mul_div_no_round(a, 64, b), |engine| { + engine.op_div().unwrap(); + }); + } else { + engine.value_stack.push(a).unwrap(); + engine.value_stack.push(b).unwrap(); + assert!(matches!(engine.op_div(), Err(HintErrorKind::DivideByZero))); + } + } + } + } + + #[test] + fn f26dot6_unops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + for b in -10..=10 { + let a = a * 64 + b; + let input = &[a]; + engine.test_exec(input, math::floor(a), |engine| { + engine.op_floor().unwrap(); + }); + engine.test_exec(input, math::ceil(a), |engine| { + engine.op_ceiling().unwrap(); + }); + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,319 @@ +//! Managing the flow of control. +//! +//! Implements 6 instructions. +//! +//! See + +use read_fonts::tables::glyf::bytecode::Opcode; + +use super::{Engine, HintErrorKind, OpResult}; + +impl Engine<'_> { + /// If test. + /// + /// IF[] (0x58) + /// + /// Pops: e: stack element + /// + /// Tests the element popped off the stack: if it is zero (FALSE), the + /// instruction pointer is jumped to the next ELSE or EIF instruction + /// in the instruction stream. If the element at the top of the stack is + /// nonzero (TRUE), the next instruction in the instruction stream is + /// executed. Execution continues until an ELSE instruction is encountered + /// or an EIF instruction ends the IF. If an else statement is found before + /// the EIF, the instruction pointer is moved to the EIF statement. + /// + /// See + /// and + pub(super) fn op_if(&mut self) -> OpResult { + if self.value_stack.pop()? == 0 { + // The condition variable is false so we jump to the next + // ELSE or EIF but we have to skip intermediate IF/ELSE/EIF + // instructions. + let mut nest_depth = 1; + let mut out = false; + while !out { + let opcode = self.decode_next_opcode()?; + match opcode { + Opcode::IF => nest_depth += 1, + Opcode::ELSE => out = nest_depth == 1, + Opcode::EIF => { + nest_depth -= 1; + out = nest_depth == 0; + } + _ => {} + } + } + } + Ok(()) + } + + /// Else. + /// + /// ELSE[] (0x1B) + /// + /// Marks the start of the sequence of instructions that are to be executed + /// if an IF instruction encounters a FALSE value on the stack. This + /// sequence of instructions is terminated with an EIF instruction. + /// + /// See + /// and + pub(super) fn op_else(&mut self) -> OpResult { + let mut nest_depth = 1; + while nest_depth != 0 { + let opcode = self.decode_next_opcode()?; + match opcode { + Opcode::IF => nest_depth += 1, + Opcode::EIF => nest_depth -= 1, + _ => {} + } + } + Ok(()) + } + + /// End if. + /// + /// EIF[] (0x59) + /// + /// Marks the end of an IF[] instruction. + /// + /// See + /// and + pub(super) fn op_eif(&mut self) -> OpResult { + // Nothing + Ok(()) + } + + /// Jump relative on true. + /// + /// JROT[] (0x78) + /// + /// Pops: e: stack element + /// offset: number of bytes to move the instruction pointer + /// + /// Pops and tests the element value, and then pops the offset. If the + /// element value is non-zero (TRUE), the signed offset will be added + /// to the instruction pointer and execution will be resumed at the address + /// obtained. Otherwise, the jump is not taken and the next instruction in + /// the instruction stream is executed. The jump is relative to the position + /// of the instruction itself. That is, the instruction pointer is still + /// pointing at the JROT[ ] instruction when offset is added to obtain the + /// new address. + /// + /// See + /// and + pub(super) fn op_jrot(&mut self) -> OpResult { + let e = self.value_stack.pop()?; + self.do_jump(e != 0) + } + + /// Jump. + /// + /// JMPR[] (0x1C) + /// + /// Pops: offset: number of bytes to move the instruction pointer + /// + /// The signed offset is added to the instruction pointer and execution + /// is resumed at the new location in the instruction steam. The jump is + /// relative to the position of the instruction itself. That is, the + /// instruction pointer is still pointing at the JROT[] instruction when + /// offset is added to obtain the new address. + /// + /// See + /// and + pub(super) fn op_jmpr(&mut self) -> OpResult { + self.do_jump(true) + } + + /// Jump relative on false. + /// + /// JROF[] (0x78) + /// + /// Pops: e: stack element + /// offset: number of bytes to move the instruction pointer + /// + /// Pops and tests the element value, and then pops the offset. If the + /// element value is non-zero (TRUE), the signed offset will be added + /// to the instruction pointer and execution will be resumed at the address + /// obtained. Otherwise, the jump is not taken and the next instruction in + /// the instruction stream is executed. The jump is relative to the position + /// of the instruction itself. That is, the instruction pointer is still + /// pointing at the JROT[ ] instruction when offset is added to obtain the + /// new address. + /// + /// Pops and tests the element value, and then pops the offset. If the + /// element value is zero (FALSE), the signed offset will be added to the + /// nstruction pointer and execution will be resumed at the address + /// obtainted. Otherwise, the jump is not taken and the next instruction + /// in the instruction stream is executed. The jump is relative to the + /// position of the instruction itself. That is, the instruction pointer is + /// still pointing at the JROT[ ] instruction when the offset is added to + /// obtain the new address. + /// + /// See + /// and + pub(super) fn op_jrof(&mut self) -> OpResult { + let e = self.value_stack.pop()?; + self.do_jump(e == 0) + } + + /// Common code for jump instructions. + /// + /// See + fn do_jump(&mut self, test: bool) -> OpResult { + // Offset is relative to previous jump instruction and decoder is + // already pointing to next instruction, so subtract one + let jump_offset = self.value_stack.pop()?.wrapping_sub(1); + if test { + if jump_offset < 0 { + if jump_offset == -1 { + // If the offset is -1, we'll just loop in place... forever + return Err(HintErrorKind::InvalidJump); + } + self.loop_budget.doing_backward_jump()?; + } + self.program.decoder.pc = self + .program + .decoder + .pc + .wrapping_add_signed(jump_offset as isize); + } + Ok(()) + } + + fn decode_next_opcode(&mut self) -> Result { + Ok(self + .program + .decoder + .decode() + .ok_or(HintErrorKind::UnexpectedEndOfBytecode)?? + .opcode) + } +} + +#[cfg(test)] +mod tests { + use super::{super::MockEngine, HintErrorKind, Opcode}; + + #[test] + fn if_else() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Some code with nested ifs + #[rustfmt::skip] + let ops = [ + IF, + ADD, // 1 + SUB, + IF, + MUL, // 4 + DIV, + ELSE, // 8 + IUP0, // 7 + IUP1, + EIF, + ELSE, // 10 + RUTG, // 11 + IF, + EIF, + EIF // 14 + ]; + let bytecode = ops.map(|op| op as u8); + engine.program.decoder.bytecode = bytecode.as_slice(); + // Outer if + { + // push a true value to enter the first branch + engine.program.decoder.pc = 1; + engine.value_stack.push(1).unwrap(); + engine.op_if().unwrap(); + assert_eq!(engine.program.decoder.pc, 1); + // false enters the else branch + engine.program.decoder.pc = 1; + engine.value_stack.push(0).unwrap(); + engine.op_if().unwrap(); + assert_eq!(engine.program.decoder.pc, 11); + } + // Inner if + { + // push a true value to enter the first branch + engine.program.decoder.pc = 4; + engine.value_stack.push(1).unwrap(); + engine.op_if().unwrap(); + assert_eq!(engine.program.decoder.pc, 4); + // false enters the else branch + engine.program.decoder.pc = 4; + engine.value_stack.push(0).unwrap(); + engine.op_if().unwrap(); + assert_eq!(engine.program.decoder.pc, 7); + } + // Else with nested if + { + // This jumps to the instruction after the next EIF, skipping any + // nested conditional blocks + engine.program.decoder.pc = 10; + engine.op_else().unwrap(); + assert_eq!(engine.program.decoder.pc, 15); + engine.program.decoder.pc = 8; + engine.op_else().unwrap(); + assert_eq!(engine.program.decoder.pc, 10); + } + } + + #[test] + fn jumps() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Unconditional jump + { + engine.program.decoder.pc = 1000; + engine.value_stack.push(100).unwrap(); + engine.op_jmpr().unwrap(); + assert_eq!(engine.program.decoder.pc, 1099); + } + // Jump if true + { + engine.program.decoder.pc = 1000; + // first test false condition, pc shouldn't change + engine.value_stack.push(100).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_jrot().unwrap(); + assert_eq!(engine.program.decoder.pc, 1000); + // then true condition + engine.value_stack.push(100).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_jrot().unwrap(); + assert_eq!(engine.program.decoder.pc, 1099); + } + // Jump if false + { + engine.program.decoder.pc = 1000; + // first test true condition, pc shouldn't change + engine.value_stack.push(-100).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_jrof().unwrap(); + assert_eq!(engine.program.decoder.pc, 1000); + // then false condition + engine.value_stack.push(-100).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_jrof().unwrap(); + assert_eq!(engine.program.decoder.pc, 899); + } + // Exhaust backward jump loop budget + { + engine.loop_budget.limit = 40; + for i in 0..45 { + engine.value_stack.push(-5).unwrap(); + let result = engine.op_jmpr(); + if i < 39 { + result.unwrap(); + } else { + assert!(matches!( + result, + Err(HintErrorKind::ExceededExecutionBudget) + )); + } + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,163 @@ +//! Managing the control value table. +//! +//! Implements 3 instructions. +//! +//! See + +use super::{super::math::mul, Engine, F26Dot6, OpResult}; + +impl Engine<'_> { + /// Write control value table in pixel units. + /// + /// WCVTP[] (0x44) + /// + /// Pops: value: number in pixels (F26Dot6 fixed point number), + /// location: Control Value Table location (uint32) + /// + /// Pops a location and a value from the stack and puts that value in the + /// specified location in the Control Value Table. This instruction assumes + /// the value is in pixels and not in FUnits. + /// + /// See + /// and + pub(super) fn op_wcvtp(&mut self) -> OpResult { + let value = self.value_stack.pop_f26dot6()?; + let location = self.value_stack.pop_usize()?; + let result = self.cvt.set(location, value); + if self.graphics.is_pedantic { + result + } else { + Ok(()) + } + } + + /// Write control value table in font units. + /// + /// WCVTF[] (0x70) + /// + /// Pops: value: number in pixels (F26Dot6 fixed point number), + /// location: Control Value Table location (uint32) + /// + /// Pops a location and a value from the stack and puts the specified + /// value in the specified address in the Control Value Table. This + /// instruction assumes the value is expressed in FUnits and not pixels. + /// The value is scaled before being written to the table. + /// + /// See + /// and + pub(super) fn op_wcvtf(&mut self) -> OpResult { + let value = self.value_stack.pop()?; + let location = self.value_stack.pop_usize()?; + let result = self.cvt.set( + location, + F26Dot6::from_bits(mul(value, self.graphics.scale)), + ); + if self.graphics.is_pedantic { + result + } else { + Ok(()) + } + } + + /// Read control value table. + /// + /// RCVT[] (0x45) + /// + /// Pops: location: CVT entry number + /// Pushes: value: CVT value (F26Dot6) + /// + /// Pops a location from the stack and pushes the value in the location + /// specified in the Control Value Table onto the stack. + /// + /// See + /// and + pub(super) fn op_rcvt(&mut self) -> OpResult { + let location = self.value_stack.pop()? as usize; + let maybe_value = self.cvt.get(location); + let value = if self.graphics.is_pedantic { + maybe_value? + } else { + maybe_value.unwrap_or_default() + }; + self.value_stack.push(value.to_bits()) + } +} + +#[cfg(test)] +mod tests { + use super::super::{super::math, HintErrorKind, MockEngine}; + + #[test] + fn write_read() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.value_stack.push(i * 2).unwrap(); + engine.op_wcvtp().unwrap(); + } + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.op_rcvt().unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), i * 2); + } + } + + #[test] + fn write_scaled_read() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let scale = 64; + engine.graphics.scale = scale; + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.value_stack.push(i * 2).unwrap(); + // WCVTF takes a value in font units and converts to pixels + // with the current scale + engine.op_wcvtf().unwrap(); + } + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.op_rcvt().unwrap(); + let value = engine.value_stack.pop().unwrap(); + assert_eq!(value, math::mul(i * 2, scale)); + } + } + + #[test] + fn pedantry() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let oob_index = 1000; + // Disable pedantic mode: OOB writes are ignored, OOB reads + // push 0 + engine.graphics.is_pedantic = false; + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_wcvtp().unwrap(); + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_wcvtf().unwrap(); + engine.value_stack.push(oob_index).unwrap(); + engine.op_rcvt().unwrap(); + // Enable pedantic mode: OOB reads/writes error + engine.graphics.is_pedantic = true; + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + assert_eq!( + engine.op_wcvtp(), + Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) + ); + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + assert_eq!( + engine.op_wcvtf(), + Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) + ); + engine.value_stack.push(oob_index).unwrap(); + assert_eq!( + engine.op_rcvt(), + Err(HintErrorKind::InvalidCvtIndex(oob_index as _)) + ); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,288 @@ +//! Reading and writing data. +//! +//! Implements 7 instructions. +//! +//! See + +use super::{ + super::{math, zone::ZonePointer}, + Engine, OpResult, +}; + +impl Engine<'_> { + /// Get coordinate project in to the projection vector. + /// + /// GC\[a\] (0x46 - 0x47) + /// + /// a: 0: use current position of point p + /// 1: use the position of point p in the original outline + /// + /// Pops: p: point number + /// Pushes: value: coordinate location (F26Dot6) + /// + /// Measures the coordinate value of point p on the current + /// projection_vector and pushes the value onto the stack. + /// + /// See + /// and + pub(super) fn op_gc(&mut self, opcode: u8) -> OpResult { + let p = self.value_stack.pop_usize()?; + let gs = &mut self.graphics; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp2, p)]) { + self.value_stack.push(0)?; + return Ok(()); + } + let value = if (opcode & 1) != 0 { + gs.dual_project(gs.zp2().original(p)?, Default::default()) + } else { + gs.project(gs.zp2().point(p)?, Default::default()) + }; + self.value_stack.push(value.to_bits())?; + Ok(()) + } + + /// Set coordinate from the stack using projection vector and freedom + /// vector. + /// + /// SCFS[] (0x48) + /// + /// Pops: value: distance from origin to move point (F26Dot6) + /// p: point number + /// + /// Moves point p from its current position along the freedom_vector so + /// that its component along the projection_vector becomes the value popped + /// off the stack. + /// + /// See + /// and + pub(super) fn op_scfs(&mut self) -> OpResult { + let value = self.value_stack.pop_f26dot6()?; + let p = self.value_stack.pop_usize()?; + let gs = &mut self.graphics; + let projection = gs.project(gs.zp2().point(p)?, Default::default()); + gs.move_point(gs.zp2, p, value.wrapping_sub(projection))?; + if gs.zp2.is_twilight() { + let twilight = gs.zone_mut(ZonePointer::Twilight); + *twilight.original_mut(p)? = twilight.point(p)?; + } + Ok(()) + } + + /// Measure distance. + /// + /// MD\[a\] (0x46 - 0x47) + /// + /// a: 0: measure distance in grid-fitted outline + /// 1: measure distance in original outline + /// + /// Pops: p1: point number + /// p2: point number + /// Pushes: distance (F26Dot6) + /// + /// Measures the distance between outline point p1 and outline point p2. + /// The value returned is in pixels (F26Dot6) If distance is negative, it + /// was measured against the projection vector. Reversing the order in + /// which the points are listed will change the sign of the result. + /// + /// See + /// and + pub(super) fn op_md(&mut self, opcode: u8) -> OpResult { + let p1 = self.value_stack.pop_usize()?; + let p2 = self.value_stack.pop_usize()?; + let gs = &self.graphics; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, p2), (gs.zp1, p1)]) { + self.value_stack.push(0)?; + return Ok(()); + } + let distance = if (opcode & 1) != 0 { + // measure in grid fitted outline + gs.project(gs.zp0().point(p2)?, gs.zp1().point(p1)?) + .to_bits() + } else if gs.zp0.is_twilight() || gs.zp1.is_twilight() { + // special case for twilight zone + gs.dual_project(gs.zp0().original(p2)?, gs.zp1().original(p1)?) + .to_bits() + } else { + // measure in original unscaled outline + math::mul( + gs.dual_project_unscaled(gs.zp0().unscaled(p2), gs.zp1().unscaled(p1)), + gs.unscaled_to_pixels(), + ) + }; + self.value_stack.push(distance) + } + + /// Measure pixels per em. + /// + /// MPPEM[] (0x4B) + /// + /// Pushes: ppem: pixels per em (uint32) + /// + /// This instruction pushes the number of pixels per em onto the stack. + /// Pixels per em is a function of the resolution of the rendering device + /// and the current point size and the current transformation matrix. + /// + /// See + /// and + pub(super) fn op_mppem(&mut self) -> OpResult { + self.value_stack.push(self.graphics.ppem) + } + + /// Measure point size. + /// + /// MPS[] (0x4C) + /// + /// Pushes: pointSize: the size in points of the current glyph (F26Dot6) + /// + /// Measure point size can be used to obtain a value which serves as the + /// basis for choosing whether to branch to an alternative path through the + /// instruction stream. It makes it possible to treat point sizes below or + /// above a certain threshold differently. + /// + /// See + /// and + pub(super) fn op_mps(&mut self) -> OpResult { + // Note: FreeType computes this at + // + // which is mul_div(ppem, 64 * 72, resolution) where resolution + // is always 72 for our purposes (Skia), resulting in ppem * 64. + self.value_stack.push(self.graphics.ppem * 64) + } +} + +#[cfg(test)] +mod tests { + use super::super::{super::zone::ZonePointer, math, Engine, MockEngine}; + use raw::types::F26Dot6; + + #[test] + fn measure_ppem_and_point_size() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let ppem = 20; + engine.graphics.ppem = ppem; + engine.op_mppem().unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), ppem); + engine.op_mps().unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), ppem * 64); + } + + #[test] + fn gc() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + // current point projected coord + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + engine.value_stack.push(1).unwrap(); + engine.op_gc(0).unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), 4); + // original point projected coord + let point = engine.graphics.zones[1].original_mut(1).unwrap(); + point.x = F26Dot6::from_bits(-64); + point.y = F26Dot6::from_bits(521); + engine.value_stack.push(1).unwrap(); + engine.op_gc(1).unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), 176); + } + + #[test] + fn scfs() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + // This instruction is a nop in backward compatibility mode + // and before IUP. + engine.graphics.backward_compatibility = false; + engine.graphics.did_iup_x = true; + engine.graphics.did_iup_y = true; + // use the twilight zone to test the optional code path + engine.graphics.zp2 = ZonePointer::Twilight; + let point = engine.graphics.zones[0].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + // assert we're not currently the same + assert_ne!( + engine.graphics.zones[0].point(1).unwrap(), + engine.graphics.zones[0].original(1).unwrap() + ); + // push point number + engine.value_stack.push(1).unwrap(); + // push value to match + engine.value_stack.push(42).unwrap(); + // set coordinate from stack! + engine.op_scfs().unwrap(); + let point = engine.graphics.zones[0].point(1).unwrap(); + assert_eq!(point.x.to_bits(), 166); + assert_eq!(point.y.to_bits(), -239); + // ensure that we set original = point + assert_eq!(point, engine.graphics.zones[0].original(1).unwrap()); + } + + #[test] + fn md_scaled() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + // first path, measure in grid fitted outline + let zone = engine.graphics.zone_mut(ZonePointer::Glyph); + let point1 = zone.point_mut(1).unwrap(); + point1.x = F26Dot6::from_bits(132); + point1.y = F26Dot6::from_bits(-256); + let point2 = zone.point_mut(3).unwrap(); + point2.x = F26Dot6::from_bits(-64); + point2.y = F26Dot6::from_bits(100); + // now measure + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(3).unwrap(); + engine.op_md(1).unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), 16); + } + + #[test] + fn md_unscaled() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + // second path, measure in original unscaled outline. + // unscaled points are set in mock engine but we need a scale + engine.graphics.scale = 375912; + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(3).unwrap(); + engine.op_md(0).unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), 11); + } + + #[test] + fn md_twilight() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + // final path, measure in original outline, in twilight zone + engine.graphics.zp0 = ZonePointer::Twilight; + engine.graphics.zp1 = ZonePointer::Twilight; + // set some points + let zone = engine.graphics.zone_mut(ZonePointer::Twilight); + let point1 = zone.original_mut(1).unwrap(); + point1.x = F26Dot6::from_bits(132); + point1.y = F26Dot6::from_bits(-256); + let point2 = zone.original_mut(3).unwrap(); + point2.x = F26Dot6::from_bits(-64); + point2.y = F26Dot6::from_bits(100); + // now measure + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(3).unwrap(); + engine.op_md(0).unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), 16); + } + + fn set_test_vectors(engine: &mut Engine) { + let v = math::normalize14(100, 50); + engine.graphics.proj_vector = v; + engine.graphics.dual_proj_vector = v; + engine.graphics.freedom_vector = v; + engine.graphics.update_projection_state(); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,522 @@ +//! Defining and using functions and instructions. +//! +//! Implements 5 instructions. +//! +//! See + +use read_fonts::tables::glyf::bytecode::Opcode; + +use super::{ + super::{definition::Definition, program::Program}, + Engine, HintErrorKind, OpResult, +}; + +/// [Functions|Instructions] may not exceed 64K in size. +/// See +/// See +const MAX_DEFINITION_SIZE: usize = u16::MAX as usize; + +impl Engine<'_> { + /// Function definition. + /// + /// FDEF[] (0x2C) + /// + /// Pops: f: function identifier number + /// + /// Marks the start of a function definition. The argument f is a number + /// that uniquely identifies this function. A function definition can + /// appear only in the Font Program or the CVT program; attempts to invoke + /// the FDEF instruction within a glyph program will result in an error. + /// Functions may not exceed 64K in size. + /// + /// See + /// and + pub(super) fn op_fdef(&mut self) -> OpResult { + let f = self.value_stack.pop()?; + self.do_def(DefKind::Function, f) + } + + /// End function definition. + /// + /// ENDF[] (0x2D) + /// + /// Marks the end of a function definition or an instruction definition. + /// + /// See + /// and + pub(super) fn op_endf(&mut self) -> OpResult { + self.program.leave() + } + + /// Call function. + /// + /// CALL[] (0x2B) + /// + /// Pops: f: function identifier number + /// + /// Calls the function identified by the number f. + /// + /// See + /// and + pub(super) fn op_call(&mut self) -> OpResult { + let f = self.value_stack.pop()?; + self.do_call(DefKind::Function, 1, f) + } + + /// Loop and call function. + /// + /// LOOPCALL[] (0x2a) + /// + /// Pops: f: function identifier number + /// count: number of times to call the function + /// + /// Calls the function f, count number of times. + /// + /// See + /// and + pub(super) fn op_loopcall(&mut self) -> OpResult { + let f = self.value_stack.pop()?; + let count = self.value_stack.pop()?; + if count > 0 { + self.loop_budget.doing_loop_call(count as usize)?; + self.do_call(DefKind::Function, count as u32, f) + } else { + Ok(()) + } + } + + /// Instruction definition. + /// + /// IDEF[] (0x89) + /// + /// Pops: opcode + /// + /// Begins the definition of an instruction. The instruction definition + /// terminates when at ENDF, which is encountered in the instruction + /// stream. Subsequent executions of the opcode popped will be directed + /// to the contents of this instruction definition (IDEF). IDEFs must be + /// defined in the Font Program or the CVT Program; attempts to invoke the + /// IDEF instruction within a glyph program will result in an error. An + /// IDEF affects only undefined opcodes. If the opcode in question is + /// already defined, the interpreter will ignore the IDEF. This is to be + /// used as a patching mechanism for future instructions. Instructions + /// may not exceed 64K in size. + /// + /// See + /// and + pub(super) fn op_idef(&mut self) -> OpResult { + let opcode = self.value_stack.pop()?; + self.do_def(DefKind::Instruction, opcode) + } + + /// Catch all for unhandled opcodes which will attempt to dispatch to a + /// user defined instruction. + pub(super) fn op_unknown(&mut self, opcode: u8) -> OpResult { + self.do_call(DefKind::Instruction, 1, opcode as i32) + } + + /// Common code for FDEF and IDEF. + fn do_def(&mut self, kind: DefKind, key: i32) -> OpResult { + if self.program.initial == Program::Glyph { + return Err(HintErrorKind::DefinitionInGlyphProgram); + } + let defs = match kind { + DefKind::Function => &mut self.definitions.functions, + DefKind::Instruction => &mut self.definitions.instructions, + }; + let def = defs.allocate(key)?; + let start = self.program.decoder.pc; + while let Some(ins) = self.program.decoder.decode() { + let ins = ins?; + match ins.opcode { + Opcode::FDEF | Opcode::IDEF => return Err(HintErrorKind::NestedDefinition), + Opcode::ENDF => { + let range = start..ins.pc + 1; + if self.graphics.is_pedantic && range.len() > MAX_DEFINITION_SIZE { + *def = Default::default(); + return Err(HintErrorKind::DefinitionTooLarge); + } + *def = Definition::new(self.program.current, range, key); + return Ok(()); + } + _ => {} + } + } + Err(HintErrorKind::UnexpectedEndOfBytecode) + } + + /// Common code for CALL, LOOPCALL and unknown opcode handling. + fn do_call(&mut self, kind: DefKind, count: u32, key: i32) -> OpResult { + if count == 0 { + return Ok(()); + } + let def = match kind { + DefKind::Function => self.definitions.functions.get(key), + DefKind::Instruction => match self.definitions.instructions.get(key) { + // Remap an invalid definition error to unhandled opcode + Err(HintErrorKind::InvalidDefinition(opcode)) => Err( + HintErrorKind::UnhandledOpcode(Opcode::from_byte(opcode as u8)), + ), + result => result, + }, + }; + self.program.enter(*def?, count) + } +} + +enum DefKind { + Function, + Instruction, +} + +#[cfg(test)] +mod tests { + use super::{ + super::{ + super::program::{Program, ProgramState}, + Engine, MockEngine, + }, + HintErrorKind, Opcode, MAX_DEFINITION_SIZE, + }; + + /// Define two functions, one of which calls the other with + /// both CALL and LOOPCALL. + #[test] + fn define_function_call_loopcall() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB001), 1, 0, + // FDEF 0: adds 2 to top stack value + op(FDEF), + op(PUSHB000), 2, + op(ADD), + op(ENDF), + // FDEF 1: calls FDEF 0 once, loop calls 5 times, then + // negates the result + op(FDEF), + op(PUSHB000), 0, + op(CALL), + op(PUSHB001), 5, 0, + op(LOOPCALL), + op(NEG), + op(ENDF), + ]; + // Execute this code to define our functions + engine.set_font_code(&font_code); + engine.run().unwrap(); + // Call FDEF 1 with value of 10 on the stack: + // * calls FDEF 0 which adds 2 + // * loop calls FDEF 0 an additional 5 times which adds a total of 10 + // * then negates the result + // leaving -22 on the stack + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_call().unwrap(); + engine.run().unwrap(); + assert_eq!(engine.value_stack.pop().ok(), Some(-22)); + } + + /// Control value programs can override functions defined in the font + /// program based on instance state. + #[test] + fn override_function() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB001), 0, 0, + // FDEF 0: adds 2 to top stack value + op(FDEF), + op(PUSHB000), 2, + op(ADD), + op(ENDF), + // Redefine FDEF 0: subtract 2 instead + op(FDEF), + op(PUSHB000), 2, + op(SUB), + op(ENDF), + ]; + // Execute this code to define our functions + engine.set_font_code(&font_code); + engine.run().unwrap(); + // Call FDEF 0 with value of 10 on the stack: + // * should subtract 2 rather than add + // leaving 8 on the stack + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_call().unwrap(); + engine.run().unwrap(); + assert_eq!(engine.value_stack.pop().ok(), Some(8)); + } + + /// Executes a call from a CV program into a font program. + /// + /// Tests ProgramState bytecode/decoder management. + #[test] + fn call_different_program() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB000), 0, + // FDEF 0: adds 2 to top stack value + op(FDEF), + op(PUSHB000), 2, + op(ADD), + op(ENDF), + ]; + #[rustfmt::skip] + let cv_code = [ + // Call function defined in font program and negate result + op(PUSHB001), 40, 0, + op(CALL), + op(NEG) + ]; + let glyph_code = &[]; + // Run font program first to define the function + engine.program = ProgramState::new(&font_code, &cv_code, glyph_code, Program::Font); + engine.run().unwrap(); + // Now run CV program which calls into the font program + engine.program = ProgramState::new(&font_code, &cv_code, glyph_code, Program::ControlValue); + engine.run().unwrap(); + // Executing CV program: + // * pushes 40 to the stack + // * calls FDEF 0 in font program which adds 2 + // * returns to CV program + // * negates the value + // leaving -42 on the stack + assert_eq!(engine.value_stack.pop().ok(), Some(-42)); + } + + /// Fail when we exceed loop call budget. + #[test] + fn loopcall_budget() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let limit = engine.loop_budget.limit; + #[rustfmt::skip] + let font_code = [ + op(PUSHB001), 1, 0, + // FDEF 0: does nothing + op(FDEF), + op(ENDF), + // FDEF 1: loop calls FDEF 0 twice, exceeding the budget on the + // second attempt + op(FDEF), + op(PUSHB001), limit as u8, 0, + op(LOOPCALL), + op(PUSHB001), 1, 0, + op(LOOPCALL), // pc = 13 + op(ENDF), + ]; + // Execute this code to define our functions + engine.set_font_code(&font_code); + engine.run().unwrap(); + // Call FDEF 1 which attempts to loop call FDEF 0 (limit + 1) times + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_call().unwrap(); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::ExceededExecutionBudget)); + assert_eq!(err.pc, 13); + } + + /// Defines an instruction using an available opcode and executes it. + #[test] + fn define_instruction_and_use() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + // IDEF 0x93: adds 2 to top stack value + op(PUSHB000), op(INS93), + op(IDEF), + op(PUSHB000), 2, + op(ADD), + op(ENDF), + // FDEF 0: uses defined instruction 0x93 and negates the result + op(PUSHB000), 0, + op(FDEF), + op(INS93), + op(NEG), + op(ENDF), + ]; + // Execute this code to define our functions + engine.set_font_code(&font_code); + engine.run().unwrap(); + // Call FDEF 0 with value of 10 on the stack: + // * executes defined instruction 0x93 + // * then negates the result + // leaving -12 on the stack + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_call().unwrap(); + engine.run().unwrap(); + assert_eq!(engine.value_stack.pop().ok(), Some(-12)); + } + + // Invalid to nest definitions. + #[test] + fn nested_definition() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB001), 1, 0, + op(FDEF), // pc = 3 + op(FDEF), + op(ENDF), + op(ENDF), + ]; + // Execute this code to define our functions + engine.set_font_code(&font_code); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::NestedDefinition)); + assert_eq!(err.pc, 3); + } + + // Invalid to modify definitions from the glyph program. + #[test] + fn definition_in_glyph_program() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB000), 0, + op(FDEF), // pc = 2 + op(ENDF), + ]; + engine.set_font_code(&font_code); + engine.program.initial = Program::Glyph; + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::DefinitionInGlyphProgram)); + assert_eq!(err.pc, 2); + } + + #[test] + fn undefined_function() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.value_stack.push(111).unwrap(); + assert!(matches!( + engine.op_call(), + Err(HintErrorKind::InvalidDefinition(111)) + )); + } + + /// Fun function that just calls itself :) + #[test] + fn infinite_recursion() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + // FDEF 0: call FDEF 0 + op(PUSHB000), 0, + op(FDEF), + op(PUSHB000), 0, + op(CALL), // pc = 5 + op(ENDF), + ]; + engine.set_font_code(&font_code); + engine.run().unwrap(); + // Call stack overflow + engine.value_stack.push(0).unwrap(); + engine.op_call().unwrap(); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::CallStackOverflow)); + assert_eq!(err.pc, 5); + } + + #[test] + fn call_stack_underflow() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(ENDF) + ]; + engine.set_font_code(&font_code); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::CallStackUnderflow)); + assert_eq!(err.pc, 0); + } + + #[test] + fn unhandled_opcode() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(Opcode::INS28), + ]; + engine.set_font_code(&font_code); + let err = engine.run().unwrap_err(); + assert!(matches!( + err.kind, + HintErrorKind::UnhandledOpcode(Opcode::INS28) + )); + assert_eq!(err.pc, 0); + } + + #[test] + fn too_many_definitions() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + #[rustfmt::skip] + let font_code = [ + op(PUSHB101), 0, 1, 2, 3, 4, 5, + op(FDEF), op(ENDF), + op(FDEF), op(ENDF), + op(FDEF), op(ENDF), + op(FDEF), op(ENDF), + op(FDEF), op(ENDF), + op(FDEF), op(ENDF), + ]; + engine.set_font_code(&font_code); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::TooManyDefinitions)); + assert_eq!(err.pc, 17); + } + + #[test] + fn big_definition() { + use Opcode::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let mut font_code = vec![]; + font_code.extend_from_slice(&[op(PUSHB000), 0, op(FDEF)]); + font_code.extend(core::iter::repeat(op(NEG)).take(MAX_DEFINITION_SIZE + 1)); + font_code.push(op(ENDF)); + engine.set_font_code(&font_code); + engine.graphics.is_pedantic = true; + engine.value_stack.push(1).unwrap(); + let err = engine.run().unwrap_err(); + assert!(matches!(err.kind, HintErrorKind::DefinitionTooLarge)); + assert_eq!(err.pc, 2); + } + + fn op(opcode: Opcode) -> u8 { + opcode as u8 + } + + impl<'a> Engine<'a> { + fn set_font_code(&mut self, code: &'a [u8]) { + self.program.bytecode[0] = code; + self.program.decoder.bytecode = code; + self.program.current = Program::Font; + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,195 @@ +//! Managing delta exceptions. +//! +//! Implements 6 instructions. +//! +//! See + +use super::{super::graphics::CoordAxis, Engine, F26Dot6, OpResult}; +use read_fonts::tables::glyf::bytecode::Opcode; + +impl Engine<'_> { + /// Delta exception P1, P2 and P3. + /// + /// DELTAP1[] (0x5D) + /// DELTAP2[] (0x71) + /// DELTAP3[] (0x72) + /// + /// Pops: n: number of pairs of exception specifications and points (uint32) + /// p1, arg1, p2, arg2, ..., pnn argn: n pairs of exception specifications + /// and points (pairs of uint32s) + /// + /// DELTAP moves the specified points at the size and by the + /// amount specified in the paired argument. An arbitrary number of points + /// and arguments can be specified. + /// + /// The only difference between the instructions is the bias added to the + /// point adjustment. + /// + /// See + /// and + pub(super) fn op_deltap(&mut self, opcode: Opcode) -> OpResult { + let gs = &mut self.graphics; + let ppem = gs.ppem as u32; + let n = self.value_stack.pop_usize()?; + let bias = match opcode { + Opcode::DELTAP2 => 16, + Opcode::DELTAP3 => 32, + _ => 0, + } + gs.delta_base as u32; + let back_compat = gs.backward_compatibility; + let did_iup = gs.did_iup_x && gs.did_iup_y; + for _ in 0..n { + let point_ix = self.value_stack.pop_usize()?; + let mut b = self.value_stack.pop()?; + // FreeType notes that some popular fonts contain invalid DELTAP + // instructions so out of bounds points are ignored. + // See + if point_ix >= gs.zp0().points.len() { + continue; + } + let mut c = (b as u32 & 0xF0) >> 4; + c += bias; + if ppem == c { + // Blindly copying FreeType here + // + b = (b & 0xF) - 8; + if b >= 0 { + b += 1; + } + b *= 1 << (6 - gs.delta_shift as i32); + let distance = F26Dot6::from_bits(b); + if back_compat { + if !did_iup + && ((gs.is_composite && gs.freedom_vector.y != 0) + || gs.zp0().is_touched(point_ix, CoordAxis::Y)?) + { + gs.move_point(gs.zp0, point_ix, distance)?; + } + } else { + gs.move_point(gs.zp0, point_ix, distance)?; + } + } + } + Ok(()) + } + + /// Delta exception C1, C2 and C3. + /// + /// DELTAC1[] (0x73) + /// DELTAC2[] (0x74) + /// DELTAC3[] (0x75) + /// + /// Pops: n: number of pairs of exception specifications and CVT entry numbers (uint32) + /// c1, arg1, c2, arg2,..., cn, argn: (pairs of uint32s) + /// + /// DELTAC changes the value in each CVT entry specified at the size and + /// by the amount specified in its paired argument. + /// + /// The only difference between the instructions is the bias added to the + /// adjustment. + /// + /// See + /// and + pub(super) fn op_deltac(&mut self, opcode: Opcode) -> OpResult { + let gs = &mut self.graphics; + let ppem = gs.ppem as u32; + let n = self.value_stack.pop_usize()?; + let bias = match opcode { + Opcode::DELTAC2 => 16, + Opcode::DELTAC3 => 32, + _ => 0, + } + gs.delta_base as u32; + for _ in 0..n { + let cvt_ix = self.value_stack.pop_usize()?; + let mut b = self.value_stack.pop()?; + let mut c = (b as u32 & 0xF0) >> 4; + c += bias; + if ppem == c { + // See + b = (b & 0xF) - 8; + if b >= 0 { + b += 1; + } + b *= 1 << (6 - gs.delta_shift as i32); + let cvt_val = self.cvt.get(cvt_ix)?; + self.cvt.set(cvt_ix, cvt_val + F26Dot6::from_bits(b))?; + } + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::super::{super::zone::ZonePointer, MockEngine}; + use raw::{ + tables::glyf::bytecode::Opcode, + types::{F26Dot6, Point}, + }; + + #[test] + fn deltap() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + let raw_ppem = 16; + let raw_adjustment = 7; + for (point_ix, (ppem_bias, opcode)) in [ + (0, Opcode::DELTAP1), + (16, Opcode::DELTAP2), + (32, Opcode::DELTAP3), + ] + .iter() + .enumerate() + { + let ppem = raw_ppem + ppem_bias; + engine.graphics.ppem = ppem; + // packed ppem + adjustment entry + let packed_ppem = raw_ppem - engine.graphics.delta_base as i32; + engine + .value_stack + .push((packed_ppem << 4) | raw_adjustment) + .unwrap(); + // point index + engine.value_stack.push(point_ix as _).unwrap(); + // exception count + engine.value_stack.push(1).unwrap(); + engine.op_deltap(*opcode).unwrap(); + let point = engine.graphics.zones[1].point(point_ix).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(-8, 0)); + } + } + + #[test] + fn deltac() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let raw_ppem = 16; + let raw_adjustment = 7; + for (cvt_ix, (ppem_bias, opcode)) in [ + (0, Opcode::DELTAC1), + (16, Opcode::DELTAC2), + (32, Opcode::DELTAC3), + ] + .iter() + .enumerate() + { + let ppem = raw_ppem + ppem_bias; + engine.graphics.ppem = ppem; + // packed ppem + adjustment entry + let packed_ppem = raw_ppem - engine.graphics.delta_base as i32; + engine + .value_stack + .push((packed_ppem << 4) | raw_adjustment) + .unwrap(); + // cvt index + engine.value_stack.push(cvt_ix as _).unwrap(); + // exception count + engine.value_stack.push(1).unwrap(); + engine.op_deltac(*opcode).unwrap(); + let value = engine.cvt.get(cvt_ix).unwrap(); + assert_eq!(value.to_bits(), -8); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,243 @@ +//! Instruction decoding and dispatch. + +use read_fonts::tables::glyf::bytecode::Opcode; + +use super::{super::program::Program, Engine, HintError, HintErrorKind, Instruction}; + +/// Maximum number of instructions we will execute in `Engine::run()`. This +/// is used to ensure termination of a hinting program. +/// See +const MAX_RUN_INSTRUCTIONS: usize = 1_000_000; + +impl<'a> Engine<'a> { + /// Resets state for the specified program and executes all instructions. + pub fn run_program(&mut self, program: Program, is_pedantic: bool) -> Result<(), HintError> { + self.reset(program, is_pedantic); + self.run() + } + + /// Set internal state for running the specified program. + pub fn reset(&mut self, program: Program, is_pedantic: bool) { + self.program.reset(program); + // Reset overall graphics state, keeping the retained bits. + self.graphics.reset(); + self.graphics.is_pedantic = is_pedantic; + self.loop_budget.reset(); + // Program specific setup. + match program { + Program::Font => { + self.definitions.functions.reset(); + self.definitions.instructions.reset(); + } + Program::ControlValue => { + self.graphics.backward_compatibility = false; + } + Program::Glyph => { + // Instruct control bit 1 says we reset retained graphics state + // to default values. + if self.graphics.instruct_control & 2 != 0 { + self.graphics.reset_retained(); + } + // Set backward compatibility mode + if self.graphics.target.preserve_linear_metrics() { + self.graphics.backward_compatibility = true; + } else if self.graphics.target.is_smooth() { + self.graphics.backward_compatibility = + (self.graphics.instruct_control & 0x4) == 0; + } else { + self.graphics.backward_compatibility = false; + } + } + } + } + + /// Decodes and dispatches all instructions until completion or error. + pub fn run(&mut self) -> Result<(), HintError> { + let mut count = 0; + while let Some(ins) = self.decode() { + let ins = ins?; + self.dispatch(&ins)?; + count += 1; + if count > MAX_RUN_INSTRUCTIONS { + return Err(HintError { + program: self.program.current, + glyph_id: None, + pc: ins.pc, + opcode: Some(ins.opcode), + kind: HintErrorKind::ExceededExecutionBudget, + }); + } + } + Ok(()) + } + + /// Decodes the next instruction from the current program. + pub fn decode(&mut self) -> Option, HintError>> { + let ins = self.program.decoder.decode()?; + Some(ins.map_err(|_| HintError { + program: self.program.current, + glyph_id: None, + pc: self.program.decoder.pc, + opcode: None, + kind: HintErrorKind::UnexpectedEndOfBytecode, + })) + } + + /// Executes the appropriate code for the given instruction. + pub fn dispatch(&mut self, ins: &Instruction) -> Result<(), HintError> { + let current_program = self.program.current; + self.dispatch_inner(ins).map_err(|kind| HintError { + program: current_program, + glyph_id: None, + pc: ins.pc, + opcode: Some(ins.opcode), + kind, + }) + } + + fn dispatch_inner(&mut self, ins: &Instruction) -> Result<(), HintErrorKind> { + use Opcode::*; + let opcode = ins.opcode; + let raw_opcode = opcode as u8; + match ins.opcode { + SVTCA0 | SVTCA1 | SPVTCA0 | SPVTCA1 | SFVTCA0 | SFVTCA1 => self.op_svtca(raw_opcode)?, + SPVTL0 | SPVTL1 | SFVTL0 | SFVTL1 => self.op_svtl(raw_opcode)?, + SPVFS => self.op_spvfs()?, + SFVFS => self.op_sfvfs()?, + GPV => self.op_gpv()?, + GFV => self.op_gfv()?, + SFVTPV => self.op_sfvtpv()?, + ISECT => self.op_isect()?, + SRP0 => self.op_srp0()?, + SRP1 => self.op_srp1()?, + SRP2 => self.op_srp2()?, + SZP0 => self.op_szp0()?, + SZP1 => self.op_szp1()?, + SZP2 => self.op_szp2()?, + SZPS => self.op_szps()?, + SLOOP => self.op_sloop()?, + RTG => self.op_rtg()?, + RTHG => self.op_rthg()?, + SMD => self.op_smd()?, + ELSE => self.op_else()?, + JMPR => self.op_jmpr()?, + SCVTCI => self.op_scvtci()?, + SSWCI => self.op_sswci()?, + SSW => self.op_ssw()?, + DUP => self.op_dup()?, + POP => self.op_pop()?, + CLEAR => self.op_clear()?, + SWAP => self.op_swap()?, + DEPTH => self.op_depth()?, + CINDEX => self.op_cindex()?, + MINDEX => self.op_mindex()?, + ALIGNPTS => self.op_alignpts()?, + // UNUSED: 0x28 + UTP => self.op_utp()?, + LOOPCALL => self.op_loopcall()?, + CALL => self.op_call()?, + FDEF => self.op_fdef()?, + ENDF => self.op_endf()?, + MDAP0 | MDAP1 => self.op_mdap(raw_opcode)?, + IUP0 | IUP1 => self.op_iup(raw_opcode)?, + SHP0 | SHP1 => self.op_shp(raw_opcode)?, + SHC0 | SHC1 => self.op_shc(raw_opcode)?, + SHZ0 | SHZ1 => self.op_shz(raw_opcode)?, + SHPIX => self.op_shpix()?, + IP => self.op_ip()?, + MSIRP0 | MSIRP1 => self.op_msirp(raw_opcode)?, + ALIGNRP => self.op_alignrp()?, + RTDG => self.op_rtdg()?, + MIAP0 | MIAP1 => self.op_miap(raw_opcode)?, + NPUSHB | NPUSHW => self.op_push(&ins.inline_operands)?, + WS => self.op_ws()?, + RS => self.op_rs()?, + WCVTP => self.op_wcvtp()?, + RCVT => self.op_rcvt()?, + GC0 | GC1 => self.op_gc(raw_opcode)?, + SCFS => self.op_scfs()?, + MD0 | MD1 => self.op_md(raw_opcode)?, + MPPEM => self.op_mppem()?, + MPS => self.op_mps()?, + FLIPON => self.op_flipon()?, + FLIPOFF => self.op_flipoff()?, + // Should be unused in production fonts, but we may want to + // support debugging at some point. Just pops a value from + // the stack. + DEBUG => { + self.value_stack.pop()?; + } + LT => self.op_lt()?, + LTEQ => self.op_lteq()?, + GT => self.op_gt()?, + GTEQ => self.op_gteq()?, + EQ => self.op_eq()?, + NEQ => self.op_neq()?, + ODD => self.op_odd()?, + EVEN => self.op_even()?, + IF => self.op_if()?, + EIF => self.op_eif()?, + AND => self.op_and()?, + OR => self.op_or()?, + NOT => self.op_not()?, + DELTAP1 => self.op_deltap(opcode)?, + SDB => self.op_sdb()?, + SDS => self.op_sds()?, + ADD => self.op_add()?, + SUB => self.op_sub()?, + DIV => self.op_div()?, + MUL => self.op_mul()?, + ABS => self.op_abs()?, + NEG => self.op_neg()?, + FLOOR => self.op_floor()?, + CEILING => self.op_ceiling()?, + ROUND00 | ROUND01 | ROUND10 | ROUND11 => self.op_round()?, + // "No round" means do nothing :) + NROUND00 | NROUND01 | NROUND10 | NROUND11 => {} + WCVTF => self.op_wcvtf()?, + DELTAP2 | DELTAP3 => self.op_deltap(opcode)?, + DELTAC1 | DELTAC2 | DELTAC3 => self.op_deltac(opcode)?, + SROUND => self.op_sround()?, + S45ROUND => self.op_s45round()?, + JROT => self.op_jrot()?, + JROF => self.op_jrof()?, + ROFF => self.op_roff()?, + // UNUSED: 0x7B + RUTG => self.op_rutg()?, + RDTG => self.op_rdtg()?, + SANGW => self.op_sangw()?, + // Unsupported instruction, do nothing + AA => {} + FLIPPT => self.op_flippt()?, + FLIPRGON => self.op_fliprgon()?, + FLIPRGOFF => self.op_fliprgoff()?, + // UNUSED: 0x83 | 0x84 + SCANCTRL => self.op_scanctrl()?, + SDPVTL0 | SDPVTL1 => self.op_sdpvtl(raw_opcode)?, + GETINFO => self.op_getinfo()?, + IDEF => self.op_idef()?, + ROLL => self.op_roll()?, + MAX => self.op_max()?, + MIN => self.op_min()?, + SCANTYPE => self.op_scantype()?, + INSTCTRL => self.op_instctrl()?, + // UNUSED: 0x8F | 0x90 (ADJUST?) + GETVARIATION => self.op_getvariation()?, + GETDATA => self.op_getdata()?, + _ => { + // FreeType handles MIRP, MDRP and pushes here. + // + if opcode >= MIRP00000 { + self.op_mirp(raw_opcode)? + } else if opcode >= MDRP00000 { + self.op_mdrp(raw_opcode)? + } else if opcode >= PUSHB000 { + self.op_push(&ins.inline_operands)?; + } else { + return self.op_unknown(opcode as u8); + } + } + } + Ok(()) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1154 @@ +//! Managing the graphics state. +//! +//! Implements 45 instructions. +//! +//! See + +use super::{ + super::{math, program::Program, round::RoundMode}, + Engine, F26Dot6, HintErrorKind, OpResult, Point, +}; + +impl Engine<'_> { + /// Set vectors to coordinate axis. + /// + /// SVTCA\[a\] (0x00 - 0x01) + /// + /// Sets both the projection_vector and freedom_vector to the same one of + /// the coordinate axes. + /// + /// See + /// + /// SPVTCA\[a\] (0x02 - 0x03) + /// + /// Sets the projection_vector to one of the coordinate axes depending on + /// the value of the flag a. + /// + /// See + /// + /// SFVTCA\[a\] (0x04 - 0x05) + /// + /// Sets the freedom_vector to one of the coordinate axes depending on + /// the value of the flag a. + /// + /// See + /// + /// FreeType combines these into a single function using some bit magic on + /// the opcode to determine which axes and vectors to set. + /// + /// See + pub(super) fn op_svtca(&mut self, opcode: u8) -> OpResult { + let opcode = opcode as i32; + // The low bit of the opcode determines the axis to set (1 = x, 0 = y). + let x = (opcode & 1) << 14; + let y = x ^ 0x4000; + // Opcodes 0..4 set the projection vector. + if opcode < 4 { + self.graphics.proj_vector.x = x; + self.graphics.proj_vector.y = y; + self.graphics.dual_proj_vector.x = x; + self.graphics.dual_proj_vector.y = y; + } + // Opcodes with bit 2 unset modify the freedom vector. + if opcode & 2 == 0 { + self.graphics.freedom_vector.x = x; + self.graphics.freedom_vector.y = y; + } + self.graphics.update_projection_state(); + Ok(()) + } + + /// Set vectors to line. + /// + /// SPVTL\[a\] (0x06 - 0x07) + /// + /// Sets the projection_vector to a unit vector parallel or perpendicular + /// to the line segment from point p1 to point p2. + /// + /// See + /// + /// SFVTL\[a\] (0x08 - 0x09) + /// + /// Sets the freedom_vector to a unit vector parallel or perpendicular + /// to the line segment from point p1 to point p2. + /// + /// See + /// + /// Pops: p1, p2 (point number) + /// + /// See + pub(super) fn op_svtl(&mut self, opcode: u8) -> OpResult { + let index1 = self.value_stack.pop_usize()?; + let index2 = self.value_stack.pop_usize()?; + let is_parallel = opcode & 1 == 0; + let p1 = self.graphics.zp1().point(index2)?; + let p2 = self.graphics.zp2().point(index1)?; + let vector = line_vector(p1, p2, is_parallel); + if opcode < 8 { + self.graphics.proj_vector = vector; + self.graphics.dual_proj_vector = vector; + } else { + self.graphics.freedom_vector = vector; + } + self.graphics.update_projection_state(); + Ok(()) + } + + /// Set freedom vector to projection vector. + /// + /// SFVTPV[] (0x0E) + /// + /// Sets the freedom_vector to be the same as the projection_vector. + /// + /// See + /// and + pub(super) fn op_sfvtpv(&mut self) -> OpResult { + self.graphics.freedom_vector = self.graphics.proj_vector; + self.graphics.update_projection_state(); + Ok(()) + } + + /// Set dual projection vector to line. + /// + /// SDPVTL\[a\] (0x86 - 0x87) + /// + /// Pops: p1, p2 (point number) + /// + /// Pops two point numbers from the stack and uses them to specify a line + /// that defines a second, dual_projection_vector. + /// + /// See + /// and + pub(super) fn op_sdpvtl(&mut self, opcode: u8) -> OpResult { + let index1 = self.value_stack.pop_usize()?; + let index2 = self.value_stack.pop_usize()?; + let is_parallel = opcode & 1 == 0; + // First set the dual projection vector from *original* points. + let p1 = self.graphics.zp1().original(index2)?; + let p2 = self.graphics.zp2().original(index1)?; + self.graphics.dual_proj_vector = line_vector(p1, p2, is_parallel); + // Now set the projection vector from the *current* points. + let p1 = self.graphics.zp1().point(index2)?; + let p2 = self.graphics.zp2().point(index1)?; + self.graphics.proj_vector = line_vector(p1, p2, is_parallel); + self.graphics.update_projection_state(); + Ok(()) + } + + /// Set projection vector from stack. + /// + /// SPVFS[] (0x0A) + /// + /// Pops: y, x (2.14 fixed point numbers padded with zeroes) + /// + /// Sets the direction of the projection_vector, using values x and y taken + /// from the stack, so that its projections onto the x and y-axes are x and + /// y, which are specified as signed (two’s complement) fixed-point (2.14) + /// numbers. The square root of (x2 + y2) must be equal to 0x4000 (hex) + /// + /// See + /// and + pub(super) fn op_spvfs(&mut self) -> OpResult { + let y = self.value_stack.pop()? as i16 as i32; + let x = self.value_stack.pop()? as i16 as i32; + let vector = if (x, y) == (0, 0) { + self.graphics.proj_vector + } else { + math::normalize14(x, y) + }; + self.graphics.proj_vector = vector; + self.graphics.dual_proj_vector = vector; + self.graphics.update_projection_state(); + Ok(()) + } + + /// Set freedom vector from stack. + /// + /// SFVFS[] (0x0B) + /// + /// Pops: y, x (2.14 fixed point numbers padded with zeroes) + /// + /// Sets the direction of the freedom_vector, using values x and y taken + /// from the stack, so that its projections onto the x and y-axes are x and + /// y, which are specified as signed (two’s complement) fixed-point (2.14) + /// numbers. The square root of (x2 + y2) must be equal to 0x4000 (hex) + /// + /// See + /// and + pub(super) fn op_sfvfs(&mut self) -> OpResult { + let y = self.value_stack.pop()? as i16 as i32; + let x = self.value_stack.pop()? as i16 as i32; + let vector = if (x, y) == (0, 0) { + self.graphics.freedom_vector + } else { + math::normalize14(x, y) + }; + self.graphics.freedom_vector = vector; + self.graphics.update_projection_state(); + Ok(()) + } + + /// Get projection vector. + /// + /// GPV[] (0x0C) + /// + /// Pushes: x, y (2.14 fixed point numbers padded with zeroes) + /// + /// Pushes the x and y components of the projection_vector onto the stack + /// as two 2.14 numbers. + /// + /// See + /// and + pub(super) fn op_gpv(&mut self) -> OpResult { + let vector = self.graphics.proj_vector; + self.value_stack.push(vector.x)?; + self.value_stack.push(vector.y) + } + + /// Get freedom vector. + /// + /// GFV[] (0x0D) + /// + /// Pushes: x, y (2.14 fixed point numbers padded with zeroes) + /// + /// Pushes the x and y components of the freedom_vector onto the stack as + /// two 2.14 numbers. + /// + /// See + /// and + pub(super) fn op_gfv(&mut self) -> OpResult { + let vector = self.graphics.freedom_vector; + self.value_stack.push(vector.x)?; + self.value_stack.push(vector.y) + } + + /// Set reference point 0. + /// + /// SRP0[] (0x10) + /// + /// Pops: p (point number) + /// + /// Pops a point number from the stack and sets rp0 to that point number. + /// + /// See + /// and + pub(super) fn op_srp0(&mut self) -> OpResult { + let p = self.value_stack.pop_usize()?; + self.graphics.rp0 = p; + Ok(()) + } + + /// Set reference point 1. + /// + /// SRP1[] (0x11) + /// + /// Pops: p (point number) + /// + /// Pops a point number from the stack and sets rp1 to that point number. + /// + /// See + /// and + pub(super) fn op_srp1(&mut self) -> OpResult { + let p = self.value_stack.pop_usize()?; + self.graphics.rp1 = p; + Ok(()) + } + + /// Set reference point 2. + /// + /// SRP2[] (0x12) + /// + /// Pops: p (point number) + /// + /// Pops a point number from the stack and sets rp2 to that point number. + /// + /// See + /// and + pub(super) fn op_srp2(&mut self) -> OpResult { + let p = self.value_stack.pop_usize()?; + self.graphics.rp2 = p; + Ok(()) + } + + /// Set zone pointer 0. + /// + /// SZP0[] (0x13) + /// + /// Pops: n (zone number) + /// + /// Pops a zone number, n, from the stack and sets zp0 to the zone with + /// that number. If n is 0, zp0 points to zone 0. If n is 1, zp0 points + /// to zone 1. Any other value for n is an error. + /// + /// See + /// and + pub(super) fn op_szp0(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.zp0 = n.try_into()?; + Ok(()) + } + + /// Set zone pointer 1. + /// + /// SZP1[] (0x14) + /// + /// Pops: n (zone number) + /// + /// Pops a zone number, n, from the stack and sets zp0 to the zone with + /// that number. If n is 0, zp1 points to zone 0. If n is 1, zp0 points + /// to zone 1. Any other value for n is an error. + /// + /// See + /// and + pub(super) fn op_szp1(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.zp1 = n.try_into()?; + Ok(()) + } + + /// Set zone pointer 2. + /// + /// SZP2[] (0x15) + /// + /// Pops: n (zone number) + /// + /// Pops a zone number, n, from the stack and sets zp0 to the zone with + /// that number. If n is 0, zp2 points to zone 0. If n is 1, zp0 points + /// to zone 1. Any other value for n is an error. + /// + /// See + /// and + pub(super) fn op_szp2(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.zp2 = n.try_into()?; + Ok(()) + } + + /// Set zone pointers. + /// + /// SZPS[] (0x16) + /// + /// Pops: n (zone number) + /// + /// Pops a zone number from the stack and sets all of the zone pointers to + /// point to the zone with that number. If n is 0, all three zone pointers + /// will point to zone 0. If n is 1, all three zone pointers will point to + /// zone 1. Any other value for n is an error. + /// + /// See + /// and + pub(super) fn op_szps(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + let zp = n.try_into()?; + self.graphics.zp0 = zp; + self.graphics.zp1 = zp; + self.graphics.zp2 = zp; + Ok(()) + } + + /// Round to half grid. + /// + /// RTHG[] (0x19) + /// + /// Sets the round_state variable to state 0 (hg). In this state, the + /// coordinates of a point are rounded to the nearest half grid line. + /// + /// See + /// and + pub(super) fn op_rthg(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::HalfGrid; + Ok(()) + } + + /// Round to grid. + /// + /// RTG[] (0x18) + /// + /// Sets the round_state variable to state 1 (g). In this state, distances + /// are rounded to the closest grid line. + /// + /// See + /// and + pub(super) fn op_rtg(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::Grid; + Ok(()) + } + + /// Round to double grid. + /// + /// RTDG[] (0x3D) + /// + /// Sets the round_state variable to state 2 (dg). In this state, distances + /// are rounded to the closest half or integer pixel. + /// + /// See + /// and + pub(super) fn op_rtdg(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::DoubleGrid; + Ok(()) + } + + /// Round down to grid. + /// + /// RDTG[] (0x7D) + /// + /// Sets the round_state variable to state 3 (dtg). In this state, distances + /// are rounded down to the closest integer grid line. + /// + /// See + /// and + pub(super) fn op_rdtg(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::DownToGrid; + Ok(()) + } + + /// Round up to grid. + /// + /// RUTG[] (0x7C) + /// + /// Sets the round_state variable to state 4 (utg). In this state distances + /// are rounded up to the closest integer pixel boundary. + /// + /// See + /// and + pub(super) fn op_rutg(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::UpToGrid; + Ok(()) + } + + /// Round off. + /// + /// ROFF[] (0x7A) + /// + /// Sets the round_state variable to state 5 (off). In this state rounding + /// is turned off. + /// + /// See + /// and + pub(super) fn op_roff(&mut self) -> OpResult { + self.graphics.round_state.mode = RoundMode::Off; + Ok(()) + } + + /// Super round. + /// + /// SROUND[] (0x76) + /// + /// Pops: n (number decomposed to obtain period, phase threshold) + /// + /// SROUND allows you fine control over the effects of the round_state + /// variable by allowing you to set the values of three components of + /// the round_state: period, phase, and threshold. + /// + /// More formally, SROUND maps the domain of 26.6 fixed point numbers into + /// a set of discrete values that are separated by equal distances. + /// + /// See + /// and + pub(super) fn op_sround(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.super_round(0x4000, n); + self.graphics.round_state.mode = RoundMode::Super; + Ok(()) + } + + /// Super round 45 degrees. + /// + /// S45ROUND[] (0x77) + /// + /// Pops: n (number decomposed to obtain period, phase threshold) + /// + /// S45ROUND is analogous to SROUND. The gridPeriod is SQRT(2)/2 pixels + /// rather than 1 pixel. It is useful for measuring at a 45 degree angle + /// with the coordinate axes. + /// + /// See + /// and + pub(super) fn op_s45round(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.super_round(0x2D41, n); + self.graphics.round_state.mode = RoundMode::Super45; + Ok(()) + } + + /// Helper function for decomposing period, phase and threshold for + /// the SROUND[] and SROUND45[] instructions. + /// + /// See + fn super_round(&mut self, grid_period: i32, selector: i32) { + let round_state = &mut self.graphics.round_state; + let period = match selector & 0xC0 { + 0 => grid_period / 2, + 0x40 => grid_period, + 0x80 => grid_period * 2, + 0xC0 => grid_period, + _ => round_state.period, + }; + let phase = match selector & 0x30 { + 0 => 0, + 0x10 => period / 4, + 0x20 => period / 2, + 0x30 => period * 3 / 4, + _ => round_state.phase, + }; + let threshold = if (selector & 0x0F) == 0 { + period - 1 + } else { + ((selector & 0x0F) - 4) * period / 8 + }; + round_state.period = period >> 8; + round_state.phase = phase >> 8; + round_state.threshold = threshold >> 8; + } + + /// Set loop variable. + /// + /// SLOOP[] (0x17) + /// + /// Pops: n (value for loop Graphics State variable (integer)) + /// + /// Pops a value, n, from the stack and sets the loop variable count to + /// that value. The loop variable works with the SHP\[a\], SHPIX[], IP[], + /// FLIPPT[], and ALIGNRP[]. The value n indicates the number of times + /// the instruction is to be repeated. After the instruction executes, + /// the loop variable is reset to 1. + /// + /// See + /// and + pub(super) fn op_sloop(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + if n < 0 { + return Err(HintErrorKind::NegativeLoopCounter); + } + // As in FreeType, heuristically limit the number of loops to 16 bits. + self.graphics.loop_counter = (n as u32).min(0xFFFF); + Ok(()) + } + + /// Set minimum distance. + /// + /// SMD[] (0x1A) + /// + /// Pops: distance: value for minimum_distance (F26Dot6) + /// + /// Pops a value from the stack and sets the minimum_distance variable + /// to that value. The distance is assumed to be expressed in sixty-fourths + /// of a pixel. + /// + /// See + /// and + pub(super) fn op_smd(&mut self) -> OpResult { + let distance = self.value_stack.pop_f26dot6()?; + self.graphics.min_distance = distance; + Ok(()) + } + + /// Instruction execution control. + /// + /// INSTCTRL[] (0x8E) + /// + /// Pops: s: selector flag (int32) + /// value: used to set value of instruction_control (uint16 padded) + /// + /// Sets the instruction control state variable making it possible to turn + /// on or off the execution of instructions and to regulate use of + /// parameters set in the CVT program. INSTCTRL[ ] can only be executed in + /// the CVT program. + /// + /// See + /// and + pub(super) fn op_instctrl(&mut self) -> OpResult { + let selector = self.value_stack.pop()? as u32; + let value = self.value_stack.pop()? as u32; + // Selectors are indices starting with 1; not flags. + // Avoid potential subtract with overflow below. + // See + // and + if !(1..=3).contains(&selector) { + return Ok(()); + } + // Convert index to flag. + let selector_flag = 1 << (selector - 1); + if value != 0 && value != selector_flag { + return Ok(()); + } + // If preserving linear metrics, prevent modification of the backward + // compatibility flag. + if selector == 3 && self.graphics.target.preserve_linear_metrics() { + return Ok(()); + } + match (self.program.initial, selector) { + // Typically, this instruction can only be executed in the prep table. + (Program::ControlValue, _) => { + self.graphics.instruct_control &= !(selector_flag as u8); + self.graphics.instruct_control |= value as u8; + } + // Allow an exception in the glyph program for selector 3 which can + // temporarily disable backward compatibility mode. + (Program::Glyph, 3) => { + self.graphics.backward_compatibility = value != 4; + } + _ => {} + } + Ok(()) + } + + /// Scan conversion control. + /// + /// SCANCTRL[] (0x85) + /// + /// Pops: n: flags indicating when to turn on dropout control mode + /// + /// SCANCTRL is used to set the value of the Graphics State variable + /// scan_control which in turn determines whether the scan converter + /// will activate dropout control for this glyph. + /// + /// See + /// and + pub(super) fn op_scanctrl(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + // Bits 0-7 represent the threshold value for ppem. + let threshold = n & 0xFF; + match threshold { + // A value of FF in bits 0-7 means invoke scan_control for all + // sizes. + 0xFF => self.graphics.scan_control = true, + // A value of 0 in bits 0-7 means never invoke scan_control. + 0 => self.graphics.scan_control = false, + _ => { + let ppem = self.graphics.ppem; + let is_rotated = self.graphics.is_rotated; + let is_stretched = self.graphics.is_stretched; + let scan_control = &mut self.graphics.scan_control; + // Bits 8-13 are used to turn on scan_control in cases where + // the specified conditions are met. Bits 8, 9 and 10 are used + // to turn on the scan_control mode (assuming other + // conditions do not block it). Bits 11, 12, and 13 are used to + // turn off the dropout mode unless other conditions force it + if (n & 0x100) != 0 && ppem <= threshold { + // Bit 8: Set scan_control to TRUE if other conditions + // do not block and ppem is less than or equal to the + // threshold value. + *scan_control = true; + } + if (n & 0x200) != 0 && is_rotated { + // Bit 9: Set scan_control to TRUE if other conditions + // do not block and the glyph is rotated + *scan_control = true; + } + if (n & 0x400) != 0 && is_stretched { + // Bit 10: Set scan_control to TRUE if other conditions + // do not block and the glyph is stretched. + *scan_control = true; + } + if (n & 0x800) != 0 && ppem > threshold { + // Bit 11: Set scan_control to FALSE unless ppem is less + // than or equal to the threshold value. + *scan_control = false; + } + if (n & 0x1000) != 0 && is_rotated { + // Bit 12: Set scan_control to FALSE based on rotation + // state. + *scan_control = false; + } + if (n & 0x2000) != 0 && is_stretched { + // Bit 13: Set scan_control to FALSE based on stretched + // state. + *scan_control = false; + } + } + } + Ok(()) + } + + /// Scan type. + /// + /// SCANTYPE[] (0x8D) + /// + /// Pops: n: 16 bit integer + /// + /// Pops a 16-bit integer whose value is used to determine which rules the + /// scan converter will use. + /// + /// See + /// and + pub(super) fn op_scantype(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.scan_type = n & 0xFFFF; + Ok(()) + } + + /// Set control value table cut in. + /// + /// SCVTCI[] (0x1D) + /// + /// Pops: n: value for cut_in (F26Dot6) + /// + /// Sets the control_value_cut_in in the Graphics State. The value n is + /// expressed in sixty-fourths of a pixel. + /// + /// See + /// and + pub(super) fn op_scvtci(&mut self) -> OpResult { + let n = self.value_stack.pop_f26dot6()?; + self.graphics.control_value_cutin = n; + Ok(()) + } + + /// Set single width cut in. + /// + /// SSWCI[] (0x1E) + /// + /// Pops: n: value for single_width_cut_in (F26Dot6) + /// + /// Sets the single_width_cut_in in the Graphics State. The value n is + /// expressed in sixty-fourths of a pixel. + /// + /// See + /// and + pub(super) fn op_sswci(&mut self) -> OpResult { + let n = self.value_stack.pop_f26dot6()?; + self.graphics.single_width_cutin = n; + Ok(()) + } + + /// Set single width. + /// + /// SSW[] (0x1F) + /// + /// Pops: n: value for single_width_value (FUnits) + /// + /// Sets the single_width_value in the Graphics State. The + /// single_width_value is expressed in FUnits, which the + /// interpreter converts to pixels (F26Dot6). + /// + /// See + /// and + pub(super) fn op_ssw(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.single_width = F26Dot6::from_bits(math::mul(n, self.graphics.scale)); + Ok(()) + } + + /// Set auto flip on. + /// + /// FLIPON[] (0x4D) + /// + /// Sets the auto_flip Boolean in the Graphics State to TRUE causing the + /// MIRP instructions to ignore the sign of Control Value Table entries. + /// The default auto_flip Boolean value is TRUE. + /// + /// See + /// and + pub(super) fn op_flipon(&mut self) -> OpResult { + self.graphics.auto_flip = true; + Ok(()) + } + + /// Set auto flip off. + /// + /// FLIPOFF[] (0x4E) + /// + /// Set the auto_flip Boolean in the Graphics State to FALSE causing the + /// MIRP instructions to use the sign of Control Value Table entries. + /// The default auto_flip Boolean value is TRUE. + /// + /// See + /// and + pub(super) fn op_flipoff(&mut self) -> OpResult { + self.graphics.auto_flip = false; + Ok(()) + } + + /// Set angle weight. + /// + /// SANGW[] (0x7E) + /// + /// Pops: weight: value for angle_weight + /// + /// SANGW is no longer needed because of dropped support to the AA + /// (Adjust Angle) instruction. AA was the only instruction that used + /// angle_weight in the global graphics state. + /// + /// See + /// and + pub(super) fn op_sangw(&mut self) -> OpResult { + // totally unsupported but we still need to pop the stack value + let _weight = self.value_stack.pop()?; + Ok(()) + } + + /// Set delta base in graphics state. + /// + /// SDB[] (0x5E) + /// + /// Pops: n: value for delta_base + /// + /// Pops a number, n, and sets delta_base to the value n. The default for + /// delta_base is 9. + /// + /// See + /// and + pub(super) fn op_sdb(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + self.graphics.delta_base = n as u16; + Ok(()) + } + + /// Set delta shift in graphics state. + /// + /// SDS[] (0x5F) + /// + /// Pops: n: value for delta_shift + /// + /// Sets delta_shift to the value n. The default for delta_shift is 3. + /// + /// See + /// and + pub(super) fn op_sds(&mut self) -> OpResult { + let n = self.value_stack.pop()?; + if n as u32 > 6 { + Err(HintErrorKind::InvalidStackValue(n)) + } else { + self.graphics.delta_shift = n as u16; + Ok(()) + } + } +} + +/// Computes a parallel or perpendicular normalized vector for the line +/// between the two given points. +/// +/// This is common code for the "set vector to line" instructions. +/// +/// See +fn line_vector(p1: Point, p2: Point, is_parallel: bool) -> Point { + let mut a = (p1.x - p2.x).to_bits(); + let mut b = (p1.y - p2.y).to_bits(); + if a == 0 && b == 0 { + // If the points are equal, set to the x axis. + a = 0x4000; + } else if !is_parallel { + // Perform a counter-clockwise rotation by 90 degrees to form a + // perpendicular line. + let c = b; + b = a; + a = -c; + } + math::normalize14(a, b) +} + +#[cfg(test)] +mod tests { + use super::{ + super::{ + super::zone::{Zone, ZonePointer}, + math, F2Dot14, MockEngine, + }, + F26Dot6, HintErrorKind, Point, Program, RoundMode, + }; + + // Some helpful constants for testing vectors + const ONE: i32 = F2Dot14::ONE.to_bits() as i32; + + const X_AXIS: Point = Point::new(ONE, 0); + const Y_AXIS: Point = Point::new(0, ONE); + + #[test] + fn set_vectors_to_coord_axis() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // freedom and projection vector to y axis + engine.op_svtca(0x00).unwrap(); + assert_eq!(engine.graphics.freedom_vector, Y_AXIS); + assert_eq!(engine.graphics.proj_vector, Y_AXIS); + // freedom and projection vector to x axis + engine.op_svtca(0x01).unwrap(); + assert_eq!(engine.graphics.freedom_vector, X_AXIS); + assert_eq!(engine.graphics.proj_vector, X_AXIS); + // projection vector to y axis + engine.op_svtca(0x02).unwrap(); + assert_eq!(engine.graphics.proj_vector, Y_AXIS); + // projection vector to x axis + engine.op_svtca(0x03).unwrap(); + assert_eq!(engine.graphics.proj_vector, X_AXIS); + // freedom vector to y axis + engine.op_svtca(0x04).unwrap(); + assert_eq!(engine.graphics.freedom_vector, Y_AXIS); + // freedom vector to x axis + engine.op_svtca(0x05).unwrap(); + assert_eq!(engine.graphics.freedom_vector, X_AXIS); + } + + #[test] + fn set_get_vectors_from_stack() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // projection vector + engine.value_stack.push(X_AXIS.x).unwrap(); + engine.value_stack.push(X_AXIS.y).unwrap(); + engine.op_spvfs().unwrap(); + assert_eq!(engine.graphics.proj_vector, X_AXIS); + engine.op_gpv().unwrap(); + let y = engine.value_stack.pop().unwrap(); + let x = engine.value_stack.pop().unwrap(); + assert_eq!(Point::new(x, y), X_AXIS); + // freedom vector + engine.value_stack.push(Y_AXIS.x).unwrap(); + engine.value_stack.push(Y_AXIS.y).unwrap(); + engine.op_sfvfs().unwrap(); + assert_eq!(engine.graphics.freedom_vector, Y_AXIS); + engine.op_gfv().unwrap(); + let y = engine.value_stack.pop().unwrap(); + let x = engine.value_stack.pop().unwrap(); + assert_eq!(Point::new(x, y), Y_AXIS); + } + + #[test] + fn set_vectors_to_line() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Set up a zone for testing and set all the zone pointers to it. + let points = &mut [Point::new(0, 0), Point::new(64, 0)].map(|p| p.map(F26Dot6::from_bits)); + let original = + &mut [Point::new(0, 64), Point::new(0, -64)].map(|p| p.map(F26Dot6::from_bits)); + engine.graphics.zones[1] = Zone { + points, + original, + unscaled: &mut [], + flags: &mut [], + contours: &[], + }; + engine.value_stack.push(1).unwrap(); + engine.op_szps().unwrap(); + // First, push point indices (a few times for reuse) + for _ in 0..6 { + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(0).unwrap(); + } + // SPVTL: set projection vector to line: + { + // (parallel) + engine.op_svtl(0x6).unwrap(); + assert_eq!(engine.graphics.proj_vector, X_AXIS); + // (perpendicular) + engine.op_svtl(0x7).unwrap(); + assert_eq!(engine.graphics.proj_vector, Point::new(0, ONE)); + } + // SFVTL: set freedom vector to line: + { + // (parallel) + engine.op_svtl(0x8).unwrap(); + assert_eq!(engine.graphics.freedom_vector, X_AXIS); + // (perpendicular) + engine.op_svtl(0x9).unwrap(); + assert_eq!(engine.graphics.freedom_vector, Point::new(0, ONE)); + } + // SDPVTL: set dual projection vector to line: + { + // (parallel) + engine.op_sdpvtl(0x86).unwrap(); + assert_eq!(engine.graphics.dual_proj_vector, Point::new(0, -ONE)); + // (perpendicular) + engine.op_sdpvtl(0x87).unwrap(); + assert_eq!(engine.graphics.dual_proj_vector, Point::new(ONE, 0)); + } + } + + /// Lots of little tests for instructions that just set fields on + /// the graphics state. + #[test] + fn simple_state_setting() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // srp0 + engine.value_stack.push(111).unwrap(); + engine.op_srp0().unwrap(); + assert_eq!(engine.graphics.rp0, 111); + // srp1 + engine.value_stack.push(222).unwrap(); + engine.op_srp1().unwrap(); + assert_eq!(engine.graphics.rp1, 222); + // srp2 + engine.value_stack.push(333).unwrap(); + engine.op_srp2().unwrap(); + assert_eq!(engine.graphics.rp2, 333); + // zp0 + engine.value_stack.push(1).unwrap(); + engine.op_szp0().unwrap(); + assert_eq!(engine.graphics.zp0, ZonePointer::Glyph); + // zp1 + engine.value_stack.push(0).unwrap(); + engine.op_szp1().unwrap(); + assert_eq!(engine.graphics.zp1, ZonePointer::Twilight); + // zp2 + engine.value_stack.push(1).unwrap(); + engine.op_szp2().unwrap(); + assert_eq!(engine.graphics.zp2, ZonePointer::Glyph); + // zps + engine.value_stack.push(0).unwrap(); + engine.op_szps().unwrap(); + assert_eq!( + [ + engine.graphics.zp0, + engine.graphics.zp1, + engine.graphics.zp2 + ], + [ZonePointer::Twilight; 3] + ); + // zp failure + engine.value_stack.push(2).unwrap(); + assert!(matches!( + engine.op_szps(), + Err(HintErrorKind::InvalidZoneIndex(2)) + )); + // rtg + engine.op_rtg().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::Grid); + // rtdg + engine.op_rtdg().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::DoubleGrid); + // rdtg + engine.op_rdtg().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::DownToGrid); + // rutg + engine.op_rutg().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::UpToGrid); + // roff + engine.op_roff().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::Off); + // sround + engine.value_stack.push(0).unwrap(); + engine.op_sround().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::Super); + // s45round + engine.value_stack.push(0).unwrap(); + engine.op_s45round().unwrap(); + assert_eq!(engine.graphics.round_state.mode, RoundMode::Super45); + // sloop + engine.value_stack.push(10).unwrap(); + engine.op_sloop().unwrap(); + assert_eq!(engine.graphics.loop_counter, 10); + // loop variable cannot be negative + engine.value_stack.push(-10).unwrap(); + assert!(matches!( + engine.op_sloop(), + Err(HintErrorKind::NegativeLoopCounter) + )); + // smd + engine.value_stack.push(64).unwrap(); + engine.op_smd().unwrap(); + assert_eq!(engine.graphics.min_distance, F26Dot6::from_bits(64)); + // scantype + engine.value_stack.push(50).unwrap(); + engine.op_scantype().unwrap(); + assert_eq!(engine.graphics.scan_type, 50); + // scvtci + engine.value_stack.push(128).unwrap(); + engine.op_scvtci().unwrap(); + assert_eq!(engine.graphics.control_value_cutin, F26Dot6::from_bits(128)); + // sswci + engine.value_stack.push(100).unwrap(); + engine.op_sswci().unwrap(); + assert_eq!(engine.graphics.single_width_cutin, F26Dot6::from_bits(100)); + // ssw + engine.graphics.scale = 64; + engine.value_stack.push(100).unwrap(); + engine.op_ssw().unwrap(); + assert_eq!( + engine.graphics.single_width, + F26Dot6::from_bits(math::mul(100, engine.graphics.scale)) + ); + // flipoff + engine.op_flipoff().unwrap(); + assert!(!engine.graphics.auto_flip); + // flipon + engine.op_flipon().unwrap(); + assert!(engine.graphics.auto_flip); + // sdb + engine.value_stack.push(172).unwrap(); + engine.op_sdb().unwrap(); + assert_eq!(engine.graphics.delta_base, 172); + // sds + engine.value_stack.push(4).unwrap(); + engine.op_sds().unwrap(); + assert_eq!(engine.graphics.delta_shift, 4); + // delta_shift has a max value of 6 + engine.value_stack.push(7).unwrap(); + assert!(matches!( + engine.op_sds(), + Err(HintErrorKind::InvalidStackValue(7)) + )); + } + + #[test] + fn instctrl() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.program.initial = Program::ControlValue; + // selectors 1..=3 are valid and values for each selector + // can be 0, which disables the field, or 1 << (selector - 1) to + // enable it + for selector in 1..=3 { + // enable first + let enable_mask = (1 << (selector - 1)) as u8; + engine.value_stack.push(enable_mask as i32).unwrap(); + engine.value_stack.push(selector).unwrap(); + engine.op_instctrl().unwrap(); + assert!(engine.graphics.instruct_control & enable_mask != 0); + // now disable + engine.value_stack.push(0).unwrap(); + engine.value_stack.push(selector).unwrap(); + engine.op_instctrl().unwrap(); + assert!(engine.graphics.instruct_control & enable_mask == 0); + } + // in glyph programs, selector 3 can be used to toggle + // backward_compatibility + engine.program.initial = Program::Glyph; + // enabling this flag opts into "native ClearType mode" + // which disables backward compatibility + engine.value_stack.push((3 - 1) << 1).unwrap(); + engine.value_stack.push(3).unwrap(); + engine.op_instctrl().unwrap(); + assert!(!engine.graphics.backward_compatibility); + // and disabling it enables backward compatibility + engine.value_stack.push(0).unwrap(); + engine.value_stack.push(3).unwrap(); + engine.op_instctrl().unwrap(); + assert!(engine.graphics.backward_compatibility); + } + + // Subtract with overflow caught by fuzzing when selector == 0 + // See + // and + #[test] + fn instctrl_avoid_overflow() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.program.initial = Program::ControlValue; + engine.value_stack.push(0).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_instctrl().unwrap(); + } + + #[test] + fn scanctrl() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Example modes from specification: + // 0x0000 No dropout control is invoked + engine.value_stack.push(0x0000).unwrap(); + engine.op_scanctrl().unwrap(); + assert!(!engine.graphics.scan_control); + // 0x01FF Always do dropout control + engine.value_stack.push(0x01FF).unwrap(); + engine.op_scanctrl().unwrap(); + assert!(engine.graphics.scan_control); + // 0x0A10 Do dropout control if the glyph is rotated and has less than 16 pixels per-em + engine.value_stack.push(0x0A10).unwrap(); + engine.graphics.is_rotated = true; + engine.graphics.ppem = 12; + engine.op_scanctrl().unwrap(); + assert!(engine.graphics.scan_control); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,305 @@ +//! Logical functions. +//! +//! Implements 11 instructions. +//! +//! See + +use super::{Engine, F26Dot6, OpResult}; + +impl Engine<'_> { + /// Less than. + /// + /// LT[] (0x50) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// First pops e2, then pops e1 off the stack and compares them: if e1 is + /// less than e2, 1, signifying TRUE, is pushed onto the stack. If e1 is + /// not less than e2, 0, signifying FALSE, is placed onto the stack. + /// + /// See + /// and + pub(super) fn op_lt(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a < b) as i32)) + } + + /// Less than or equal. + /// + /// LTEQ[] (0x51) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e2 and e1 off the stack and compares them. If e1 is less than or + /// equal to e2, 1, signifying TRUE, is pushed onto the stack. If e1 is + /// not less than or equal to e2, 0, signifying FALSE, is placed onto the + /// stack. + /// + /// See + /// and + pub(super) fn op_lteq(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a <= b) as i32)) + } + + /// Greater than. + /// + /// GT[] (0x52) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// First pops e2 then pops e1 off the stack and compares them. If e1 is + /// greater than e2, 1, signifying TRUE, is pushed onto the stack. If e1 + /// is not greater than e2, 0, signifying FALSE, is placed onto the stack. + /// + /// See + /// and + pub(super) fn op_gt(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a > b) as i32)) + } + + /// Greater than or equal. + /// + /// GTEQ[] (0x53) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e1 and e2 off the stack and compares them. If e1 is greater than + /// or equal to e2, 1, signifying TRUE, is pushed onto the stack. If e1 + /// is not greater than or equal to e2, 0, signifying FALSE, is placed + /// onto the stack. + /// + /// See + /// and + pub(super) fn op_gteq(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a >= b) as i32)) + } + + /// Equal. + /// + /// EQ[] (0x54) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e1 and e2 off the stack and compares them. If they are equal, 1, + /// signifying TRUE is pushed onto the stack. If they are not equal, 0, + /// signifying FALSE is placed onto the stack. + /// + /// See + /// and + pub(super) fn op_eq(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a == b) as i32)) + } + + /// Not equal. + /// + /// NEQ[] (0x55) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e1 and e2 from the stack and compares them. If they are not equal, + /// 1, signifying TRUE, is pushed onto the stack. If they are equal, 0, + /// signifying FALSE, is placed on the stack. + /// + /// See + /// and + pub(super) fn op_neq(&mut self) -> OpResult { + self.value_stack.apply_binary(|a, b| Ok((a != b) as i32)) + } + + /// Odd. + /// + /// ODD[] (0x56) + /// + /// Pops: e1 + /// Pushes: Boolean value + /// + /// Tests whether the number at the top of the stack is odd. Pops e1 from + /// the stack and rounds it as specified by the round_state before testing + /// it. After the value is rounded, it is shifted from a fixed point value + /// to an integer value (any fractional values are ignored). If the integer + /// value is odd, one, signifying TRUE, is pushed onto the stack. If it is + /// even, zero, signifying FALSE is placed onto the stack. + /// + /// See + /// and + pub(super) fn op_odd(&mut self) -> OpResult { + let round_state = self.graphics.round_state; + self.value_stack.apply_unary(|e1| { + Ok((round_state.round(F26Dot6::from_bits(e1)).to_bits() & 127 == 64) as i32) + }) + } + + /// Even. + /// + /// EVEN[] (0x57) + /// + /// Pops: e1 + /// Pushes: Boolean value + /// + /// Tests whether the number at the top of the stack is even. Pops e1 off + /// the stack and rounds it as specified by the round_state before testing + /// it. If the rounded number is even, one, signifying TRUE, is pushed onto + /// the stack if it is odd, zero, signifying FALSE, is placed onto the + /// stack. + /// + /// See + /// and + pub(super) fn op_even(&mut self) -> OpResult { + let round_state = self.graphics.round_state; + self.value_stack.apply_unary(|e1| { + Ok((round_state.round(F26Dot6::from_bits(e1)).to_bits() & 127 == 0) as i32) + }) + } + + /// Logical and. + /// + /// AND[] (0x5A) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e1 and e2 off the stack and pushes onto the stack the result of a + /// logical and of the two elements. Zero is returned if either or both of + /// the elements are FALSE (have the value zero). One is returned if both + /// elements are TRUE (have a non zero value). + /// + /// See + /// and + pub(super) fn op_and(&mut self) -> OpResult { + self.value_stack + .apply_binary(|a, b| Ok((a != 0 && b != 0) as i32)) + } + + /// Logical or. + /// + /// OR[] (0x5B) + /// + /// Pops: e1, e2 + /// Pushes: Boolean value + /// + /// Pops e1 and e2 off the stack and pushes onto the stack the result of a + /// logical or operation between the two elements. Zero is returned if both + /// of the elements are FALSE. One is returned if either one or both of the + /// elements are TRUE (has a nonzero value). + /// + /// See + /// and + pub(super) fn op_or(&mut self) -> OpResult { + self.value_stack + .apply_binary(|a, b| Ok((a != 0 || b != 0) as i32)) + } + + /// Logical not. + /// + /// NOT[] (0x5C) + /// + /// Pops: e + /// Pushes: (not e): logical negation of e + /// + /// Pops e off the stack and returns the result of a logical NOT operation + /// performed on e. If originally zero, one is pushed onto the stack if + /// originally nonzero, zero is pushed onto the stack. + /// + /// See + /// and + pub(super) fn op_not(&mut self) -> OpResult { + self.value_stack.apply_unary(|e| Ok((e == 0) as i32)) + } +} + +#[cfg(test)] +mod tests { + use super::super::MockEngine; + + #[test] + fn compare_ops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + for b in -10..=10 { + let input = &[a, b]; + engine.test_exec(input, a < b, |engine| { + engine.op_lt().unwrap(); + }); + engine.test_exec(input, a <= b, |engine| { + engine.op_lteq().unwrap(); + }); + engine.test_exec(input, a > b, |engine| { + engine.op_gt().unwrap(); + }); + engine.test_exec(input, a >= b, |engine| { + engine.op_gteq().unwrap(); + }); + engine.test_exec(input, a == b, |engine| { + engine.op_eq().unwrap(); + }); + engine.test_exec(input, a != b, |engine| { + engine.op_neq().unwrap(); + }); + } + } + } + + #[test] + fn parity_ops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // These operate on 26.6 so values are multiple of 64 + let cases = [ + // (input, is_even) + (0, true), + (64, false), + (128, true), + (192, false), + (256, true), + (57, false), + (-128, true), + ]; + for (input, is_even) in cases { + engine.test_exec(&[input], is_even, |engine| { + engine.op_even().unwrap(); + }); + } + for (input, is_even) in cases { + engine.test_exec(&[input], !is_even, |engine| { + engine.op_odd().unwrap(); + }); + } + } + + #[test] + fn not_op() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.test_exec(&[0], 1, |engine| { + engine.op_not().unwrap(); + }); + engine.test_exec(&[234234], 0, |engine| { + engine.op_not().unwrap(); + }); + } + + #[test] + fn and_or_ops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for a in -10..=10 { + for b in -10..=10 { + let input = &[a, b]; + let a = a != 0; + let b = b != 0; + engine.test_exec(input, a && b, |engine| { + engine.op_and().unwrap(); + }); + engine.test_exec(input, a || b, |engine| { + engine.op_or().unwrap(); + }); + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,322 @@ +//! Miscellaneous instructions. +//! +//! Implements 3 instructions. +//! +//! See + +use super::{Engine, OpResult}; + +impl Engine<'_> { + /// Get information. + /// + /// GETINFO[] (0x88) + /// + /// Pops: selector: integer + /// Pushes: result: integer + /// + /// GETINFO is used to obtain data about the font scaler version and the + /// characteristics of the current glyph. The instruction pops a selector + /// used to determine the type of information desired and pushes a result + /// onto the stack. + /// + /// See + /// and + pub(super) fn op_getinfo(&mut self) -> OpResult { + use getinfo::*; + let selector = self.value_stack.pop()?; + let mut result = 0; + // Interpreter version (selector bit: 0, result bits: 0-7) + if (selector & VERSION_SELECTOR_BIT) != 0 { + result = 40; + } + // Glyph rotated (selector bit: 1, result bit: 8) + if (selector & GLYPH_ROTATED_SELECTOR_BIT) != 0 && self.graphics.is_rotated { + result |= GLYPH_ROTATED_RESULT_BIT; + } + // Glyph stretched (selector bit: 2, result bit: 9) + if (selector & GLYPH_STRETCHED_SELECTOR_BIT) != 0 && self.graphics.is_stretched { + result |= GLYPH_STRETCHED_RESULT_BIT; + } + // Font variations (selector bit: 3, result bit: 10) + if (selector & FONT_VARIATIONS_SELECTOR_BIT) != 0 && self.axis_count != 0 { + result |= FONT_VARIATIONS_RESULT_BIT; + } + // The following only apply for smooth hinting. + if self.graphics.target.is_smooth() { + // Subpixel hinting [cleartype enabled] (selector bit: 6, result bit: 13) + // (always enabled) + if (selector & SUBPIXEL_HINTING_SELECTOR_BIT) != 0 { + result |= SUBPIXEL_HINTING_RESULT_BIT; + } + // Vertical LCD subpixels? (selector bit: 8, result bit: 15) + if (selector & VERTICAL_LCD_SELECTOR_BIT) != 0 && self.graphics.target.is_vertical_lcd() + { + result |= VERTICAL_LCD_RESULT_BIT; + } + // Subpixel positioned? (selector bit: 10, result bit: 17) + // (always enabled) + if (selector & SUBPIXEL_POSITIONED_SELECTOR_BIT) != 0 { + result |= SUBPIXEL_POSITIONED_RESULT_BIT; + } + // Symmetrical smoothing (selector bit: 11, result bit: 18) + // Note: FreeType always enables this but we allow direct control + // with our own flag. + // See + if (selector & SYMMETRICAL_SMOOTHING_SELECTOR_BIT) != 0 + && self.graphics.target.symmetric_rendering() + { + result |= SYMMETRICAL_SMOOTHING_RESULT_BIT; + } + // ClearType hinting and grayscale rendering (selector bit: 12, result bit: 19) + if (selector & GRAYSCALE_CLEARTYPE_SELECTOR_BIT) != 0 + && self.graphics.target.is_grayscale_cleartype() + { + result |= GRAYSCALE_CLEARTYPE_RESULT_BIT; + } + } + self.value_stack.push(result) + } + + /// Get variation. + /// + /// GETVARIATION[] (0x91) + /// + /// Pushes: Normalized axes coordinates, one for each axis in the font. + /// + /// GETVARIATION is used to obtain the current normalized variation + /// coordinates for each axis. The coordinate for the first axis, as + /// defined in the 'fvar' table, is pushed first on the stack, followed + /// by each consecutive axis until the coordinate for the last axis is + /// on the stack. + /// + /// See + /// and + pub(super) fn op_getvariation(&mut self) -> OpResult { + // For non-variable fonts, this falls back to IDEF resolution. + let axis_count = self.axis_count as usize; + if axis_count != 0 { + // Make sure we push `axis_count` coords regardless of the value + // provided by the user. + for coord in self + .coords + .iter() + .copied() + .chain(std::iter::repeat(Default::default())) + .take(axis_count) + { + self.value_stack.push(coord.to_bits() as i32)?; + } + Ok(()) + } else { + self.op_unknown(0x91) + } + } + + /// Get data. + /// + /// GETDATA[] (0x92) + /// + /// Pushes: 17 + /// + /// Undocumented and nobody knows what this does. FreeType just + /// returns 17 for variable fonts and falls back to IDEF lookup + /// otherwise. + /// + /// See + pub(super) fn op_getdata(&mut self) -> OpResult { + if self.axis_count != 0 { + self.value_stack.push(17) + } else { + self.op_unknown(0x92) + } + } +} + +/// Constants for the GETINFO instruction. Extracted here +/// to enable access from tests. +mod getinfo { + // Interpreter version (selector bit: 0, result bits: 0-7) + pub const VERSION_SELECTOR_BIT: i32 = 1 << 0; + + // Glyph rotated (selector bit: 1, result bit: 8) + pub const GLYPH_ROTATED_SELECTOR_BIT: i32 = 1 << 1; + pub const GLYPH_ROTATED_RESULT_BIT: i32 = 1 << 8; + + // Glyph stretched (selector bit: 2, result bit: 9) + pub const GLYPH_STRETCHED_SELECTOR_BIT: i32 = 1 << 2; + pub const GLYPH_STRETCHED_RESULT_BIT: i32 = 1 << 9; + + // Font variations (selector bit: 3, result bit: 10) + pub const FONT_VARIATIONS_SELECTOR_BIT: i32 = 1 << 3; + pub const FONT_VARIATIONS_RESULT_BIT: i32 = 1 << 10; + + // Subpixel hinting [cleartype enabled] (selector bit: 6, result bit: 13) + // (always enabled) + pub const SUBPIXEL_HINTING_SELECTOR_BIT: i32 = 1 << 6; + pub const SUBPIXEL_HINTING_RESULT_BIT: i32 = 1 << 13; + + // Vertical LCD subpixels? (selector bit: 8, result bit: 15) + pub const VERTICAL_LCD_SELECTOR_BIT: i32 = 1 << 8; + pub const VERTICAL_LCD_RESULT_BIT: i32 = 1 << 15; + + // Subpixel positioned? (selector bit: 10, result bit: 17) + // (always enabled) + pub const SUBPIXEL_POSITIONED_SELECTOR_BIT: i32 = 1 << 10; + pub const SUBPIXEL_POSITIONED_RESULT_BIT: i32 = 1 << 17; + + // Symmetrical smoothing (selector bit: 11, result bit: 18) + // Note: FreeType always enables this but we deviate when our own + // preserve linear metrics flag is enabled. + pub const SYMMETRICAL_SMOOTHING_SELECTOR_BIT: i32 = 1 << 11; + pub const SYMMETRICAL_SMOOTHING_RESULT_BIT: i32 = 1 << 18; + + // ClearType hinting and grayscale rendering (selector bit: 12, result bit: 19) + pub const GRAYSCALE_CLEARTYPE_SELECTOR_BIT: i32 = 1 << 12; + pub const GRAYSCALE_CLEARTYPE_RESULT_BIT: i32 = 1 << 19; +} + +#[cfg(test)] +mod tests { + use super::super::{ + super::super::super::{SmoothMode, Target}, + Engine, HintErrorKind, MockEngine, + }; + use raw::types::F2Dot14; + use read_fonts::tables::glyf::bytecode::Opcode; + + #[test] + fn getinfo() { + use super::getinfo::*; + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // version + engine.getinfo_test(VERSION_SELECTOR_BIT, 40); + // not rotated + engine.getinfo_test(GLYPH_ROTATED_SELECTOR_BIT, 0); + // rotated + engine.graphics.is_rotated = true; + engine.getinfo_test(GLYPH_ROTATED_SELECTOR_BIT, GLYPH_ROTATED_RESULT_BIT); + // not stretched + engine.getinfo_test(GLYPH_STRETCHED_SELECTOR_BIT, 0); + // stretched + engine.graphics.is_stretched = true; + engine.getinfo_test(GLYPH_STRETCHED_SELECTOR_BIT, GLYPH_STRETCHED_RESULT_BIT); + // stretched and rotated + engine.getinfo_test( + GLYPH_ROTATED_SELECTOR_BIT | GLYPH_STRETCHED_SELECTOR_BIT, + GLYPH_ROTATED_RESULT_BIT | GLYPH_STRETCHED_RESULT_BIT, + ); + // not variable + engine.getinfo_test(FONT_VARIATIONS_SELECTOR_BIT, 0); + // variable + engine.axis_count = 1; + engine.getinfo_test(FONT_VARIATIONS_SELECTOR_BIT, FONT_VARIATIONS_RESULT_BIT); + // in strong hinting mode, the following selectors are always disabled + engine.graphics.target = Target::Mono; + for selector in [ + SUBPIXEL_HINTING_SELECTOR_BIT, + VERTICAL_LCD_SELECTOR_BIT, + SUBPIXEL_POSITIONED_SELECTOR_BIT, + SYMMETRICAL_SMOOTHING_SELECTOR_BIT, + GRAYSCALE_CLEARTYPE_SELECTOR_BIT, + ] { + engine.getinfo_test(selector, 0); + } + // set back to smooth mode + engine.graphics.target = Target::default(); + for (selector, result) in [ + // default smooth mode is grayscale cleartype + ( + GRAYSCALE_CLEARTYPE_SELECTOR_BIT, + GRAYSCALE_CLEARTYPE_RESULT_BIT, + ), + // always enabled in smooth mode + (SUBPIXEL_HINTING_SELECTOR_BIT, SUBPIXEL_HINTING_RESULT_BIT), + ( + SUBPIXEL_POSITIONED_SELECTOR_BIT, + SUBPIXEL_POSITIONED_RESULT_BIT, + ), + ] { + engine.getinfo_test(selector, result); + } + // vertical lcd + engine.graphics.target = Target::Smooth { + mode: SmoothMode::VerticalLcd, + preserve_linear_metrics: true, + symmetric_rendering: false, + }; + engine.getinfo_test(VERTICAL_LCD_SELECTOR_BIT, VERTICAL_LCD_RESULT_BIT); + // symmetical smoothing is disabled + engine.getinfo_test(SYMMETRICAL_SMOOTHING_SELECTOR_BIT, 0); + // grayscale cleartype is disabled when lcd_subpixel is not None + engine.getinfo_test(GRAYSCALE_CLEARTYPE_SELECTOR_BIT, 0); + // reset to default to disable preserve linear metrics + engine.graphics.target = Target::default(); + // now symmetrical smoothing is enabled + engine.getinfo_test( + SYMMETRICAL_SMOOTHING_SELECTOR_BIT, + SYMMETRICAL_SMOOTHING_RESULT_BIT, + ); + } + + #[test] + fn getvariation() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // no variations should trigger unknown opcode + assert!(matches!( + engine.op_getvariation(), + Err(HintErrorKind::UnhandledOpcode(Opcode::GETVARIATION)) + )); + // set the axis count to a non-zero value to enable variations + engine.axis_count = 2; + // and creates some coords + let coords = [ + F2Dot14::from_f32(-1.0), + F2Dot14::from_f32(0.5), + F2Dot14::from_f32(1.0), + ]; + let coords_bits = coords.map(|x| x.to_bits() as i32); + // too few, pad with zeros + engine.coords = &coords[0..1]; + engine.op_getvariation().unwrap(); + assert_eq!(engine.value_stack.len(), 2); + assert_eq!(engine.value_stack.values(), &[coords_bits[0], 0]); + engine.value_stack.clear(); + // too many, truncate + engine.coords = &coords[0..3]; + engine.op_getvariation().unwrap(); + assert_eq!(engine.value_stack.len(), 2); + assert_eq!(engine.value_stack.values(), &coords_bits[0..2]); + engine.value_stack.clear(); + // just right + engine.coords = &coords[0..2]; + engine.op_getvariation().unwrap(); + assert_eq!(engine.value_stack.len(), 2); + assert_eq!(engine.value_stack.values(), &coords_bits[0..2]); + } + + #[test] + fn getdata() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // no variations should trigger unknown opcode + assert!(matches!( + engine.op_getdata(), + Err(HintErrorKind::UnhandledOpcode(Opcode::GETDATA)) + )); + // set the axis count to a non-zero value to enable variations + engine.axis_count = 1; + engine.op_getdata().unwrap(); + // :shrug: + assert_eq!(engine.value_stack.pop().unwrap(), 17); + } + + impl Engine<'_> { + fn getinfo_test(&mut self, selector: i32, expected: i32) { + self.value_stack.push(selector).unwrap(); + self.op_getinfo().unwrap(); + assert_eq!(self.value_stack.pop().unwrap(), expected); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,269 @@ +//! TrueType bytecode interpreter. + +mod arith; +mod control_flow; +mod cvt; +mod data; +mod definition; +mod delta; +mod dispatch; +mod graphics; +mod logical; +mod misc; +mod outline; +mod round; +mod stack; +mod storage; + +use read_fonts::{ + tables::glyf::bytecode::Instruction, + types::{F26Dot6, F2Dot14, Point}, +}; + +use super::{ + super::Outlines, + cvt::Cvt, + definition::DefinitionState, + error::{HintError, HintErrorKind}, + graphics::{GraphicsState, RetainedGraphicsState}, + math, + program::ProgramState, + storage::Storage, + value_stack::ValueStack, + zone::Zone, +}; + +pub type OpResult = Result<(), HintErrorKind>; + +/// TrueType bytecode interpreter. +pub struct Engine<'a> { + program: ProgramState<'a>, + graphics: GraphicsState<'a>, + definitions: DefinitionState<'a>, + cvt: Cvt<'a>, + storage: Storage<'a>, + value_stack: ValueStack<'a>, + loop_budget: LoopBudget, + axis_count: u16, + coords: &'a [F2Dot14], +} + +impl<'a> Engine<'a> { + #[allow(clippy::too_many_arguments)] + pub fn new( + outlines: &Outlines, + program: ProgramState<'a>, + graphics: RetainedGraphicsState, + definitions: DefinitionState<'a>, + cvt: impl Into>, + storage: impl Into>, + value_stack: ValueStack<'a>, + twilight: Zone<'a>, + glyph: Zone<'a>, + axis_count: u16, + coords: &'a [F2Dot14], + is_composite: bool, + ) -> Self { + let point_count = if glyph.points.is_empty() { + None + } else { + Some(glyph.points.len()) + }; + let graphics = GraphicsState { + retained: graphics, + zones: [twilight, glyph], + is_composite, + ..Default::default() + }; + Self { + program, + graphics, + definitions, + cvt: cvt.into(), + storage: storage.into(), + value_stack, + loop_budget: LoopBudget::new(outlines, point_count), + axis_count, + coords, + } + } + + pub fn backward_compatibility(&self) -> bool { + self.graphics.backward_compatibility + } + + pub fn retained_graphics_state(&self) -> &RetainedGraphicsState { + &self.graphics.retained + } +} + +/// Tracks budgets for loops to limit execution time. +struct LoopBudget { + /// Maximum number of times we can do backward jumps or + /// loop calls. + limit: usize, + /// Current number of backward jumps executed. + backward_jumps: usize, + /// Current number of loop call iterations executed. + loop_calls: usize, +} + +impl LoopBudget { + fn new(outlines: &Outlines, point_count: Option) -> Self { + let cvt_len = outlines.cvt_len as usize; + // Compute limits for loop calls and backward jumps. + // See + let limit = if let Some(point_count) = point_count { + (point_count * 10).max(50) + (cvt_len / 10).max(50) + } else { + 300 + 22 * cvt_len + }; + // FreeType has two variables for neg_jump_counter_max and + // loopcall_counter_max but sets them to the same value so + // we'll just use a single limit. + Self { + limit, + backward_jumps: 0, + loop_calls: 0, + } + } + + fn reset(&mut self) { + self.backward_jumps = 0; + self.loop_calls = 0; + } + + fn doing_backward_jump(&mut self) -> Result<(), HintErrorKind> { + self.backward_jumps += 1; + if self.backward_jumps > self.limit { + Err(HintErrorKind::ExceededExecutionBudget) + } else { + Ok(()) + } + } + + fn doing_loop_call(&mut self, count: usize) -> Result<(), HintErrorKind> { + self.loop_calls += count; + if self.loop_calls > self.limit { + Err(HintErrorKind::ExceededExecutionBudget) + } else { + Ok(()) + } + } +} + +#[cfg(test)] +use mock::MockEngine; + +#[cfg(test)] +mod mock { + use super::{ + super::{ + cow_slice::CowSlice, + definition::{Definition, DefinitionMap, DefinitionState}, + program::{Program, ProgramState}, + zone::Zone, + Point, PointFlags, + }, + Engine, F26Dot6, GraphicsState, LoopBudget, ValueStack, + }; + + /// Mock engine for testing. + pub(super) struct MockEngine { + cvt_storage: Vec, + value_stack: Vec, + definitions: Vec, + unscaled: Vec>, + points: Vec>, + point_flags: Vec, + contours: Vec, + twilight: Vec>, + twilight_flags: Vec, + } + + impl MockEngine { + pub fn new() -> Self { + Self { + cvt_storage: vec![0; 32], + value_stack: vec![0; 32], + definitions: vec![Default::default(); 8], + unscaled: vec![Default::default(); 32], + points: vec![Default::default(); 64], + point_flags: vec![Default::default(); 32], + contours: vec![31], + twilight: vec![Default::default(); 32], + twilight_flags: vec![Default::default(); 32], + } + } + + pub fn engine(&mut self) -> Engine { + let font_code = &[]; + let cv_code = &[]; + let glyph_code = &[]; + let (cvt, storage) = self.cvt_storage.split_at_mut(16); + let (function_defs, instruction_defs) = self.definitions.split_at_mut(5); + let definition = DefinitionState::new( + DefinitionMap::Mut(function_defs), + DefinitionMap::Mut(instruction_defs), + ); + for (i, point) in self.unscaled.iter_mut().enumerate() { + let i = i as i32; + point.x = 57 + i * 2; + point.y = -point.x * 3; + } + let (points, original) = self.points.split_at_mut(32); + let glyph_zone = Zone::new( + &self.unscaled, + original, + points, + &mut self.point_flags, + &self.contours, + ); + let (points, original) = self.twilight.split_at_mut(16); + let twilight_zone = Zone::new(&[], original, points, &mut self.twilight_flags, &[]); + let mut graphics_state = GraphicsState { + zones: [twilight_zone, glyph_zone], + ..Default::default() + }; + graphics_state.update_projection_state(); + Engine { + graphics: graphics_state, + cvt: CowSlice::new_mut(cvt).into(), + storage: CowSlice::new_mut(storage).into(), + value_stack: ValueStack::new(&mut self.value_stack, false), + program: ProgramState::new(font_code, cv_code, glyph_code, Program::Font), + loop_budget: LoopBudget { + limit: 10, + backward_jumps: 0, + loop_calls: 0, + }, + definitions: definition, + axis_count: 0, + coords: &[], + } + } + } + + impl Default for MockEngine { + fn default() -> Self { + Self::new() + } + } + + impl Engine<'_> { + /// Helper to push values to the stack, invoke a callback and check + /// the expected result. + pub(super) fn test_exec( + &mut self, + push: &[i32], + expected_result: impl Into, + mut f: impl FnMut(&mut Engine), + ) { + for &val in push { + self.value_stack.push(val).unwrap(); + } + f(self); + assert_eq!(self.value_stack.pop().ok(), Some(expected_result.into())); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1418 @@ +//! Managing outlines. +//! +//! Implements 87 instructions. +//! +//! See + +use super::{ + super::{ + graphics::CoordAxis, + zone::{PointDisplacement, ZonePointer}, + }, + math, Engine, F26Dot6, HintErrorKind, OpResult, +}; + +impl Engine<'_> { + /// Flip point. + /// + /// FLIPPT[] (0x80) + /// + /// Pops: p: point number (uint32) + /// + /// Uses the loop counter. + /// + /// Flips points that are off the curve so that they are on the curve and + /// points that are on the curve so that they are off the curve. The point + /// is not marked as touched. The result of a FLIPPT instruction is that + /// the contour describing part of a glyph outline is redefined. + /// + /// See + /// and + pub(super) fn op_flippt(&mut self) -> OpResult { + let count = self.graphics.loop_counter as usize; + self.graphics.loop_counter = 1; + // In backward compatibility mode, don't flip points after IUP has + // been done. + if self.graphics.backward_compatibility + && self.graphics.did_iup_x + && self.graphics.did_iup_y + { + for _ in 0..count { + self.value_stack.pop()?; + } + return Ok(()); + } + let zone = self.graphics.zone_mut(ZonePointer::Glyph); + for _ in 0..count { + let p = self.value_stack.pop_usize()?; + zone.flip_on_curve(p)?; + } + Ok(()) + } + + /// Flip range on. + /// + /// FLIPRGON[] (0x81) + /// + /// Pops: highpoint: highest point number in range of points to be flipped (uint32) + /// lowpoint: lowest point number in range of points to be flipped (uint32) + /// + /// Flips a range of points beginning with lowpoint and ending with highpoint so that + /// any off the curve points become on the curve points. The points are not marked as + /// touched. + /// + /// See + /// and + pub(super) fn op_fliprgon(&mut self) -> OpResult { + self.set_on_curve_for_range(true) + } + + /// Flip range off. + /// + /// FLIPRGOFF[] (0x82) + /// + /// Pops: highpoint: highest point number in range of points to be flipped (uint32) + /// lowpoint: lowest point number in range of points to be flipped (uint32) + /// + /// Flips a range of points beginning with lowpoint and ending with + /// highpoint so that any on the curve points become off the curve points. + /// The points are not marked as touched. + /// + /// See + /// and + pub(super) fn op_fliprgoff(&mut self) -> OpResult { + self.set_on_curve_for_range(false) + } + + /// Shift point by the last point. + /// + /// SHP\[a\] (0x32 - 0x33) + /// + /// a: 0: uses rp2 in the zone pointed to by zp1 + /// 1: uses rp1 in the zone pointed to by zp0 + /// + /// Pops: p: point to be shifted + /// + /// Uses the loop counter. + /// + /// Shift point p by the same amount that the reference point has been + /// shifted. Point p is shifted along the freedom_vector so that the + /// distance between the new position of point p and the current position + /// of point p is the same as the distance between the current position + /// of the reference point and the original position of the reference point. + /// + /// See + /// and + pub(super) fn op_shp(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let PointDisplacement { dx, dy, .. } = gs.point_displacement(opcode)?; + let count = gs.loop_counter; + gs.loop_counter = 1; + for _ in 0..count { + let p = self.value_stack.pop_usize()?; + gs.move_zp2_point(p, dx, dy, true)?; + } + Ok(()) + } + + /// Shift contour by the last point. + /// + /// SHC\[a\] (0x34 - 0x35) + /// + /// a: 0: uses rp2 in the zone pointed to by zp1 + /// 1: uses rp1 in the zone pointed to by zp0 + /// + /// Pops: c: contour to be shifted + /// + /// Shifts every point on contour c by the same amount that the reference + /// point has been shifted. Each point is shifted along the freedom_vector + /// so that the distance between the new position of the point and the old + /// position of that point is the same as the distance between the current + /// position of the reference point and the original position of the + /// reference point. The distance is measured along the projection_vector. + /// If the reference point is one of the points defining the contour, the + /// reference point is not moved by this instruction. + /// + /// See + /// and + pub(super) fn op_shc(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let contour_ix = self.value_stack.pop_usize()?; + if !gs.is_pedantic && contour_ix >= gs.zp2().contours.len() { + return Ok(()); + } + let point_disp = gs.point_displacement(opcode)?; + let start = if contour_ix != 0 { + gs.zp2().contour(contour_ix - 1)? as usize + 1 + } else { + 0 + }; + let end = if gs.zp2.is_twilight() { + gs.zp2().points.len() + } else { + gs.zp2().contour(contour_ix)? as usize + 1 + }; + for i in start..end { + if point_disp.zone != gs.zp2 || point_disp.point_ix != i { + gs.move_zp2_point(i, point_disp.dx, point_disp.dy, true)?; + } + } + Ok(()) + } + + /// Shift zone by the last point. + /// + /// SHZ\[a\] (0x36 - 0x37) + /// + /// a: 0: uses rp2 in the zone pointed to by zp1 + /// 1: uses rp1 in the zone pointed to by zp0 + /// + /// Pops: e: zone to be shifted + /// + /// Shift the points in the specified zone (Z1 or Z0) by the same amount + /// that the reference point has been shifted. The points in the zone are + /// shifted along the freedom_vector so that the distance between the new + /// position of the shifted points and their old position is the same as + /// the distance between the current position of the reference point and + /// the original position of the reference point. + /// + /// See + /// and + pub(super) fn op_shz(&mut self, opcode: u8) -> OpResult { + let _e = ZonePointer::try_from(self.value_stack.pop()?)?; + let gs = &mut self.graphics; + let point_disp = gs.point_displacement(opcode)?; + let end = if gs.zp2.is_twilight() { + gs.zp2().points.len() + } else if !gs.zp2().contours.is_empty() { + *gs.zp2() + .contours + .last() + .ok_or(HintErrorKind::InvalidContourIndex(0))? as usize + + 1 + } else { + 0 + }; + for i in 0..end { + if point_disp.zone != gs.zp2 || i != point_disp.point_ix { + gs.move_zp2_point(i, point_disp.dx, point_disp.dy, false)?; + } + } + Ok(()) + } + + /// Shift point by a pixel amount. + /// + /// SHPIX (0x38) + /// + /// Pops: amount: magnitude of the shift (F26Dot6) + /// p1, p2,.. pn: points to be shifted + /// + /// Uses the loop counter. + /// + /// Shifts the points specified by the amount stated. When the loop + /// variable is used, the amount to be shifted is put onto the stack + /// only once. That is, if loop = 3, then the contents of the top of + /// the stack should be point p1, point p2, point p3, amount. The value + /// amount is expressed in sixty-fourths of a pixel. + /// + /// See + /// and + pub(super) fn op_shpix(&mut self) -> OpResult { + let gs = &mut self.graphics; + let in_twilight = gs.zp0.is_twilight() || gs.zp1.is_twilight() || gs.zp2.is_twilight(); + let amount = self.value_stack.pop()?; + let dx = F26Dot6::from_bits(math::mul14(amount, gs.freedom_vector.x)); + let dy = F26Dot6::from_bits(math::mul14(amount, gs.freedom_vector.y)); + let count = gs.loop_counter; + gs.loop_counter = 1; + let did_iup = gs.did_iup_x && gs.did_iup_y; + for _ in 0..count { + let p = self.value_stack.pop_usize()?; + if gs.backward_compatibility { + if in_twilight + || (!did_iup + && ((gs.is_composite && gs.freedom_vector.y != 0) + || gs.zp2().is_touched(p, CoordAxis::Y)?)) + { + gs.move_zp2_point(p, dx, dy, true)?; + } + } else { + gs.move_zp2_point(p, dx, dy, true)?; + } + } + Ok(()) + } + + /// Move stack indirect relative point. + /// + /// MSIRP\[a\] (0x3A - 0x3B) + /// + /// a: 0: do not set rp0 to p + /// 1: set rp0 to p + /// + /// Pops: d: distance (F26Dot6) + /// p: point number + /// + /// Makes the distance between a point p and rp0 equal to the value + /// specified on the stack. The distance on the stack is in fractional + /// pixels (F26Dot6). An MSIRP has the same effect as a MIRP instruction + /// except that it takes its value from the stack rather than the Control + /// Value Table. As a result, the cut_in does not affect the results of a + /// MSIRP. Additionally, MSIRP is unaffected by the round_state. + /// + /// See + /// and + pub(super) fn op_msirp(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let distance = self.value_stack.pop_f26dot6()?; + let point_ix = self.value_stack.pop_usize()?; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp1, point_ix), (gs.zp0, gs.rp0)]) { + return Ok(()); + } + if gs.zp1.is_twilight() { + *gs.zp1_mut().point_mut(point_ix)? = gs.zp0().original(gs.rp0)?; + gs.move_original(gs.zp1, point_ix, distance)?; + *gs.zp1_mut().point_mut(point_ix)? = gs.zp1().original(point_ix)?; + } + let d = gs.project(gs.zp1().point(point_ix)?, gs.zp0().point(gs.rp0)?); + gs.move_point(gs.zp1, point_ix, distance.wrapping_sub(d))?; + gs.rp1 = gs.rp0; + gs.rp2 = point_ix; + if (opcode & 1) != 0 { + gs.rp0 = point_ix; + } + Ok(()) + } + + /// Move direct absolute point. + /// + /// MDAP\[a\] (0x2E - 0x2F) + /// + /// a: 0: do not round the value + /// 1: round the value + /// + /// Pops: p: point number + /// + /// Sets the reference points rp0 and rp1 equal to point p. If a=1, this + /// instruction rounds point p to the grid point specified by the state + /// variable round_state. If a=0, it simply marks the point as touched in + /// the direction(s) specified by the current freedom_vector. This command + /// is often used to set points in the twilight zone. + /// + /// See + /// and + pub(super) fn op_mdap(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let p = self.value_stack.pop_usize()?; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, p)]) { + gs.rp0 = p; + gs.rp1 = p; + return Ok(()); + } + let distance = if (opcode & 1) != 0 { + let cur_dist = gs.project(gs.zp0().point(p)?, Default::default()); + gs.round(cur_dist) - cur_dist + } else { + F26Dot6::ZERO + }; + gs.move_point(gs.zp0, p, distance)?; + gs.rp0 = p; + gs.rp1 = p; + Ok(()) + } + + /// Move indirect absolute point. + /// + /// MIAP\[a\] (0x3E - 0x3F) + /// + /// a: 0: do not round the distance and don't use control value cutin + /// 1: round the distance and use control value cutin + /// + /// Pops: n: CVT entry number + /// p: point number + /// + /// Moves point p to the absolute coordinate position specified by the nth + /// Control Value Table entry. The coordinate is measured along the current + /// projection_vector. If a=1, the position will be rounded as specified by + /// round_state. If a=1, and if the device space difference between the CVT + /// value and the original position is greater than the + /// control_value_cut_in, then the original position will be rounded + /// (instead of the CVT value.) + /// + /// See + /// and + pub(super) fn op_miap(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let cvt_entry = self.value_stack.pop_usize()?; + let point_ix = self.value_stack.pop_usize()?; + let mut distance = self.cvt.get(cvt_entry)?; + if gs.zp0.is_twilight() { + // Special behavior for twilight zone. + // + let fv = gs.freedom_vector; + let z = gs.zp0_mut(); + let original_point = z.original_mut(point_ix)?; + original_point.x = F26Dot6::from_bits(math::mul14(distance.to_bits(), fv.x)); + original_point.y = F26Dot6::from_bits(math::mul14(distance.to_bits(), fv.y)); + *z.point_mut(point_ix)? = *original_point; + } + let original_distance = gs.project(gs.zp0().point(point_ix)?, Default::default()); + if (opcode & 1) != 0 { + let delta = (distance.wrapping_sub(original_distance)).abs(); + if delta > gs.control_value_cutin { + distance = original_distance; + } + distance = gs.round(distance); + } + gs.move_point(gs.zp0, point_ix, distance.wrapping_sub(original_distance))?; + gs.rp0 = point_ix; + gs.rp1 = point_ix; + Ok(()) + } + + /// Move direct relative point. + /// + /// MDRP\[abcde\] (0xC0 - 0xDF) + /// + /// a: 0: do not set rp0 to point p after move + /// 1: do set rp0 to point p after move + /// b: 0: do not keep distance greater than or equal to minimum_distance + /// 1: keep distance greater than or equal to minimum_distance + /// c: 0: do not round distance + /// 1: round the distance + /// de: distance type for engine characteristic compensation + /// + /// Pops: p: point number + /// + /// MDRP moves point p along the freedom_vector so that the distance from + /// its new position to the current position of rp0 is the same as the + /// distance between the two points in the original uninstructed outline, + /// and then adjusts it to be consistent with the Boolean settings. Note + /// that it is only the original positions of rp0 and point p and the + /// current position of rp0 that determine the new position of point p + /// along the freedom_vector. + /// + /// See + /// and + pub(super) fn op_mdrp(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let p = self.value_stack.pop_usize()?; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp1, p), (gs.zp0, gs.rp0)]) { + gs.rp1 = gs.rp0; + gs.rp2 = p; + if (opcode & 16) != 0 { + gs.rp0 = p; + } + return Ok(()); + } + let mut original_distance = if gs.zp0.is_twilight() || gs.zp1.is_twilight() { + gs.dual_project(gs.zp1().original(p)?, gs.zp0().original(gs.rp0)?) + } else { + let v1 = gs.zp1().unscaled(p); + let v2 = gs.zp0().unscaled(gs.rp0); + let dist = gs.dual_project_unscaled(v1, v2); + F26Dot6::from_bits(math::mul(dist, gs.unscaled_to_pixels())) + }; + let cutin = gs.single_width_cutin; + let value = gs.single_width; + if cutin > F26Dot6::ZERO + && original_distance < value + cutin + && original_distance > value - cutin + { + original_distance = if original_distance >= F26Dot6::ZERO { + value + } else { + -value + }; + } + // round flag + let mut distance = if (opcode & 4) != 0 { + gs.round(original_distance) + } else { + original_distance + }; + // minimum distance flag + if (opcode & 8) != 0 { + let min_distance = gs.min_distance; + if original_distance >= F26Dot6::ZERO { + if distance < min_distance { + distance = min_distance; + } + } else if distance > -min_distance { + distance = -min_distance; + } + } + original_distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); + gs.move_point(gs.zp1, p, distance.wrapping_sub(original_distance))?; + gs.rp1 = gs.rp0; + gs.rp2 = p; + if (opcode & 16) != 0 { + gs.rp0 = p; + } + Ok(()) + } + + /// Move indirect relative point. + /// + /// MIRP\[abcde\] (0xE0 - 0xFF) + /// + /// a: 0: do not set rp0 to point p after move + /// 1: do set rp0 to point p after move + /// b: 0: do not keep distance greater than or equal to minimum_distance + /// 1: keep distance greater than or equal to minimum_distance + /// c: 0: do not round distance and do not look at control_value_cutin + /// 1: round the distance and look at control_value_cutin + /// de: distance type for engine characteristic compensation + /// + /// Pops: n: CVT entry number + /// p: point number + /// + /// A MIRP instruction makes it possible to preserve the distance between + /// two points subject to a number of qualifications. Depending upon the + /// setting of Boolean flag b, the distance can be kept greater than or + /// equal to the value established by the minimum_distance state variable. + /// Similarly, the instruction can be set to round the distance according + /// to the round_state graphics state variable. The value of the minimum + /// distance variable is the smallest possible value the distance between + /// two points can be rounded to. Additionally, if the c Boolean is set, + /// the MIRP instruction acts subject to the control_value_cut_in. If the + /// difference between the actual measurement and the value in the CVT is + /// sufficiently small (less than the cut_in_value), the CVT value will be + /// used and not the actual value. If the device space difference between + /// this distance from the CVT and the single_width_value is smaller than + /// the single_width_cut_in, then use the single_width_value rather than + /// the outline or Control Value Table distance. + /// + /// See + /// and + pub(super) fn op_mirp(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let n = (self.value_stack.pop()? + 1) as usize; + let p = self.value_stack.pop_usize()?; + if !gs.is_pedantic + && (!gs.in_bounds([(gs.zp1, p), (gs.zp0, gs.rp0)]) || (n > self.cvt.len())) + { + gs.rp1 = gs.rp0; + if (opcode & 16) != 0 { + gs.rp0 = p; + } + gs.rp2 = p; + return Ok(()); + } + let mut cvt_distance = if n == 0 { + F26Dot6::ZERO + } else { + self.cvt.get(n - 1)? + }; + // single width test + let cutin = gs.single_width_cutin; + let value = gs.single_width; + let mut delta = cvt_distance.wrapping_sub(value).abs(); + if delta < cutin { + cvt_distance = if cvt_distance >= F26Dot6::ZERO { + value + } else { + -value + }; + } + if gs.zp1.is_twilight() { + let fv = gs.freedom_vector; + let point = { + let d = cvt_distance.to_bits(); + let p2 = gs.zp0().original(gs.rp0)?; + let p1 = gs.zp1_mut().original_mut(p)?; + p1.x = p2.x + F26Dot6::from_bits(math::mul(d, fv.x)); + p1.y = p2.y + F26Dot6::from_bits(math::mul(d, fv.y)); + *p1 + }; + *gs.zp1_mut().point_mut(p)? = point; + } + let original_distance = gs.dual_project(gs.zp1().original(p)?, gs.zp0().original(gs.rp0)?); + let current_distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); + // auto flip test + if gs.auto_flip && (original_distance.to_bits() ^ cvt_distance.to_bits()) < 0 { + cvt_distance = -cvt_distance; + } + // control value cutin and round + let mut distance = if (opcode & 4) != 0 { + if gs.zp0 == gs.zp1 { + delta = cvt_distance.wrapping_sub(original_distance).abs(); + if delta > gs.control_value_cutin { + cvt_distance = original_distance; + } + } + gs.round(cvt_distance) + } else { + cvt_distance + }; + // minimum distance test + if (opcode & 8) != 0 { + let min_distance = gs.min_distance; + if original_distance >= F26Dot6::ZERO { + if distance < min_distance { + distance = min_distance + }; + } else if distance > -min_distance { + distance = -min_distance + } + } + gs.move_point(gs.zp1, p, distance.wrapping_sub(current_distance))?; + gs.rp1 = gs.rp0; + if (opcode & 16) != 0 { + gs.rp0 = p; + } + gs.rp2 = p; + Ok(()) + } + + /// Align relative point. + /// + /// ALIGNRP[] (0x3C) + /// + /// Pops: p: point number (uint32) + /// + /// Uses the loop counter. + /// + /// Reduces the distance between rp0 and point p to zero. Since distance + /// is measured along the projection_vector and movement is along the + /// freedom_vector, the effect of the instruction is to align points. + /// + /// See + /// and + pub(super) fn op_alignrp(&mut self) -> OpResult { + let gs = &mut self.graphics; + let count = gs.loop_counter; + gs.loop_counter = 1; + for _ in 0..count { + let p = self.value_stack.pop_usize()?; + let distance = gs.project(gs.zp1().point(p)?, gs.zp0().point(gs.rp0)?); + gs.move_point(gs.zp1, p, -distance)?; + } + Ok(()) + } + + /// Move point to intersection of two lines. + /// + /// ISECT[] (0x0F) + /// + /// Pops: b1: end point of line 2 + /// b0: start point of line 2 + /// a1: end point of line 1 + /// a0: start point of line 1 + /// p: point to move. + /// + /// Puts point p at the intersection of the lines A and B. The points a0 + /// and a1 define line A. Similarly, b0 and b1 define line B. ISECT + /// ignores the freedom_vector in moving point p. + /// + /// See + /// and + pub(super) fn op_isect(&mut self) -> OpResult { + let gs = &mut self.graphics; + let b1 = self.value_stack.pop_usize()?; + let b0 = self.value_stack.pop_usize()?; + let a1 = self.value_stack.pop_usize()?; + let a0 = self.value_stack.pop_usize()?; + let point_ix = self.value_stack.pop_usize()?; + // Lots of funky fixed point math so just map these to i32 to avoid + // a bunch of wrapping/unwrapping. + // To shreds you say! + let [pa0, pa1] = { + let z = gs.zp1(); + [z.point(a0)?, z.point(a1)?].map(|p| p.map(F26Dot6::to_bits)) + }; + let [pb0, pb1] = { + let z = gs.zp0(); + [z.point(b0)?, z.point(b1)?].map(|p| p.map(F26Dot6::to_bits)) + }; + let dbx = pb1.x - pb0.x; + let dby = pb1.y - pb0.y; + let dax = pa1.x - pa0.x; + let day = pa1.y - pa0.y; + let dx = pb0.x - pa0.x; + let dy = pb0.y - pa0.y; + use math::mul_div; + let discriminant = mul_div(dax, -dby, 0x40) + mul_div(day, dbx, 0x40); + let dotproduct = mul_div(dax, dbx, 0x40) + mul_div(day, dby, 0x40); + // Useful context from FreeType: + // + // "The discriminant above is actually a cross product of vectors + // da and db. Together with the dot product, they can be used as + // surrogates for sine and cosine of the angle between the vectors. + // Indeed, + // dotproduct = |da||db|cos(angle) + // discriminant = |da||db|sin(angle) + // We use these equations to reject grazing intersections by + // thresholding abs(tan(angle)) at 1/19, corresponding to 3 degrees." + // + // See + if 19 * discriminant.abs() > dotproduct.abs() { + let v = mul_div(dx, -dby, 0x40) + mul_div(dy, dbx, 0x40); + let x = mul_div(v, dax, discriminant); + let y = mul_div(v, day, discriminant); + let point = gs.zp2_mut().point_mut(point_ix)?; + point.x = F26Dot6::from_bits(pa0.x + x); + point.y = F26Dot6::from_bits(pa0.y + y); + } else { + let point = gs.zp2_mut().point_mut(point_ix)?; + point.x = F26Dot6::from_bits((pa0.x + pa1.x + pb0.x + pb1.x) / 4); + point.y = F26Dot6::from_bits((pa0.y + pa1.y + pb0.y + pb1.y) / 4); + } + gs.zp2_mut().touch(point_ix, CoordAxis::Both)?; + Ok(()) + } + + /// Align points. + /// + /// ALIGNPTS[] (0x27) + /// + /// Pops: p1: point number + /// p2: point number + /// + /// Makes the distance between point 1 and point 2 zero by moving both + /// along the freedom_vector to the average of both their projections + /// along the projection_vector. + /// + /// See + /// and + pub(super) fn op_alignpts(&mut self) -> OpResult { + let p2 = self.value_stack.pop_usize()?; + let p1 = self.value_stack.pop_usize()?; + let gs = &mut self.graphics; + let distance = F26Dot6::from_bits( + gs.project(gs.zp0().point(p2)?, gs.zp1().point(p1)?) + .to_bits() + / 2, + ); + gs.move_point(gs.zp1, p1, distance)?; + gs.move_point(gs.zp0, p2, -distance)?; + Ok(()) + } + + /// Interpolate point by last relative stretch. + /// + /// IP[] (0x39) + /// + /// Pops: p: point number + /// + /// Uses the loop counter. + /// + /// Moves point p so that its relationship to rp1 and rp2 is the same as it + /// was in the original uninstructed outline. Measurements are made along + /// the projection_vector, and movement to satisfy the interpolation + /// relationship is constrained to be along the freedom_vector. This + /// instruction is not valid if rp1 and rp2 have the same position on the + /// projection_vector. + /// + /// See + /// and + pub(super) fn op_ip(&mut self) -> OpResult { + let gs = &mut self.graphics; + let count = gs.loop_counter; + gs.loop_counter = 1; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp0, gs.rp1), (gs.zp1, gs.rp2)]) { + return Ok(()); + } + let in_twilight = gs.zp0.is_twilight() || gs.zp1.is_twilight() || gs.zp2.is_twilight(); + let orus_base = if in_twilight { + gs.zp0().original(gs.rp1)? + } else { + gs.zp0().unscaled(gs.rp1).map(F26Dot6::from_bits) + }; + let cur_base = gs.zp0().point(gs.rp1)?; + let old_range = if in_twilight { + gs.dual_project(gs.zp1().original(gs.rp2)?, orus_base) + } else { + gs.dual_project(gs.zp1().unscaled(gs.rp2).map(F26Dot6::from_bits), orus_base) + }; + let cur_range = gs.project(gs.zp1().point(gs.rp2)?, cur_base); + for _ in 0..count { + let point = self.value_stack.pop_usize()?; + if !gs.is_pedantic && !gs.in_bounds([(gs.zp2, point)]) { + continue; + } + let original_distance = if in_twilight { + gs.dual_project(gs.zp2().original(point)?, orus_base) + } else { + gs.dual_project(gs.zp2().unscaled(point).map(F26Dot6::from_bits), orus_base) + }; + let cur_distance = gs.project(gs.zp2().point(point)?, cur_base); + let new_distance = if original_distance != F26Dot6::ZERO { + if old_range != F26Dot6::ZERO { + F26Dot6::from_bits(math::mul_div( + original_distance.to_bits(), + cur_range.to_bits(), + old_range.to_bits(), + )) + } else { + original_distance + } + } else { + F26Dot6::ZERO + }; + gs.move_point(gs.zp2, point, new_distance.wrapping_sub(cur_distance))?; + } + Ok(()) + } + + /// Interpolate untouched points through the outline. + /// + /// IUP\[a\] (0x30 - 0x31) + /// + /// a: 0: interpolate in the y-direction + /// 1: interpolate in the x-direction + /// + /// Considers a glyph contour by contour, moving any untouched points in + /// each contour that are between a pair of touched points. If the + /// coordinates of an untouched point were originally between those of + /// the touched pair, it is linearly interpolated between the new + /// coordinates, otherwise the untouched point is shifted by the amount + /// the nearest touched point is shifted. + /// + /// See + /// and + pub(super) fn op_iup(&mut self, opcode: u8) -> OpResult { + let gs = &mut self.graphics; + let axis = if (opcode & 1) != 0 { + CoordAxis::X + } else { + CoordAxis::Y + }; + let mut run = true; + // In backward compatibility mode, allow IUP until it has been done on + // both axes. + if gs.backward_compatibility { + if gs.did_iup_x && gs.did_iup_y { + run = false; + } + if axis == CoordAxis::X { + gs.did_iup_x = true; + } else { + gs.did_iup_y = true; + } + } + if run { + gs.zone_mut(ZonePointer::Glyph).iup(axis)?; + } + Ok(()) + } + + /// Untouch point. + /// + /// UTP[] (0x29) + /// + /// Pops: p: point number (uint32) + /// + /// Marks point p as untouched. A point may be touched in the x direction, + /// the y direction, both, or neither. This instruction uses the current + /// freedom_vector to determine whether to untouch the point in the + /// x-direction, the y direction, or both. Points that are marked as + /// untouched will be moved by an IUP (interpolate untouched points) + /// instruction. Using UTP you can ensure that a point will be affected + /// by IUP even if it was previously touched. + /// + /// See + /// and + pub(super) fn op_utp(&mut self) -> OpResult { + let p = self.value_stack.pop_usize()?; + let coord_axis = match ( + self.graphics.freedom_vector.x != 0, + self.graphics.freedom_vector.y != 0, + ) { + (true, true) => Some(CoordAxis::Both), + (true, false) => Some(CoordAxis::X), + (false, true) => Some(CoordAxis::Y), + (false, false) => None, + }; + if let Some(coord_axis) = coord_axis { + self.graphics.zp0_mut().untouch(p, coord_axis)?; + } + Ok(()) + } + + /// Helper for FLIPRGON and FLIPRGOFF. + fn set_on_curve_for_range(&mut self, on: bool) -> OpResult { + let high_point = self.value_stack.pop_usize()?; + let low_point = self.value_stack.pop_usize()?; + // high_point is inclusive but Zone::set_on_curve takes an exclusive + // range + let high_point = high_point + .checked_add(1) + .ok_or(HintErrorKind::InvalidPointIndex(high_point))?; + // In backward compatibility mode, don't flip points after IUP has + // been done. + if self.graphics.backward_compatibility + && self.graphics.did_iup_x + && self.graphics.did_iup_y + { + return Ok(()); + } + self.graphics + .zone_mut(ZonePointer::Glyph) + .set_on_curve(low_point, high_point, on) + } +} + +#[cfg(test)] +mod tests { + use super::{super::MockEngine, math, CoordAxis, Engine, ZonePointer}; + use raw::{ + tables::glyf::{bytecode::Opcode, PointMarker}, + types::{F26Dot6, Point}, + }; + + #[test] + fn flip_point() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Points all start as off-curve in the mock engine. + // Flip every odd point in the first 10 + let count = 5; + // First, set the loop counter: + engine.value_stack.push(count).unwrap(); + engine.op_sloop().unwrap(); + // Now push the point indices + for i in (1..=9).step_by(2) { + engine.value_stack.push(i).unwrap(); + } + assert_eq!(engine.value_stack.len(), count as usize); + // And flip! + engine.op_flippt().unwrap(); + let flags = &engine.graphics.zones[1].flags; + for i in 0..10 { + // Odd points are now on-curve + assert_eq!(flags[i].is_on_curve(), i & 1 != 0); + } + } + + /// Backward compat + IUP state prevents flipping. + #[test] + fn state_prevents_flip_point() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Points all start as off-curve in the mock engine. + // Flip every odd point in the first 10 + let count = 5; + // First, set the loop counter: + engine.value_stack.push(count).unwrap(); + engine.op_sloop().unwrap(); + // Now push the point indices + for i in (1..=9).step_by(2) { + engine.value_stack.push(i).unwrap(); + } + assert_eq!(engine.value_stack.len(), count as usize); + // Prevent flipping + engine.graphics.backward_compatibility = true; + engine.graphics.did_iup_x = true; + engine.graphics.did_iup_y = true; + // But try anyway + engine.op_flippt().unwrap(); + let flags = &engine.graphics.zones[1].flags; + for i in 0..10 { + // All points are still off-curve + assert!(!flags[i].is_on_curve()); + } + } + + #[test] + fn flip_range_on_off() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Points all start as off-curve in the mock engine. + // Flip 10..=20 on + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(20).unwrap(); + engine.op_fliprgon().unwrap(); + for (i, flag) in engine.graphics.zones[1].flags.iter().enumerate() { + assert_eq!(flag.is_on_curve(), (10..=20).contains(&i)); + } + // Now flip 12..=15 off + engine.value_stack.push(12).unwrap(); + engine.value_stack.push(15).unwrap(); + engine.op_fliprgoff().unwrap(); + for (i, flag) in engine.graphics.zones[1].flags.iter().enumerate() { + assert_eq!( + flag.is_on_curve(), + (10..=11).contains(&i) || (16..=20).contains(&i) + ); + } + } + + /// Backward compat + IUP state prevents flipping. + #[test] + fn state_prevents_flip_range_on_off() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Prevent flipping + engine.graphics.backward_compatibility = true; + engine.graphics.did_iup_x = true; + engine.graphics.did_iup_y = true; + // Points all start as off-curve in the mock engine. + // Try to flip 10..=20 on + engine.value_stack.push(10).unwrap(); + engine.value_stack.push(20).unwrap(); + engine.op_fliprgon().unwrap(); + for flag in engine.graphics.zones[1].flags.iter() { + assert!(!flag.is_on_curve()); + } + // Reset all points to on + for flag in engine.graphics.zones[1].flags.iter_mut() { + flag.set_on_curve(); + } + // Now try to flip 12..=15 off + engine.value_stack.push(12).unwrap(); + engine.value_stack.push(15).unwrap(); + engine.op_fliprgoff().unwrap(); + for flag in engine.graphics.zones[1].flags.iter() { + assert!(flag.is_on_curve()); + } + } + + #[test] + fn untouch_point() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + // Touch all points in both axes to start. + let count = engine.graphics.zones[1].points.len(); + for i in 0..count { + engine.graphics.zones[1].touch(i, CoordAxis::Both).unwrap(); + } + let mut untouch = |point_ix: usize, fx, fy, marker| { + assert!(engine.graphics.zp0().flags[point_ix].has_marker(marker)); + // Untouch axis is based on freedom vector: + engine.graphics.freedom_vector.x = fx; + engine.graphics.freedom_vector.y = fy; + engine.value_stack.push(point_ix as i32).unwrap(); + engine.op_utp().unwrap(); + assert!(!engine.graphics.zp0().flags[point_ix].has_marker(marker)); + }; + // Untouch point 0 in x axis + untouch(0, 1, 0, PointMarker::TOUCHED_X); + // Untouch point 1 in y axis + untouch(1, 0, 1, PointMarker::TOUCHED_Y); + // untouch point 2 in both axes + untouch(2, 1, 1, PointMarker::TOUCHED); + } + + #[test] + fn shp() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp2 = ZonePointer::Glyph; + engine.graphics.rp2 = 1; + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + engine.value_stack.push(1).unwrap(); + engine.op_shp(0).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(136, -254)); + } + + #[test] + fn shc() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp2 = ZonePointer::Glyph; + engine.graphics.rp2 = 1; + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + engine.value_stack.push(0).unwrap(); + engine.op_shc(0).unwrap(); + let points = engine.graphics.zones[1] + .points + .iter() + .map(|p| p.map(F26Dot6::to_bits)) + .take(3) + .collect::>(); + assert_eq!( + points, + &[Point::new(4, 2), Point::new(132, -256), Point::new(4, 2),] + ); + } + + #[test] + fn shz() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp2 = ZonePointer::Glyph; + engine.graphics.rp2 = 1; + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + engine.value_stack.push(0).unwrap(); + engine.op_shz(0).unwrap(); + let points = engine.graphics.zones[1] + .points + .iter() + .map(|p| p.map(F26Dot6::to_bits)) + .take(3) + .collect::>(); + assert_eq!( + points, + &[Point::new(4, 2), Point::new(132, -256), Point::new(4, 2),] + ); + } + + #[test] + fn shpix() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp2 = ZonePointer::Glyph; + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + // point index + engine.value_stack.push(1).unwrap(); + // amount to move in pixels along freedom vector + engine.value_stack.push(42).unwrap(); + engine.op_shpix().unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(170, -237)); + } + + #[test] + fn msirp() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp1 = ZonePointer::Glyph; + let point = engine.graphics.zones[1].point_mut(1).unwrap(); + point.x = F26Dot6::from_bits(132); + point.y = F26Dot6::from_bits(-256); + // point index + engine.value_stack.push(1).unwrap(); + // amount to move in pixels along freedom vector + engine.value_stack.push(-42).unwrap(); + engine.op_msirp(0).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(91, -277)); + assert_eq!(engine.graphics.rp0, 0); + // opcode with bit 0 set changes rp0 to point_ix + engine.value_stack.push(4).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_msirp(1).unwrap(); + assert_eq!(engine.graphics.rp0, 4); + } + + #[test] + fn mdap() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + // with rounding + engine.set_point_f26dot6(1, 1, (132, -256)); + engine.value_stack.push(1).unwrap(); + engine.op_mdap(1).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(128, -258)); + // without rounding + engine.set_point_f26dot6(1, 2, (132, -256)); + engine.value_stack.push(2).unwrap(); + engine.op_mdap(0).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(132, -256)); + } + + #[test] + fn miap() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + // set a CVT distance + engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); + // with rounding + engine.set_point_f26dot6(1, 1, (132, -256)); + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_miap(1).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); + // without rounding + engine.set_point_f26dot6(1, 2, (132, -256)); + engine.value_stack.push(2).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_miap(0).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(171, -236)); + } + + /// Tests bit 'a' of MDRP which just sets rp0 to the adjusted point + /// after move. + #[test] + fn mdrp_rp0() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.graphics.rp0 = 0; + // Don't change rp0 + engine.value_stack.push(1).unwrap(); + engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); + assert_eq!(engine.graphics.rp0, 0); + // Change rp0 + engine.value_stack.push(1).unwrap(); + engine.op_mdrp(Opcode::MDRP10000 as _).unwrap(); + assert_eq!(engine.graphics.rp0, 1); + } + + /// Test bit "b" which controls whether distances are adjusted + /// to the minimum_distance field of GraphicsState. + #[test] + fn mdrp_mindist() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + // without min distance check + engine.set_point_f26dot6(1, 1, (132, -256)); + engine.value_stack.push(1).unwrap(); + engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(128, -258)); + // with min distance check + engine.set_point_f26dot6(1, 2, (132, -256)); + engine.value_stack.push(2).unwrap(); + engine.op_mdrp(Opcode::MDRP01000 as _).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); + } + + /// Test bit "c" which controls whether distances are rounded. + #[test] + fn mdrp_round() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.op_rthg().unwrap(); + // without rounding + engine.set_point_f26dot6(1, 1, (132, -231)); + engine.value_stack.push(1).unwrap(); + engine.op_mdrp(Opcode::MDRP00000 as _).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(119, -238)); + // with rounding + engine.set_point_f26dot6(1, 2, (132, -231)); + engine.value_stack.push(2).unwrap(); + engine.op_mdrp(Opcode::MDRP00100 as _).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); + } + + /// Tests bit 'a' of MIRP which just sets rp0 to the adjusted point + /// after move. + #[test] + fn mirp_rp0() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.graphics.rp0 = 0; + // Don't change rp0 + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); + assert_eq!(engine.graphics.rp0, 0); + // Change rp0 + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP10000 as _).unwrap(); + assert_eq!(engine.graphics.rp0, 1); + } + + /// Test bit "b" which controls whether distances are adjusted + /// to the minimum_distance field of GraphicsState. + #[test] + fn mirp_mindist() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + // set a CVT distance + engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); + // without min distance check + engine.set_point_f26dot6(1, 1, (132, -256)); + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(171, -236)); + // with min distance check + engine.set_point_f26dot6(1, 2, (132, -256)); + engine.value_stack.push(2).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP01000 as _).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(186, -229)); + } + + /// Test bit "c" which controls whether distances are rounded. + #[test] + fn mirp_round() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + // set a CVT distance + engine.cvt.set(1, F26Dot6::from_f64(0.75)).unwrap(); + engine.op_rthg().unwrap(); + // without rounding + engine.set_point_f26dot6(1, 1, (132, -231)); + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP00000 as _).unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(162, -216)); + // with rounding + engine.set_point_f26dot6(1, 2, (132, -231)); + engine.value_stack.push(2).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_mirp(Opcode::MIRP00100 as _).unwrap(); + let point = engine.graphics.zones[1].point(2).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); + } + + #[test] + fn alignrp() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp1 = ZonePointer::Glyph; + engine.graphics.rp0 = 0; + engine.set_point_f26dot6(1, 0, (132, -231)); + engine.set_point_f26dot6(1, 1, (-72, 109)); + engine.value_stack.push(1).unwrap(); + engine.op_alignrp().unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(-45, 122)); + } + + #[test] + fn isect() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp1 = ZonePointer::Glyph; + engine.graphics.rp0 = 0; + // Two points for line 1 + engine.set_point_f26dot6(1, 0, (0, 0)); + engine.set_point_f26dot6(1, 1, (100, 100)); + // And two more for line 2 + engine.set_point_f26dot6(1, 2, (0, 100)); + engine.set_point_f26dot6(1, 3, (100, 0)); + // Push point numbers: first is the point where the + // intersection should be stored. + for ix in [4, 0, 1, 2, 3] { + engine.value_stack.push(ix).unwrap(); + } + engine.op_isect().unwrap(); + let point = engine.graphics.zones[1].point(4).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(50, 50)); + } + + #[test] + fn alignpts() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp1 = ZonePointer::Glyph; + engine.set_point_f26dot6(1, 0, (132, -231)); + engine.set_point_f26dot6(1, 1, (-72, 109)); + engine.value_stack.push(0).unwrap(); + engine.value_stack.push(1).unwrap(); + engine.op_alignpts().unwrap(); + let p1 = engine.graphics.zones[1].point(0).unwrap(); + let p2 = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(p1.map(F26Dot6::to_bits), Point::new(119, -238)); + assert_eq!(p2.map(F26Dot6::to_bits), Point::new(-59, 116)); + } + + #[test] + fn ip() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + set_test_vectors(&mut engine); + engine.graphics.backward_compatibility = false; + engine.graphics.zp0 = ZonePointer::Glyph; + engine.graphics.zp1 = ZonePointer::Glyph; + engine.graphics.zp2 = ZonePointer::Glyph; + engine.graphics.rp1 = 2; + engine.graphics.rp2 = 3; + engine.set_point_f26dot6(1, 2, (72, -109)); + engine.set_point_f26dot6(1, 1, (132, -231)); + engine.value_stack.push(1).unwrap(); + engine.op_ip().unwrap(); + let point = engine.graphics.zones[1].point(1).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(147, -223)); + } + + #[test] + fn iup_flags() { + // IUP shift and interpolate logic is tested in ../zone.rs so just + // check the flags here. + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + assert!(!engine.graphics.did_iup_x); + assert!(!engine.graphics.did_iup_y); + // IUP[y] + engine.op_iup(0).unwrap(); + assert!(!engine.graphics.did_iup_x); + assert!(engine.graphics.did_iup_y); + // IUP[x] + engine.op_iup(1).unwrap(); + assert!(engine.graphics.did_iup_x); + assert!(engine.graphics.did_iup_y); + } + + // Add with overflow caught by fuzzer: + // https://issues.oss-fuzz.com/issues/377736138 + #[test] + fn flip_region_avoid_overflow() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + engine.value_stack.push(1).unwrap(); + engine.value_stack.push(-1).unwrap(); + // Just don't panic + let _ = engine.set_on_curve_for_range(true); + } + + fn set_test_vectors(engine: &mut Engine) { + let v = math::normalize14(100, 50); + engine.graphics.proj_vector = v; + engine.graphics.dual_proj_vector = v; + engine.graphics.freedom_vector = v; + engine.graphics.update_projection_state(); + } + + impl Engine<'_> { + fn set_point_f26dot6(&mut self, zone_ix: usize, point_ix: usize, xy: (i32, i32)) { + let p = self.graphics.zones[zone_ix].point_mut(point_ix).unwrap(); + p.x = F26Dot6::from_bits(xy.0); + p.y = F26Dot6::from_bits(xy.1); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,76 @@ +//! Compensating for the engine characteristics (rounding). +//! +//! Implements 4 instructions. +//! +//! See + +use super::{Engine, OpResult}; + +impl Engine<'_> { + /// Round value. + /// + /// ROUND\[ab\] (0x68 - 0x6B) + /// + /// Pops: n1 + /// Pushes: n2 + /// + /// Rounds a value according to the state variable round_state while + /// compensating for the engine. n1 is popped off the stack and, + /// depending on the engine characteristics, is increased or decreased + /// by a set amount. The number obtained is then rounded and pushed + /// back onto the stack as n2. + /// + /// See + /// and + pub(super) fn op_round(&mut self) -> OpResult { + let n1 = self.value_stack.pop_f26dot6()?; + let n2 = self.graphics.round(n1); + self.value_stack.push(n2.to_bits()) + } +} + +#[cfg(test)] +mod tests { + use super::super::{super::round::RoundMode, MockEngine}; + + #[test] + fn round() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + use RoundMode::*; + let cases = [ + (Grid, &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)]), + ( + HalfGrid, + &[(0, 32), (32, 32), (-32, -32), (64, 96), (50, 32)], + ), + ( + DoubleGrid, + &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 64)], + ), + (DownToGrid, &[(0, 0), (32, 0), (-32, 0), (64, 64), (50, 0)]), + ( + UpToGrid, + &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], + ), + (Off, &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 50)]), + ]; + for (mode, values) in cases { + match mode { + Grid => engine.op_rtg().unwrap(), + HalfGrid => engine.op_rthg().unwrap(), + DoubleGrid => engine.op_rtdg().unwrap(), + DownToGrid => engine.op_rdtg().unwrap(), + UpToGrid => engine.op_rutg().unwrap(), + Off => engine.op_roff().unwrap(), + _ => unreachable!(), + } + for (input, expected) in values { + engine.value_stack.push(*input).unwrap(); + engine.op_round().unwrap(); + let result = engine.value_stack.pop().unwrap(); + assert_eq!(*expected, result); + } + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,224 @@ +//! Managing the stack and pushing data onto the interpreter stack. +//! +//! Implements 26 instructions. +//! +//! See +//! and + +use read_fonts::tables::glyf::bytecode::InlineOperands; + +use super::{Engine, OpResult}; + +impl Engine<'_> { + /// Duplicate top stack element. + /// + /// DUP[] (0x20) + /// + /// Pops: e + /// Pushes: e, e + /// + /// Duplicates the element at the top of the stack. + /// + /// See + /// and + pub(super) fn op_dup(&mut self) -> OpResult { + self.value_stack.dup() + } + + /// Pop top stack element. + /// + /// POP[] (0x21) + /// + /// Pops: e + /// + /// Pops the top element of the stack. + /// + /// See + /// and + pub(super) fn op_pop(&mut self) -> OpResult { + self.value_stack.pop()?; + Ok(()) + } + + /// Clear the entire stack. + /// + /// CLEAR[] (0x22) + /// + /// Pops: all the items on the stack + /// + /// Clears all elements from the stack. + /// + /// See + /// and + pub(super) fn op_clear(&mut self) -> OpResult { + self.value_stack.clear(); + Ok(()) + } + + /// Swap the top two elements on the stack. + /// + /// SWAP[] (0x23) + /// + /// Pops: e2, e1 + /// Pushes: e1, e2 + /// + /// Swaps the top two elements of the stack making the old top element the + /// second from the top and the old second element the top element. + /// + /// See + /// and + pub(super) fn op_swap(&mut self) -> OpResult { + self.value_stack.swap() + } + + /// Returns the depth of the stack. + /// + /// DEPTH[] (0x24) + /// + /// Pushes: n; number of elements + /// + /// Pushes n, the number of elements currently in the stack onto the stack. + /// + /// See + /// and + pub(super) fn op_depth(&mut self) -> OpResult { + let n = self.value_stack.len(); + self.value_stack.push(n as i32) + } + + /// Copy the indexed element to the top of the stack. + /// + /// CINDEX[] (0x25) + /// + /// Pops: k: stack element number + /// Pushes: ek: indexed element + /// + /// Puts a copy of the kth stack element on the top of the stack. + /// + /// See + /// and + pub(super) fn op_cindex(&mut self) -> OpResult { + self.value_stack.copy_index() + } + + /// Move the indexed element to the top of the stack. + /// + /// MINDEX[] (0x26) + /// + /// Pops: k: stack element number + /// Pushes: ek: indexed element + /// + /// Moves the indexed element to the top of the stack. + /// + /// See + /// and + pub(super) fn op_mindex(&mut self) -> OpResult { + self.value_stack.move_index() + } + + /// Roll the top three stack elements. + /// + /// ROLL[] (0x8a) + /// + /// Pops: a, b, c (top three stack elements) + /// Pushes: b, a, c (elements reordered) + /// + /// Performs a circular shift of the top three objects on the stack with + /// the effect being to move the third element to the top of the stack + /// and to move the first two elements down one position. ROLL is + /// equivalent to MINDEX[] 3. + /// + /// See + /// and + pub(super) fn op_roll(&mut self) -> OpResult { + self.value_stack.roll() + } + + /// Push data onto the interpreter stack. + /// + /// NPUSHB[] (0x8a) + /// + /// Takes n unsigned bytes from the instruction stream, where n is an + /// unsigned integer in the range (0..255), and pushes them onto the stack. + /// n itself is not pushed onto the stack. + /// + /// NPUSHW[] (0x41) + /// + /// Takes n 16-bit signed words from the instruction stream, where n is an + /// unsigned integer in the range (0..255), and pushes them onto the stack. + /// n itself is not pushed onto the stack. + /// + /// PUSHB\[abc\] (0xB0 - 0xB7) + /// + /// Takes the specified number of bytes from the instruction stream and + /// pushes them onto the interpreter stack. + /// The variables a, b, and c are binary digits representing numbers from + /// 000 to 111 (0-7 in binary). Because the actual number of bytes (n) is + /// from 1 to 8, 1 is automatically added to the ABC figure to obtain the + /// actual number of bytes pushed. + /// + /// PUSHW\[abc\] (0xB8 - 0xBF) + /// + /// Takes the specified number of words from the instruction stream and + /// pushes them onto the interpreter stack. + /// The variables a, b, and c are binary digits representing numbers from + /// 000 to 111 (0-7 binary). Because the actual number of bytes (n) is from + /// 1 to 8, 1 is automatically added to the abc figure to obtain the actual + /// number of bytes pushed. + /// + /// See + /// and + pub(super) fn op_push(&mut self, operands: &InlineOperands) -> OpResult { + self.value_stack.push_inline_operands(operands) + } +} + +#[cfg(test)] +mod tests { + use super::super::MockEngine; + use read_fonts::tables::glyf::bytecode::MockInlineOperands; + + #[test] + fn stack_ops() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let byte_args = MockInlineOperands::from_bytes(&[2, 4, 6, 8]); + let word_args = MockInlineOperands::from_words(&[-2000, 4000, -6000, 8000]); + let initial_stack = byte_args + .operands() + .values() + .chain(word_args.operands().values()) + .collect::>(); + // Push instructions + engine.op_push(&byte_args.operands()).unwrap(); + engine.op_push(&word_args.operands()).unwrap(); + assert_eq!(engine.value_stack.values(), initial_stack); + // DEPTH[] + engine.op_depth().unwrap(); + assert_eq!( + engine.value_stack.pop().ok(), + Some(initial_stack.len() as i32) + ); + // POP[] + engine.op_pop().unwrap(); + engine.op_pop().unwrap(); + assert_eq!( + engine.value_stack.values(), + &initial_stack[..initial_stack.len() - 2] + ); + // SWAP[] + engine.op_swap().unwrap(); + assert_eq!(&engine.value_stack.values()[4..], &[4000, -2000]); + // ROLL[] + engine.op_roll().unwrap(); + assert_eq!(&engine.value_stack.values()[3..], &[4000, -2000, 8]); + // CINDEX[] + engine.value_stack.push(4).unwrap(); + engine.op_cindex().unwrap(); + assert_eq!(engine.value_stack.peek(), Some(6)); + // MINDEX[] + engine.value_stack.push(3).unwrap(); + engine.op_mindex().unwrap(); + assert_eq!(engine.value_stack.peek(), Some(-2000)); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,110 @@ +//! Managing the storage area. +//! +//! Implements 2 instructions. +//! +//! See + +use super::{Engine, OpResult}; + +impl Engine<'_> { + /// Read store. + /// + /// RS[] (0x43) + /// + /// Pops: location: Storage Area location + /// Pushes: value: Storage Area value + /// + /// This instruction reads a 32 bit value from the Storage Area location + /// popped from the stack and pushes the value read onto the stack. It pops + /// an address from the stack and pushes the value found in that Storage + /// Area location to the top of the stack. The number of available storage + /// locations is specified in the maxProfile table in the font file. + /// + /// See + /// and + pub(super) fn op_rs(&mut self) -> OpResult { + let location = self.value_stack.pop_usize()?; + let maybe_value = self.storage.get(location); + let value = if self.graphics.is_pedantic { + maybe_value? + } else { + maybe_value.unwrap_or(0) + }; + self.value_stack.push(value) + } + + /// Write store. + /// + /// WS[] (0x42) + /// + /// Pops: value: Storage Area value, + /// location: Storage Area location + /// + /// This instruction writes a 32 bit value into the storage location + /// indexed by locations. It works by popping a value and then a location + /// from the stack. The value is placed in the Storage Area location + /// specified by that address. The number of storage locations is specified + /// in the maxProfile table in the font file. + /// + /// See + /// and + pub(super) fn op_ws(&mut self) -> OpResult { + let value = self.value_stack.pop()?; + let location = self.value_stack.pop_usize()?; + let result = self.storage.set(location, value); + if self.graphics.is_pedantic { + result + } else { + Ok(()) + } + } +} + +#[cfg(test)] +mod tests { + use super::super::{HintErrorKind, MockEngine}; + + #[test] + fn write_read() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.value_stack.push(i * 2).unwrap(); + engine.op_ws().unwrap(); + } + for i in 0..8 { + engine.value_stack.push(i).unwrap(); + engine.op_rs().unwrap(); + assert_eq!(engine.value_stack.pop().unwrap(), i * 2); + } + } + + #[test] + fn pedantry() { + let mut mock = MockEngine::new(); + let mut engine = mock.engine(); + let oob_index = 1000; + // Disable pedantic mode: OOB writes are ignored, OOB reads + // push 0 + engine.graphics.is_pedantic = false; + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + engine.op_ws().unwrap(); + engine.value_stack.push(oob_index).unwrap(); + engine.op_rs().unwrap(); + // Enable pedantic mode: OOB reads/writes error + engine.graphics.is_pedantic = true; + engine.value_stack.push(oob_index).unwrap(); + engine.value_stack.push(0).unwrap(); + assert_eq!( + engine.op_ws(), + Err(HintErrorKind::InvalidStorageIndex(oob_index as _)) + ); + engine.value_stack.push(oob_index).unwrap(); + assert_eq!( + engine.op_rs(), + Err(HintErrorKind::InvalidStorageIndex(oob_index as _)) + ); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,120 @@ +//! Hinting error definitions. + +use read_fonts::tables::glyf::bytecode::{DecodeError, Opcode}; + +use super::program::Program; +use crate::GlyphId; + +/// Errors that may occur when interpreting TrueType bytecode. +#[derive(Clone, PartialEq, Debug)] +pub enum HintErrorKind { + UnexpectedEndOfBytecode, + UnhandledOpcode(Opcode), + DefinitionInGlyphProgram, + NestedDefinition, + DefinitionTooLarge, + TooManyDefinitions, + InvalidDefinition(usize), + ValueStackOverflow, + ValueStackUnderflow, + CallStackOverflow, + CallStackUnderflow, + InvalidStackValue(i32), + InvalidPointIndex(usize), + InvalidPointRange(usize, usize), + InvalidContourIndex(usize), + InvalidCvtIndex(usize), + InvalidStorageIndex(usize), + DivideByZero, + InvalidZoneIndex(i32), + NegativeLoopCounter, + InvalidJump, + ExceededExecutionBudget, +} + +impl core::fmt::Display for HintErrorKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::UnexpectedEndOfBytecode => write!(f, "unexpected end of bytecode"), + Self::UnhandledOpcode(opcode) => write!(f, "unhandled instruction opcode {opcode}"), + Self::DefinitionInGlyphProgram => { + write!( + f, + "function or instruction definition present in glyph program" + ) + } + Self::NestedDefinition => write!(f, "nested function or instruction definition"), + Self::DefinitionTooLarge => write!( + f, + "function or instruction definition exceeded the maximum size of 64k" + ), + Self::TooManyDefinitions => write!(f, "too many function or instruction definitions"), + Self::InvalidDefinition(key) => { + write!(f, "function or instruction definition {key} not found") + } + Self::ValueStackOverflow => write!(f, "value stack overflow"), + Self::ValueStackUnderflow => write!(f, "value stack underflow"), + Self::CallStackOverflow => write!(f, "call stack overflow"), + Self::CallStackUnderflow => write!(f, "call stack underflow"), + Self::InvalidStackValue(value) => write!( + f, + "stack value {value} was invalid for the current operation" + ), + Self::InvalidPointIndex(index) => write!(f, "point index {index} was out of bounds"), + Self::InvalidPointRange(start, end) => { + write!(f, "point range {start}..{end} was out of bounds") + } + Self::InvalidContourIndex(index) => { + write!(f, "contour index {index} was out of bounds") + } + Self::InvalidCvtIndex(index) => write!(f, "cvt index {index} was out of bounds"), + Self::InvalidStorageIndex(index) => { + write!(f, "storage area index {index} was out of bounds") + } + Self::DivideByZero => write!(f, "attempt to divide by 0"), + Self::InvalidZoneIndex(index) => write!( + f, + "zone index {index} was invalid (only 0 or 1 are permitted)" + ), + Self::NegativeLoopCounter => { + write!(f, "attempt to set the loop counter to a negative value") + } + Self::InvalidJump => write!(f, "the target of a jump instruction was invalid"), + Self::ExceededExecutionBudget => write!(f, "too many instructions executed"), + } + } +} + +impl From for HintErrorKind { + fn from(_: DecodeError) -> Self { + Self::UnexpectedEndOfBytecode + } +} + +/// Hinting error with additional context. +#[derive(Clone, Debug)] +pub struct HintError { + pub program: Program, + pub glyph_id: Option, + pub pc: usize, + pub opcode: Option, + pub kind: HintErrorKind, +} + +impl core::fmt::Display for HintError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.program { + Program::ControlValue => write!(f, "prep")?, + Program::Font => write!(f, "fpgm")?, + Program::Glyph => write!(f, "glyf")?, + } + if let Some(glyph_id) = self.glyph_id { + write!(f, "[{}]", glyph_id.to_u32())?; + } + let (opcode, colon) = match self.opcode { + Some(opcode) => (opcode.name(), ":"), + _ => ("", ""), + }; + write!(f, "@{}:{opcode}{colon} {}", self.pc, self.kind) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,316 @@ +//! Graphics state for the TrueType interpreter. + +use super::{ + round::RoundState, + zone::{Zone, ZonePointer}, + F26Dot6, Point, Target, +}; +use core::ops::{Deref, DerefMut}; + +/// Describes the axis to which a measurement or point movement operation +/// applies. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub enum CoordAxis { + #[default] + Both, + X, + Y, +} + +/// Context in which instructions are executed. +/// +/// See +#[derive(Debug)] +pub struct GraphicsState<'a> { + /// Fields of the graphics state that persist between calls to the interpreter. + pub retained: RetainedGraphicsState, + /// A unit vector whose direction establishes an axis along which + /// distances are measured. + /// + /// See + pub proj_vector: Point, + /// Current axis for the projection vector. + pub proj_axis: CoordAxis, + /// A second projection vector set to a line defined by the original + /// outline location of two points. The dual projection vector is used + /// when it is necessary to measure distances from the scaled outline + /// before any instructions were executed. + /// + /// See + pub dual_proj_vector: Point, + /// Current axis for the dual projection vector. + pub dual_proj_axis: CoordAxis, + /// A unit vector that establishes an axis along which points can move. + /// + /// See + pub freedom_vector: Point, + /// Current axis for point movement. + pub freedom_axis: CoordAxis, + /// Dot product of freedom and projection vectors. + pub fdotp: i32, + /// Determines the manner in which values are rounded. + /// + /// See + pub round_state: RoundState, + /// First reference point. + /// + /// See + pub rp0: usize, + /// Second reference point. + /// + /// See + pub rp1: usize, + /// Third reference point. + /// + /// See + pub rp2: usize, + /// Makes it possible to repeat certain instructions a designated number of + /// times. The default value of one assures that unless the value of loop + /// is altered, these instructions will execute one time. + /// + /// See + pub loop_counter: u32, + /// First zone pointer. + /// + /// See + pub zp0: ZonePointer, + /// Second zone pointer. + /// + /// See + pub zp1: ZonePointer, + /// Third zone pointer. + /// + /// See + pub zp2: ZonePointer, + /// Outline data for each zone. + /// + /// This array contains the twilight and glyph zones, in that order. + pub zones: [Zone<'a>; 2], + /// True if the current glyph is a composite. + pub is_composite: bool, + /// If true, enables a set of backward compatibility heuristics that + /// prevent certain modifications to the outline. The purpose is to + /// support "modern" vertical only hinting that attempts to preserve + /// outline shape and metrics in the horizontal direction. This is + /// enabled by default, but fonts (and specific glyphs) can opt out + /// of this behavior using the INSTCTRL instruction. In practice, + /// opting out is usually only done by "ClearType native" fonts. + /// + /// See + /// for more background and some gory details. + /// + /// Defaults to true. + /// + /// See + pub backward_compatibility: bool, + /// If true, enables more strict error checking. + /// + /// Defaults to false. + /// + /// See + pub is_pedantic: bool, + /// Set to true when IUP has been executed in the horizontal direction. + pub did_iup_x: bool, + /// Set to true when IUP has been executed in the vertical direction. + pub did_iup_y: bool, +} + +impl GraphicsState<'_> { + /// Returns the factor for scaling unscaled points to pixels. + /// + /// For composite glyphs, "unscaled" points are already scaled so we + /// return the identity. + pub fn unscaled_to_pixels(&self) -> i32 { + if self.is_composite { + 1 << 16 + } else { + self.scale + } + } + + /// Resets the non-retained portions of the graphics state. + pub fn reset(&mut self) { + let GraphicsState { + retained, + zones, + is_composite, + .. + } = core::mem::take(self); + *self = GraphicsState { + retained, + zones, + is_composite, + ..Default::default() + }; + self.update_projection_state(); + } + + /// Resets the retained portion of the graphics state to default + /// values while saving the user instance settings. + pub fn reset_retained(&mut self) { + let scale = self.scale; + let ppem = self.ppem; + let mode = self.target; + self.retained = RetainedGraphicsState { + scale, + ppem, + target: mode, + ..Default::default() + } + } +} + +impl Default for GraphicsState<'_> { + fn default() -> Self { + // For table of default values, see + // All vectors are set to the x-axis (normalized in 2.14) + let vector = Point::new(0x4000, 0); + Self { + retained: RetainedGraphicsState::default(), + proj_vector: vector, + proj_axis: CoordAxis::Both, + dual_proj_vector: vector, + dual_proj_axis: CoordAxis::Both, + freedom_vector: vector, + freedom_axis: CoordAxis::Both, + fdotp: 0x4000, + round_state: RoundState::default(), + rp0: 0, + rp1: 0, + rp2: 0, + loop_counter: 1, + zp0: ZonePointer::default(), + zp1: ZonePointer::default(), + zp2: ZonePointer::default(), + zones: [Zone::default(), Zone::default()], + is_composite: false, + backward_compatibility: true, + is_pedantic: false, + did_iup_x: false, + did_iup_y: false, + } + } +} + +/// The persistent graphics state. +/// +/// Some of the graphics state is set by the control value program and +/// persists between runs of the interpreter. This struct captures that +/// state. +/// +/// See +#[derive(Copy, Clone, Debug)] +pub struct RetainedGraphicsState { + /// Controls whether the sign of control value table entries will be + /// changed to match the sign of the actual distance measurement with + /// which it is compared. + /// + /// See + pub auto_flip: bool, + /// Limits the regularizing effects of control value table entries to + /// cases where the difference between the table value and the measurement + /// taken from the original outline is sufficiently small. + /// + /// See + pub control_value_cutin: F26Dot6, + /// Establishes the base value used to calculate the range of point sizes + /// to which a given DELTAC[] or DELTAP[] instruction will apply. + /// + /// See + pub delta_base: u16, + /// Determines the range of movement and smallest magnitude of movement + /// (the step) in a DELTAC[] or DELTAP[] instruction. + /// + /// See + pub delta_shift: u16, + /// Makes it possible to turn off instructions under some circumstances. + /// When set to TRUE, no instructions will be executed + /// + /// See + pub instruct_control: u8, + /// Establishes the smallest possible value to which a distance will be + /// rounded. + /// + /// See + pub min_distance: F26Dot6, + /// Determines whether the interpreter will activate dropout control for + /// the current glyph. + /// + /// See + pub scan_control: bool, + /// Type associated with `scan_control`. + pub scan_type: i32, + /// The distance difference below which the interpreter will replace a + /// CVT distance or an actual distance in favor of the single width value. + /// + /// See + pub single_width_cutin: F26Dot6, + /// The value used in place of the control value table distance or the + /// actual distance value when the difference between that distance and + /// the single width value is less than the single width cut-in. + /// + /// See + pub single_width: F26Dot6, + /// The user requested hinting target. + pub target: Target, + /// The scale factor for the current instance. Conversion from font units + /// to 26.6 for current ppem. + pub scale: i32, + /// The nominal pixels per em value for the current instance. + pub ppem: i32, + /// True if a rotation is being applied. + pub is_rotated: bool, + /// True if a non-uniform scale is being applied. + pub is_stretched: bool, +} + +impl RetainedGraphicsState { + pub fn new(scale: i32, ppem: i32, target: Target) -> Self { + Self { + scale, + ppem, + target, + ..Default::default() + } + } +} + +impl Default for RetainedGraphicsState { + fn default() -> Self { + // For table of default values, see + Self { + auto_flip: true, + // 17/16 pixels in 26.6 + // (17 * 64 / 16) = 68 + control_value_cutin: F26Dot6::from_bits(68), + delta_base: 9, + delta_shift: 3, + instruct_control: 0, + // 1 pixel in 26.6 + min_distance: F26Dot6::from_bits(64), + scan_control: false, + scan_type: 0, + single_width_cutin: F26Dot6::ZERO, + single_width: F26Dot6::ZERO, + target: Default::default(), + scale: 0, + ppem: 0, + is_rotated: false, + is_stretched: false, + } + } +} + +impl Deref for GraphicsState<'_> { + type Target = RetainedGraphicsState; + + fn deref(&self) -> &Self::Target { + &self.retained + } +} + +impl DerefMut for GraphicsState<'_> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.retained + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,275 @@ +//! Instance state for TrueType hinting. + +use super::{ + super::Outlines, + cow_slice::CowSlice, + definition::{Definition, DefinitionMap, DefinitionState}, + engine::Engine, + error::HintError, + graphics::RetainedGraphicsState, + program::{Program, ProgramState}, + value_stack::ValueStack, + zone::Zone, + HintOutline, PointFlags, Target, +}; +use alloc::vec::Vec; +use raw::{ + types::{F26Dot6, F2Dot14, Fixed, Point}, + TableProvider, +}; + +#[derive(Clone, Default)] +pub struct HintInstance { + functions: Vec, + instructions: Vec, + cvt: Vec, + storage: Vec, + graphics: RetainedGraphicsState, + twilight_scaled: Vec>, + twilight_original_scaled: Vec>, + twilight_flags: Vec, + axis_count: u16, + max_stack: usize, +} + +impl HintInstance { + pub fn reconfigure( + &mut self, + outlines: &Outlines, + scale: i32, + ppem: i32, + target: Target, + coords: &[F2Dot14], + ) -> Result<(), HintError> { + self.setup(outlines, scale, coords); + let twilight_contours = [self.twilight_scaled.len() as u16]; + let twilight = Zone::new( + &[], + &mut self.twilight_original_scaled, + &mut self.twilight_scaled, + &mut self.twilight_flags, + &twilight_contours, + ); + let glyph = Zone::default(); + let mut stack_buf = vec![0; self.max_stack]; + let value_stack = ValueStack::new(&mut stack_buf, false); + let graphics = RetainedGraphicsState::new(scale, ppem, target); + let mut engine = Engine::new( + outlines, + ProgramState::new(outlines.fpgm, outlines.prep, &[], Program::Font), + graphics, + DefinitionState::new( + DefinitionMap::Mut(&mut self.functions), + DefinitionMap::Mut(&mut self.instructions), + ), + CowSlice::new_mut(&mut self.cvt), + CowSlice::new_mut(&mut self.storage), + value_stack, + twilight, + glyph, + self.axis_count, + coords, + false, + ); + // Run the font program (fpgm) + engine.run_program(Program::Font, false)?; + // Run the control value program (prep) + engine.run_program(Program::ControlValue, false)?; + // Save the retained state from the CV program + self.graphics = *engine.retained_graphics_state(); + Ok(()) + } + + /// Returns true if we should actually apply hinting. + /// + /// Hinting can be completely disabled by the control value program. + pub fn is_enabled(&self) -> bool { + // If bit 0 is set, disables hinting entirely + self.graphics.instruct_control & 1 == 0 + } + + /// Returns true if backward compatibility mode has been activated + /// by the hinter settings or the `prep` table. + pub fn backward_compatibility(&self) -> bool { + // Set backward compatibility mode + if self.graphics.target.preserve_linear_metrics() { + true + } else if self.graphics.target.is_smooth() { + (self.graphics.instruct_control & 0x4) == 0 + } else { + false + } + } + + pub fn hint( + &self, + outlines: &Outlines, + outline: &mut HintOutline, + is_pedantic: bool, + ) -> Result<(), HintError> { + // Twilight zone + let twilight_count = outline.twilight_scaled.len(); + let twilight_contours = [twilight_count as u16]; + outline + .twilight_original_scaled + .copy_from_slice(&self.twilight_original_scaled); + outline + .twilight_scaled + .copy_from_slice(&self.twilight_scaled); + outline.twilight_flags.copy_from_slice(&self.twilight_flags); + let twilight = Zone::new( + &[], + outline.twilight_original_scaled, + outline.twilight_scaled, + outline.twilight_flags, + &twilight_contours, + ); + // Glyph zone + let glyph = Zone::new( + outline.unscaled, + outline.original_scaled, + outline.scaled, + outline.flags, + outline.contours, + ); + let value_stack = ValueStack::new(outline.stack, is_pedantic); + let cvt = CowSlice::new(&self.cvt, outline.cvt).unwrap(); + let storage = CowSlice::new(&self.storage, outline.storage).unwrap(); + let mut engine = Engine::new( + outlines, + ProgramState::new( + outlines.fpgm, + outlines.prep, + outline.bytecode, + Program::Glyph, + ), + self.graphics, + DefinitionState::new( + DefinitionMap::Ref(&self.functions), + DefinitionMap::Ref(&self.instructions), + ), + cvt, + storage, + value_stack, + twilight, + glyph, + self.axis_count, + outline.coords, + outline.is_composite, + ); + engine + .run_program(Program::Glyph, is_pedantic) + .map_err(|mut e| { + e.glyph_id = Some(outline.glyph_id); + e + })?; + // If we're not running in backward compatibility mode, capture + // modified phantom points. + if !engine.backward_compatibility() { + for (i, p) in (outline.scaled[outline.scaled.len() - 4..]) + .iter() + .enumerate() + { + outline.phantom[i] = *p; + } + } + Ok(()) + } + + /// Captures limits, resizes buffers and scales the CVT. + fn setup(&mut self, outlines: &Outlines, scale: i32, coords: &[F2Dot14]) { + let axis_count = outlines + .gvar + .as_ref() + .map(|gvar| gvar.axis_count()) + .unwrap_or_default(); + self.functions.clear(); + self.functions + .resize(outlines.max_function_defs as usize, Definition::default()); + self.instructions.resize( + outlines.max_instruction_defs as usize, + Definition::default(), + ); + self.cvt.clear(); + let cvt = outlines.font.cvt().unwrap_or_default(); + if let Ok(cvar) = outlines.font.cvar() { + // First accumulate all the deltas in 16.16 + self.cvt.resize(cvt.len(), 0); + let _ = cvar.deltas(axis_count, coords, &mut self.cvt); + // Now add the base CVT values + for (value, base_value) in self.cvt.iter_mut().zip(cvt.iter()) { + // Deltas are converted from 16.16 to 26.6 + // See + let delta = Fixed::from_bits(*value).to_f26dot6().to_bits(); + let base_value = base_value.get() as i32 * 64; + *value = base_value + delta; + } + } else { + // CVT values are converted to 26.6 on load + // See + self.cvt + .extend(cvt.iter().map(|value| (value.get() as i32) * 64)); + } + // More weird scaling. This is due to the fact that CVT values are + // already in 26.6 + // See + let scale = Fixed::from_bits(scale >> 6); + for value in &mut self.cvt { + *value = (Fixed::from_bits(*value) * scale).to_bits(); + } + self.storage.clear(); + self.storage.resize(outlines.max_storage as usize, 0); + let max_twilight_points = outlines.max_twilight_points as usize; + self.twilight_scaled.clear(); + self.twilight_scaled + .resize(max_twilight_points, Default::default()); + self.twilight_original_scaled.clear(); + self.twilight_original_scaled + .resize(max_twilight_points, Default::default()); + self.twilight_flags.clear(); + self.twilight_flags + .resize(max_twilight_points, Default::default()); + self.axis_count = axis_count; + self.max_stack = outlines.max_stack_elements as usize; + self.graphics = RetainedGraphicsState::default(); + } +} + +#[cfg(test)] +impl HintInstance { + /// Enable instruct control bit 1 which effectively disables hinting. + /// + /// This mimics what the `prep` table might do for various configurations + /// and font sizes. Used for testing. + pub fn simulate_prep_flag_suppress_hinting(&mut self) { + self.graphics.instruct_control |= 1; + } +} + +#[cfg(test)] +mod tests { + use super::{super::super::Outlines, HintInstance}; + use read_fonts::{types::F2Dot14, FontRef}; + + #[test] + fn scaled_cvar_cvt() { + let font = FontRef::new(font_test_data::CVAR).unwrap(); + let outlines = Outlines::new(&font).unwrap(); + let mut instance = HintInstance::default(); + let coords = [0.5, -0.5].map(F2Dot14::from_f32); + let ppem = 16; + // ppem * 64 / upem + let scale = 67109; + instance + .reconfigure(&outlines, scale, ppem, Default::default(), &coords) + .unwrap(); + let expected = [ + 778, 10, 731, 0, 731, 10, 549, 10, 0, 0, 0, -10, 0, -10, -256, -10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 137, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 60, 0, 81, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + assert_eq!(&instance.cvt, &expected); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,324 @@ +//! Fixed point math helpers that are specific to TrueType hinting. +//! +//! These are implemented in terms of font-types types when possible. It +//! likely makes sense to use more strongly typed fixed point values +//! in the future. + +use read_fonts::types::{Fixed, Point}; + +pub fn floor(x: i32) -> i32 { + x & !63 +} + +pub fn round(x: i32) -> i32 { + floor(x + 32) +} + +pub fn ceil(x: i32) -> i32 { + floor(x + 63) +} + +fn floor_pad(x: i32, n: i32) -> i32 { + x & !(n - 1) +} + +pub fn round_pad(x: i32, n: i32) -> i32 { + floor_pad(x + n / 2, n) +} + +#[inline(always)] +pub fn mul(a: i32, b: i32) -> i32 { + (Fixed::from_bits(a) * Fixed::from_bits(b)).to_bits() +} + +pub fn div(a: i32, b: i32) -> i32 { + (Fixed::from_bits(a) / Fixed::from_bits(b)).to_bits() +} + +/// Fixed point multiply and divide: a * b / c +pub fn mul_div(a: i32, b: i32, c: i32) -> i32 { + Fixed::from_bits(a) + .mul_div(Fixed::from_bits(b), Fixed::from_bits(c)) + .to_bits() +} + +/// Fixed point multiply and divide without rounding: a * b / c +/// +/// Based on +pub fn mul_div_no_round(mut a: i32, mut b: i32, mut c: i32) -> i32 { + let mut s = 1; + if a < 0 { + a = -a; + s = -1; + } + if b < 0 { + b = -b; + s = -s; + } + if c < 0 { + c = -c; + s = -s; + } + let d = if c > 0 { + ((a as i64) * (b as i64)) / c as i64 + } else { + 0x7FFFFFFF + }; + if s < 0 { + -(d as i32) + } else { + d as i32 + } +} + +/// Multiplication for 2.14 fixed point. +/// +/// Based on +pub fn mul14(a: i32, b: i32) -> i32 { + let mut v = a as i64 * b as i64; + v += 0x2000 + (v >> 63); + (v >> 14) as i32 +} + +/// Normalize a vector in 2.14 fixed point. +/// +/// Direct port of +pub fn normalize14(x: i32, y: i32) -> Point { + use core::num::Wrapping; + let (mut sx, mut sy) = (Wrapping(1i32), Wrapping(1i32)); + let mut ux = Wrapping(x as u32); + let mut uy = Wrapping(y as u32); + const ZERO: Wrapping = Wrapping(0); + let mut result = Point::default(); + if x < 0 { + ux = ZERO - ux; + sx = -sx; + } + if y < 0 { + uy = ZERO - uy; + sy = -sy; + } + if ux == ZERO { + result.x = x / 4; + if uy.0 > 0 { + result.y = (sy * Wrapping(0x10000) / Wrapping(4)).0; + } + return result; + } + if uy == ZERO { + result.y = y / 4; + if ux.0 > 0 { + result.x = (sx * Wrapping(0x10000) / Wrapping(4)).0; + } + return result; + } + let mut len = if ux > uy { + ux + (uy >> 1) + } else { + uy + (ux >> 1) + }; + let mut shift = Wrapping(len.0.leading_zeros() as i32); + shift -= Wrapping(15) + + if len >= (Wrapping(0xAAAAAAAAu32) >> shift.0 as usize) { + Wrapping(1) + } else { + Wrapping(0) + }; + if shift.0 > 0 { + let s = shift.0 as usize; + ux <<= s; + uy <<= s; + len = if ux > uy { + ux + (uy >> 1) + } else { + uy + (ux >> 1) + }; + } else { + let s = -shift.0 as usize; + ux >>= s; + uy >>= s; + len >>= s; + } + let mut b = Wrapping(0x10000) - Wrapping(len.0 as i32); + let x = Wrapping(ux.0 as i32); + let y = Wrapping(uy.0 as i32); + let mut z; + let mut u; + let mut v; + loop { + u = Wrapping((x + ((x * b) >> 16)).0 as u32); + v = Wrapping((y + ((y * b) >> 16)).0 as u32); + z = Wrapping(-((u * u + v * v).0 as i32)) / Wrapping(0x200); + z = z * ((Wrapping(0x10000) + b) >> 8) / Wrapping(0x10000); + b += z; + if z <= Wrapping(0) { + break; + } + } + Point::new( + (Wrapping(u.0 as i32) * sx / Wrapping(4)).0, + (Wrapping(v.0 as i32) * sy / Wrapping(4)).0, + ) +} + +#[cfg(test)] +mod tests { + use raw::types::{F2Dot14, Fixed}; + + /// Tolerance value for floating point sanity checks. + /// Tests with large sets of values show this is the best we can + /// expect from the fixed point implementations. + const FLOAT_TOLERANCE: f32 = 1e-4; + + #[test] + fn mul_div_no_round() { + let cases = [ + // computed with FT_MulDiv_NoRound(): + // ((a, b, c), result) where result = a * b / c + ((-326, -11474, 9942), 376), + ((-6781, 13948, 11973), -7899), + ((3517, 15622, 8075), 6804), + ((-6127, 15026, 2276), -40450), + ((11257, 14828, 2542), 65664), + ((-12797, -16280, -9086), -22929), + ((-7994, -3340, 9583), 2786), + ((-16101, -13780, -1427), -155481), + ((10304, -16331, 15480), -10870), + ((-15879, 11912, -4650), 40677), + ((-5015, 6382, -15977), 2003), + ((2080, -11930, -15457), 1605), + ((-11071, 13350, 16138), -9158), + ((16084, -13564, -770), 283329), + ((14304, -10377, -21), 7068219), + ((-14056, -8853, -5488), -22674), + ((-10319, 14797, 8554), -17850), + ((-7820, 6826, 10555), -5057), + ((7257, 15928, 8159), 14167), + ((14929, 11579, -13204), -13091), + ((2808, 12070, -14697), -2306), + ((-13818, 8544, -1649), 71595), + ((3265, 7325, -1373), -17418), + ((14832, 10586, -6440), -24380), + ((4123, 8274, -2022), -16871), + ((4645, -4149, -7242), 2661), + ((-3891, 8366, 5771), -5640), + ((-15447, -3428, -9335), -5672), + ((13670, -14311, -11122), 17589), + ((12590, -6592, 13159), -6306), + ((-8369, -10193, 5051), 16888), + ((-9539, 5167, 2595), -18993), + ]; + for ((a, b, c), expected_result) in cases { + let result = super::mul_div_no_round(a, b, c); + assert_eq!(result, expected_result); + let fa = Fixed::from_bits(a as _).to_f32(); + let fb = Fixed::from_bits(b as _).to_f32(); + let fc = Fixed::from_bits(c as _).to_f32(); + let fresult = fa * fb / fc; + let fexpected_result = Fixed::from_bits(expected_result as _).to_f32(); + assert!((fresult - fexpected_result).abs() < FLOAT_TOLERANCE); + } + } + + #[test] + fn mul14() { + let cases = [ + // computed with TT_MulFix14(): + // ((a, b), result) where result = a * b + ((6236, -10078), -3836), + ((-6803, -5405), 2244), + ((-10006, -12852), 7849), + ((-15434, -4102), 3864), + ((-8681, 9269), -4911), + ((9449, -9130), -5265), + ((12643, 2161), 1668), + ((-6115, 9284), -3465), + ((316, 3390), 65), + ((15077, -12901), -11872), + ((-12182, 11613), -8635), + ((-7213, 8246), -3630), + ((13482, 8096), 6662), + ((5690, 15016), 5215), + ((-5991, 12613), -4612), + ((13112, -8404), -6726), + ((13524, 6786), 5601), + ((7156, 3291), 1437), + ((-2978, 353), -64), + ((-1755, 14626), -1567), + ((14402, 7886), 6932), + ((7124, 15730), 6840), + ((-12679, 14830), -11476), + ((-9374, -12999), 7437), + ((12301, -4685), -3517), + ((5324, 2066), 671), + ((6783, -4946), -2048), + ((12078, -968), -714), + ((-10137, 14116), -8734), + ((-13946, 11585), -9861), + ((-678, -2205), 91), + ((-2629, -3319), 533), + ]; + for ((a, b), expected_result) in cases { + let result = super::mul14(a, b); + assert_eq!(result, expected_result); + let fa = F2Dot14::from_bits(a as _).to_f32(); + let fb = F2Dot14::from_bits(b as _).to_f32(); + let fresult = fa * fb; + let fexpected_result = F2Dot14::from_bits(expected_result as _).to_f32(); + assert!((fresult - fexpected_result).abs() < FLOAT_TOLERANCE); + } + } + + #[test] + fn normalize14() { + let cases = [ + // computed with FT_Vector_NormLen(): + // (input vector, expected normalized vector) + ((-13660, 11807), (-12395, 10713)), + ((-10763, 9293), (-12401, 10707)), + ((-3673, 673), (-16115, 2952)), + ((15886, -2964), (16106, -3005)), + ((15442, -2871), (16108, -2994)), + ((-6308, 5744), (-12114, 11031)), + ((9410, -10415), (10983, -12156)), + ((-10620, -14856), (-9528, -13328)), + ((-9372, 12029), (-10069, 12924)), + ((-1272, -1261), (-11635, -11534)), + ((-7076, -5517), (-12920, -10074)), + ((-10297, 179), (-16381, 284)), + ((9256, -13235), (9389, -13426)), + ((5315, -12449), (6433, -15068)), + ((8064, 15213), (7673, 14476)), + ((-8665, 41), (-16383, 77)), + ((-3455, -4720), (-9677, -13220)), + ((13449, -5152), (15299, -5861)), + ((-15605, 8230), (-14492, 7643)), + ((4716, -13690), (5336, -15490)), + ((12904, -11422), (12268, -10859)), + ((2825, -6396), (6619, -14987)), + ((4654, 15245), (4783, 15670)), + ((-14769, 15133), (-11443, 11725)), + ((-8090, -9057), (-10914, -12219)), + ((-472, 1953), (-3848, 15925)), + ((-12563, 1040), (-16328, 1351)), + ((-7938, 15587), (-7435, 14599)), + ((-9701, 5356), (-14343, 7919)), + ((-642, -14484), (-725, -16367)), + ((12963, -9690), (13123, -9809)), + ((7067, 5361), (13053, 9902)), + ((0x4000, 0), (0x4000, 0)), + ((0, 0x4000), (0, 0x4000)), + ((-0x4000, 0), (-0x4000, 0)), + ((0, -0x4000), (0, -0x4000)), + ]; + for ((x, y), expected) in cases { + let n = super::normalize14(x, y); + assert_eq!((n.x, n.y), expected); + // Ensure the length of the vector is nearly 1.0 + let fx = F2Dot14::from_bits(n.x as _).to_f32(); + let fy = F2Dot14::from_bits(n.y as _).to_f32(); + let flen = (fx * fx + fy * fy).sqrt(); + assert!((flen - 1.0).abs() <= FLOAT_TOLERANCE); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,47 @@ +//! TrueType hinting. + +mod call_stack; +mod cow_slice; +mod cvt; +mod definition; +mod engine; +mod error; +mod graphics; +mod instance; +mod math; +mod program; +mod projection; +mod round; +mod storage; +mod value_stack; +mod zone; + +use super::super::Target; + +use read_fonts::{ + tables::glyf::PointFlags, + types::{F26Dot6, F2Dot14, GlyphId, Point}, +}; + +pub use error::HintError; +pub use instance::HintInstance; + +/// Outline data that is passed to the hinter. +pub struct HintOutline<'a> { + pub glyph_id: GlyphId, + pub unscaled: &'a [Point], + pub scaled: &'a mut [Point], + pub original_scaled: &'a mut [Point], + pub flags: &'a mut [PointFlags], + pub contours: &'a [u16], + pub phantom: &'a mut [Point], + pub bytecode: &'a [u8], + pub stack: &'a mut [i32], + pub cvt: &'a mut [i32], + pub storage: &'a mut [i32], + pub twilight_scaled: &'a mut [Point], + pub twilight_original_scaled: &'a mut [Point], + pub twilight_flags: &'a mut [PointFlags], + pub is_composite: bool, + pub coords: &'a [F2Dot14], +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,163 @@ +//! TrueType program management. + +use raw::tables::glyf::bytecode::Decoder; + +use super::{ + call_stack::{CallRecord, CallStack}, + definition::Definition, + error::HintErrorKind, +}; + +/// Describes the source for a piece of bytecode. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +#[repr(u8)] +pub enum Program { + /// Program that initializes the function and instruction tables. Stored + /// in the `fpgm` table. + #[default] + Font = 0, + /// Program that initializes CVT and storage based on font size and other + /// parameters. Stored in the `prep` table. + ControlValue = 1, + /// Glyph specified program. Stored per-glyph in the `glyf` table. + Glyph = 2, +} + +/// State for managing active programs and decoding instructions. +pub struct ProgramState<'a> { + /// Bytecode for each of the three program types, indexed by `Program`. + pub bytecode: [&'a [u8]; 3], + /// The initial program when execution begins. + pub initial: Program, + /// The currently active program. + pub current: Program, + /// Instruction decoder for the currently active program. + pub decoder: Decoder<'a>, + /// Tracks nested function and instruction invocations. + pub call_stack: CallStack, +} + +impl<'a> ProgramState<'a> { + pub fn new( + font_code: &'a [u8], + cv_code: &'a [u8], + glyph_code: &'a [u8], + initial_program: Program, + ) -> Self { + let bytecode = [font_code, cv_code, glyph_code]; + Self { + bytecode, + initial: initial_program, + current: initial_program, + decoder: Decoder::new(bytecode[initial_program as usize], 0), + call_stack: CallStack::default(), + } + } + + /// Resets the state for execution of the given program. + pub fn reset(&mut self, program: Program) { + self.initial = program; + self.current = program; + self.decoder = Decoder::new(self.bytecode[program as usize], 0); + self.call_stack.clear(); + } + + /// Jumps to the code in the given definition and sets it up for + /// execution `count` times. + pub fn enter(&mut self, definition: Definition, count: u32) -> Result<(), HintErrorKind> { + let program = definition.program(); + let pc = definition.code_range().start; + let bytecode = self.bytecode[program as usize]; + self.call_stack.push(CallRecord { + caller_program: self.current, + return_pc: self.decoder.pc, + current_count: count, + definition, + })?; + self.current = program; + self.decoder = Decoder::new(bytecode, pc); + Ok(()) + } + + /// Leaves the code from the definition on the top of the stack. + /// + /// If the top call record has a loop count greater than 1, restarts + /// execution from the beginning of the definition. Otherwise, resumes + /// execution at the previously active definition. + pub fn leave(&mut self) -> Result<(), HintErrorKind> { + let mut record = self.call_stack.pop()?; + if record.current_count > 1 { + // This is a loop call with some iterations remaining. + record.current_count -= 1; + self.decoder.pc = record.definition.code_range().start; + self.call_stack.push(record)?; + } else { + self.current = record.caller_program; + // Reset the decoder to the calling program and program counter. + self.decoder.bytecode = self.bytecode[record.caller_program as usize]; + self.decoder.pc = record.return_pc; + } + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Test accounting of program, bytecode and program counter through + /// enter/leave cycles. + #[test] + fn accounting() { + let font_code = &[0][..]; + let cv_code = &[1][..]; + let glyph_code = &[2][..]; + let mut state = ProgramState::new(font_code, cv_code, glyph_code, Program::Glyph); + // We start at glyph code + assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); + let font_def = Definition::new(Program::Font, 10..20, 0); + let cv_def = Definition::new(Program::ControlValue, 33..111, 1); + // Now move to CV code + state.enter(cv_def, 1).unwrap(); + assert_eq!(state.active_state(), (Program::ControlValue, cv_code, 33)); + // Bump the program counter to test capture of return_pc + state.decoder.pc += 20; + // And to font code + state.enter(font_def, 1).unwrap(); + assert_eq!(state.active_state(), (Program::Font, font_code, 10)); + // Back to CV code + state.leave().unwrap(); + assert_eq!(state.active_state(), (Program::ControlValue, cv_code, 53)); + // And to the original glyph code + state.leave().unwrap(); + assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); + } + + /// Ensure calls with a count of `n` require `n` leaves before returning + /// to previous frame. Also ensure program counter is reset to start of + /// definition at each leave. + #[test] + fn loop_call() { + let font_code = &[0][..]; + let cv_code = &[1][..]; + let glyph_code = &[2][..]; + let mut state = ProgramState::new(font_code, cv_code, glyph_code, Program::Glyph); + let font_def = Definition::new(Program::Font, 10..20, 0); + // "Execute" font definition 3 times + state.enter(font_def, 3).unwrap(); + for _ in 0..3 { + assert_eq!(state.active_state(), (Program::Font, font_code, 10)); + // Modify program counter to ensure we reset on leave + state.decoder.pc += 22; + state.leave().unwrap(); + } + // Should be back to glyph code + assert_eq!(state.active_state(), (Program::Glyph, glyph_code, 0)); + } + + impl<'a> ProgramState<'a> { + fn active_state(&self) -> (Program, &'a [u8], usize) { + (self.current, self.decoder.bytecode, self.decoder.pc) + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,177 @@ +//! Point projection. + +use super::graphics::{CoordAxis, GraphicsState}; +use raw::types::{F26Dot6, Point}; + +impl GraphicsState<'_> { + /// Updates cached state that is derived from projection vectors. + pub fn update_projection_state(&mut self) { + // 1.0 in 2.14 fixed point. + const ONE: i32 = 0x4000; + // Based on Compute_Funcs() at + // . + // FreeType uses function pointers to select between various "modes" + // but we use the CoordAxis type instead. + if self.freedom_vector.x == ONE { + self.fdotp = self.proj_vector.x; + } else if self.freedom_vector.y == ONE { + self.fdotp = self.proj_vector.y; + } else { + let px = self.proj_vector.x; + let py = self.proj_vector.y; + let fx = self.freedom_vector.x; + let fy = self.freedom_vector.y; + self.fdotp = (px * fx + py * fy) >> 14; + } + self.proj_axis = CoordAxis::Both; + if self.proj_vector.x == ONE { + self.proj_axis = CoordAxis::X; + } else if self.proj_vector.y == ONE { + self.proj_axis = CoordAxis::Y; + } + self.dual_proj_axis = CoordAxis::Both; + if self.dual_proj_vector.x == ONE { + self.dual_proj_axis = CoordAxis::X; + } else if self.dual_proj_vector.y == ONE { + self.dual_proj_axis = CoordAxis::Y; + } + self.freedom_axis = CoordAxis::Both; + if self.fdotp == ONE { + if self.freedom_vector.x == ONE { + self.freedom_axis = CoordAxis::X; + } else if self.freedom_vector.y == ONE { + self.freedom_axis = CoordAxis::Y; + } + } + // At small sizes, fdotp can become too small resulting in overflows + // and spikes. + if self.fdotp.abs() < 0x400 { + self.fdotp = ONE; + } + } + + /// Computes the projection of vector given by (v1 - v2) along the + /// current projection vector. + #[inline(always)] + pub fn project(&self, v1: Point, v2: Point) -> F26Dot6 { + match self.proj_axis { + // + CoordAxis::X => v1.x - v2.x, + // + CoordAxis::Y => v1.y - v2.y, + CoordAxis::Both => { + // + let dx = v1.x - v2.x; + let dy = v1.y - v2.y; + F26Dot6::from_bits(dot14( + dx.to_bits(), + dy.to_bits(), + self.proj_vector.x, + self.proj_vector.y, + )) + } + } + } + + /// Computes the projection of vector given by (v1 - v2) along the + /// current dual projection vector. + #[inline(always)] + pub fn dual_project(&self, v1: Point, v2: Point) -> F26Dot6 { + match self.dual_proj_axis { + // + CoordAxis::X => v1.x - v2.x, + // + CoordAxis::Y => v1.y - v2.y, + CoordAxis::Both => { + // https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L2402 + let dx = v1.x - v2.x; + let dy = v1.y - v2.y; + F26Dot6::from_bits(dot14( + dx.to_bits(), + dy.to_bits(), + self.dual_proj_vector.x, + self.dual_proj_vector.y, + )) + } + } + } + + /// Computes the projection of vector given by (v1 - v2) along the + /// current dual projection vector for unscaled points. + #[inline(always)] + pub fn dual_project_unscaled(&self, v1: Point, v2: Point) -> i32 { + match self.dual_proj_axis { + // + CoordAxis::X => v1.x - v2.x, + // + CoordAxis::Y => v1.y - v2.y, + CoordAxis::Both => { + // https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.c#L2402 + let dx = v1.x - v2.x; + let dy = v1.y - v2.y; + dot14(dx, dy, self.dual_proj_vector.x, self.dual_proj_vector.y) + } + } + } +} + +/// Dot product for vectors in 2.14 fixed point. +fn dot14(ax: i32, ay: i32, bx: i32, by: i32) -> i32 { + let mut v1 = ax as i64 * bx as i64; + let v2 = ay as i64 * by as i64; + v1 += v2; + v1 += 0x2000 + (v1 >> 63); + (v1 >> 14) as i32 +} + +#[cfg(test)] +mod tests { + use super::{super::math, CoordAxis, F26Dot6, GraphicsState, Point}; + + #[test] + fn project_one_axis() { + let mut state = GraphicsState { + proj_vector: math::normalize14(1, 0), + ..Default::default() + }; + state.update_projection_state(); + assert_eq!(state.proj_axis, CoordAxis::X); + assert_eq!(state.proj_vector, Point::new(0x4000, 0)); + let cases = &[ + (Point::new(0, 0), Point::new(0, 0), 0), + (Point::new(100, 100), Point::new(0, 0), 100), + (Point::new(42, 100), Point::new(100, 0), -58), + (Point::new(0, 0), Point::new(100, 100), -100), + ]; + test_project_cases(&state, cases); + } + + #[test] + fn project_both_axes() { + let mut state = GraphicsState { + proj_vector: math::normalize14(0x4000, 0x4000), + ..Default::default() + }; + state.update_projection_state(); + assert_eq!(state.proj_axis, CoordAxis::Both); + let cases = &[ + (Point::new(0, 0), Point::new(0, 0), 0), + (Point::new(100, 100), Point::new(0, 0), 141), + (Point::new(42, 100), Point::new(100, 0), 30), + (Point::new(0, 0), Point::new(100, 100), -141), + ]; + test_project_cases(&state, cases); + } + + fn test_project_cases(state: &GraphicsState, cases: &[(Point, Point, i32)]) { + for (v1, v2, expected) in cases.iter().copied() { + let v1 = v1.map(F26Dot6::from_bits); + let v2 = v2.map(F26Dot6::from_bits); + let result = state.project(v1, v2).to_bits(); + assert_eq!( + result, expected, + "project({v1:?}, {v2:?}) = {result} (expected {expected})" + ); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,240 @@ +//! Rounding state. + +use super::{super::F26Dot6, graphics::GraphicsState}; + +/// Rounding strategies supported by the interpreter. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub enum RoundMode { + /// Distances are rounded to the closest grid line. + /// + /// Set by `RTG` instruction. + #[default] + Grid, + /// Distances are rounded to the nearest half grid line. + /// + /// Set by `RTHG` instruction. + HalfGrid, + /// Distances are rounded to the closest half or integer pixel. + /// + /// Set by `RTDG` instruction. + DoubleGrid, + /// Distances are rounded down to the closest integer grid line. + /// + /// Set by `RDTG` instruction. + DownToGrid, + /// Distances are rounded up to the closest integer pixel boundary. + /// + /// Set by `RUTG` instruction. + UpToGrid, + /// Rounding is turned off. + /// + /// Set by `ROFF` instruction. + Off, + /// Allows fine control over the effects of the round state variable by + /// allowing you to set the values of three components of the round_state: + /// period, phase, and threshold. + /// + /// More formally, maps the domain of 26.6 fixed point numbers into a set + /// of discrete values that are separated by equal distances. + /// + /// Set by `SROUND` instruction. + Super, + /// Analogous to `Super`. The grid period is sqrt(2)/2 pixels rather than 1 + /// pixel. It is useful for measuring at a 45 degree angle with the + /// coordinate axes. + /// + /// Set by `S45ROUND` instruction. + Super45, +} + +/// Graphics state that controls rounding. +/// +/// See +#[derive(Copy, Clone, Debug)] +pub struct RoundState { + pub mode: RoundMode, + pub threshold: i32, + pub phase: i32, + pub period: i32, +} + +impl Default for RoundState { + fn default() -> Self { + Self { + mode: RoundMode::Grid, + threshold: 0, + phase: 0, + period: 64, + } + } +} + +impl RoundState { + pub fn round(&self, distance: F26Dot6) -> F26Dot6 { + use super::math; + use RoundMode::*; + let distance = distance.to_bits(); + let result = match self.mode { + // + HalfGrid => { + if distance >= 0 { + (math::floor(distance) + 32).max(0) + } else { + (-(math::floor(-distance) + 32)).min(0) + } + } + // + Grid => { + if distance >= 0 { + math::round(distance).max(0) + } else { + (-math::round(-distance)).min(0) + } + } + // + DoubleGrid => { + if distance >= 0 { + math::round_pad(distance, 32).max(0) + } else { + (-math::round_pad(-distance, 32)).min(0) + } + } + // + DownToGrid => { + if distance >= 0 { + math::floor(distance).max(0) + } else { + (-math::floor(-distance)).min(0) + } + } + // + UpToGrid => { + if distance >= 0 { + math::ceil(distance).max(0) + } else { + (-math::ceil(-distance)).min(0) + } + } + // + Super => { + if distance >= 0 { + let val = + ((distance + (self.threshold - self.phase)) & -self.period) + self.phase; + if val < 0 { + self.phase + } else { + val + } + } else { + let val = + -(((self.threshold - self.phase) - distance) & -self.period) - self.phase; + if val > 0 { + -self.phase + } else { + val + } + } + } + // + Super45 => { + if distance >= 0 { + let val = (((distance + (self.threshold - self.phase)) / self.period) + * self.period) + + self.phase; + if val < 0 { + self.phase + } else { + val + } + } else { + let val = -((((self.threshold - self.phase) - distance) / self.period) + * self.period) + - self.phase; + if val > 0 { + -self.phase + } else { + val + } + } + } + // + Off => distance, + }; + F26Dot6::from_bits(result) + } +} + +impl GraphicsState<'_> { + pub fn round(&self, distance: F26Dot6) -> F26Dot6 { + self.round_state.round(distance) + } +} + +#[cfg(test)] +mod tests { + use super::{F26Dot6, RoundMode, RoundState}; + + #[test] + fn round_to_grid() { + round_cases( + RoundMode::Grid, + &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], + ); + } + + #[test] + fn round_to_half_grid() { + round_cases( + RoundMode::HalfGrid, + &[(0, 32), (32, 32), (-32, -32), (64, 96), (50, 32)], + ); + } + + #[test] + fn round_to_double_grid() { + round_cases( + RoundMode::DoubleGrid, + &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 64)], + ); + } + + #[test] + fn round_down_to_grid() { + round_cases( + RoundMode::DownToGrid, + &[(0, 0), (32, 0), (-32, 0), (64, 64), (50, 0)], + ); + } + + #[test] + fn round_up_to_grid() { + round_cases( + RoundMode::UpToGrid, + &[(0, 0), (32, 64), (-32, -64), (64, 64), (50, 64)], + ); + } + + #[test] + fn round_off() { + round_cases( + RoundMode::Off, + &[(0, 0), (32, 32), (-32, -32), (64, 64), (50, 50)], + ); + } + + fn round_cases(mode: RoundMode, cases: &[(i32, i32)]) { + for (value, expected) in cases.iter().copied() { + let value = F26Dot6::from_bits(value); + let expected = F26Dot6::from_bits(expected); + let state = RoundState { + mode, + ..Default::default() + }; + let result = state.round(value); + assert_eq!( + result, expected, + "mismatch in rounding: {mode:?}({value}) = {result} (expected {expected})" + ); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,29 @@ +//! Storage area. + +use super::{cow_slice::CowSlice, error::HintErrorKind}; + +/// Backing store for the storage area. +/// +/// This is just a wrapper for [`CowSlice`] that converts out of bounds +/// accesses to appropriate errors. +pub struct Storage<'a>(CowSlice<'a>); + +impl Storage<'_> { + pub fn get(&self, index: usize) -> Result { + self.0 + .get(index) + .ok_or(HintErrorKind::InvalidStorageIndex(index)) + } + + pub fn set(&mut self, index: usize, value: i32) -> Result<(), HintErrorKind> { + self.0 + .set(index, value) + .ok_or(HintErrorKind::InvalidStorageIndex(index)) + } +} + +impl<'a> From> for Storage<'a> { + fn from(value: CowSlice<'a>) -> Self { + Self(value) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,359 @@ +//! Value stack for TrueType interpreter. +//! +use raw::types::F26Dot6; +use read_fonts::tables::glyf::bytecode::InlineOperands; + +use super::error::HintErrorKind; + +use HintErrorKind::{ValueStackOverflow, ValueStackUnderflow}; + +/// Value stack for the TrueType interpreter. +/// +/// This uses a slice as the backing store rather than a `Vec` to enable +/// support for allocation from user buffers. +/// +/// See +pub struct ValueStack<'a> { + values: &'a mut [i32], + len: usize, + is_pedantic: bool, +} + +impl<'a> ValueStack<'a> { + pub fn new(values: &'a mut [i32], is_pedantic: bool) -> Self { + Self { + values, + len: 0, + is_pedantic, + } + } + + /// Returns the depth of the stack + /// + pub fn len(&self) -> usize { + self.len + } + + #[cfg(test)] + fn is_empty(&self) -> bool { + self.len == 0 + } + + // This is used in tests and also useful for tracing. + #[allow(dead_code)] + pub fn values(&self) -> &[i32] { + &self.values[..self.len] + } + + pub fn push(&mut self, value: i32) -> Result<(), HintErrorKind> { + let ptr = self + .values + .get_mut(self.len) + .ok_or(HintErrorKind::ValueStackOverflow)?; + *ptr = value; + self.len += 1; + Ok(()) + } + + /// Pushes values that have been decoded from the instruction stream + /// onto the stack. + /// + /// Implements the PUSHB[], PUSHW[], NPUSHB[] and NPUSHW[] instructions. + /// + /// See + pub fn push_inline_operands(&mut self, operands: &InlineOperands) -> Result<(), HintErrorKind> { + let push_count = operands.len(); + let stack_base = self.len; + for (stack_value, value) in self + .values + .get_mut(stack_base..stack_base + push_count) + .ok_or(ValueStackOverflow)? + .iter_mut() + .zip(operands.values()) + { + *stack_value = value; + } + self.len += push_count; + Ok(()) + } + + pub fn peek(&mut self) -> Option { + if self.len > 0 { + self.values.get(self.len - 1).copied() + } else { + None + } + } + + /// Pops a value from the stack. + /// + /// Implements the POP[] instruction. + /// + /// See + pub fn pop(&mut self) -> Result { + if let Some(value) = self.peek() { + self.len -= 1; + Ok(value) + } else if self.is_pedantic { + Err(ValueStackUnderflow) + } else { + Ok(0) + } + } + + /// Convenience method for instructions that expect values in 26.6 format. + pub fn pop_f26dot6(&mut self) -> Result { + Ok(F26Dot6::from_bits(self.pop()?)) + } + + /// Convenience method for instructions that pop values that are used as an + /// index. + pub fn pop_usize(&mut self) -> Result { + Ok(self.pop()? as usize) + } + + /// Applies a unary operation. + /// + /// Pops `a` from the stack and pushes `op(a)`. + pub fn apply_unary( + &mut self, + mut op: impl FnMut(i32) -> Result, + ) -> Result<(), HintErrorKind> { + let a = self.pop()?; + self.push(op(a)?) + } + + /// Applies a binary operation. + /// + /// Pops `b` and `a` from the stack and pushes `op(a, b)`. + pub fn apply_binary( + &mut self, + mut op: impl FnMut(i32, i32) -> Result, + ) -> Result<(), HintErrorKind> { + let b = self.pop()?; + let a = self.pop()?; + self.push(op(a, b)?) + } + + /// Clear the entire stack. + /// + /// Implements the CLEAR[] instruction. + /// + /// See + pub fn clear(&mut self) { + self.len = 0; + } + + /// Duplicate top stack element. + /// + /// Implements the DUP[] instruction. + /// + /// See + pub fn dup(&mut self) -> Result<(), HintErrorKind> { + if let Some(value) = self.peek() { + self.push(value) + } else if self.is_pedantic { + Err(ValueStackUnderflow) + } else { + self.push(0) + } + } + + /// Swap the top two elements on the stack. + /// + /// Implements the SWAP[] instruction. + /// + /// See + pub fn swap(&mut self) -> Result<(), HintErrorKind> { + let a = self.pop()?; + let b = self.pop()?; + self.push(a)?; + self.push(b) + } + + /// Copy the indexed element to the top of the stack. + /// + /// Implements the CINDEX[] instruction. + /// + /// See + pub fn copy_index(&mut self) -> Result<(), HintErrorKind> { + let top_ix = self.len.checked_sub(1).ok_or(ValueStackUnderflow)?; + let index = *self.values.get(top_ix).ok_or(ValueStackUnderflow)? as usize; + let element_ix = top_ix.checked_sub(index).ok_or(ValueStackUnderflow)?; + self.values[top_ix] = self.values[element_ix]; + Ok(()) + } + + /// Moves the indexed element to the top of the stack. + /// + /// Implements the MINDEX[] instruction. + /// + /// See + pub fn move_index(&mut self) -> Result<(), HintErrorKind> { + let top_ix = self.len.checked_sub(1).ok_or(ValueStackUnderflow)?; + let index = *self.values.get(top_ix).ok_or(ValueStackUnderflow)? as usize; + let element_ix = top_ix.checked_sub(index).ok_or(ValueStackUnderflow)?; + let new_top_ix = top_ix.checked_sub(1).ok_or(ValueStackUnderflow)?; + let value = self.values[element_ix]; + self.values + .copy_within(element_ix + 1..self.len, element_ix); + self.values[new_top_ix] = value; + self.len -= 1; + Ok(()) + } + + /// Roll the top three stack elements. + /// + /// Implements the ROLL[] instruction. + /// + /// See + pub fn roll(&mut self) -> Result<(), HintErrorKind> { + let a = self.pop()?; + let b = self.pop()?; + let c = self.pop()?; + self.push(b)?; + self.push(a)?; + self.push(c)?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::{HintErrorKind, ValueStack}; + use read_fonts::tables::glyf::bytecode::MockInlineOperands; + + // The following are macros because functions can't return a new ValueStack + // with a borrowed parameter. + macro_rules! make_stack { + ($values:expr) => { + ValueStack { + values: $values, + len: $values.len(), + is_pedantic: true, + } + }; + } + macro_rules! make_empty_stack { + ($values:expr) => { + ValueStack { + values: $values, + len: 0, + is_pedantic: true, + } + }; + } + + #[test] + fn push() { + let mut stack = make_empty_stack!(&mut [0; 4]); + for i in 0..4 { + stack.push(i).unwrap(); + assert_eq!(stack.peek(), Some(i)); + } + assert!(matches!( + stack.push(0), + Err(HintErrorKind::ValueStackOverflow) + )); + } + + #[test] + fn push_args() { + let mut stack = make_empty_stack!(&mut [0; 32]); + let values = [-5, 2, 2845, 92, -26, 42, i16::MIN, i16::MAX]; + let mock_args = MockInlineOperands::from_words(&values); + stack.push_inline_operands(&mock_args.operands()).unwrap(); + let mut popped = vec![]; + while !stack.is_empty() { + popped.push(stack.pop().unwrap()); + } + assert!(values + .iter() + .rev() + .map(|x| *x as i32) + .eq(popped.iter().copied())); + } + + #[test] + fn pop() { + let mut stack = make_stack!(&mut [0, 1, 2, 3]); + for i in (0..4).rev() { + assert_eq!(stack.pop().ok(), Some(i)); + } + assert!(matches!( + stack.pop(), + Err(HintErrorKind::ValueStackUnderflow) + )); + } + + #[test] + fn dup() { + let mut stack = make_stack!(&mut [1, 2, 3, 0]); + // pop extra element so we have room for dup + stack.pop().unwrap(); + stack.dup().unwrap(); + assert_eq!(stack.values(), &[1, 2, 3, 3]); + } + + #[test] + fn swap() { + let mut stack = make_stack!(&mut [1, 2, 3]); + stack.swap().unwrap(); + assert_eq!(stack.values(), &[1, 3, 2]); + } + + #[test] + fn copy_index() { + let mut stack = make_stack!(&mut [4, 10, 2, 1, 3]); + stack.copy_index().unwrap(); + assert_eq!(stack.values(), &[4, 10, 2, 1, 10]); + } + + #[test] + fn move_index() { + let mut stack = make_stack!(&mut [4, 10, 2, 1, 3]); + stack.move_index().unwrap(); + assert_eq!(stack.values(), &[4, 2, 1, 10]); + } + + #[test] + fn roll() { + let mut stack = make_stack!(&mut [1, 2, 3]); + stack.roll().unwrap(); + assert_eq!(stack.values(), &[2, 3, 1]); + } + + #[test] + fn unnop() { + let mut stack = make_stack!(&mut [42]); + stack.apply_unary(|a| Ok(-a)).unwrap(); + assert_eq!(stack.peek(), Some(-42)); + stack.apply_unary(|a| Ok(!a)).unwrap(); + assert_eq!(stack.peek(), Some(!-42)); + } + + #[test] + fn binop() { + let mut stack = make_empty_stack!(&mut [0; 32]); + for value in 1..=5 { + stack.push(value).unwrap(); + } + stack.apply_binary(|a, b| Ok(a + b)).unwrap(); + assert_eq!(stack.peek(), Some(9)); + stack.apply_binary(|a, b| Ok(a * b)).unwrap(); + assert_eq!(stack.peek(), Some(27)); + stack.apply_binary(|a, b| Ok(a - b)).unwrap(); + assert_eq!(stack.peek(), Some(-25)); + stack.apply_binary(|a, b| Ok(a / b)).unwrap(); + assert_eq!(stack.peek(), Some(0)); + } + + // Subtract with overflow when stack size is 1 and element index is 0 + // https://oss-fuzz.com/testcase-detail/5765856825507840 + #[test] + fn move_index_avoid_overflow() { + let mut stack = make_stack!(&mut [0]); + // Don't panic + let _ = stack.move_index(); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,835 @@ +//! Glyph zones. + +use read_fonts::{ + tables::glyf::{PointFlags, PointMarker}, + types::{F26Dot6, Point}, +}; + +use super::{ + error::HintErrorKind, + graphics::{CoordAxis, GraphicsState}, + math, +}; + +use HintErrorKind::{InvalidPointIndex, InvalidPointRange}; + +/// Reference to either the twilight or glyph zone. +/// +/// See +#[derive(Copy, Clone, PartialEq, Default, Debug)] +#[repr(u8)] +pub enum ZonePointer { + Twilight = 0, + #[default] + Glyph = 1, +} + +impl ZonePointer { + pub fn is_twilight(self) -> bool { + self == Self::Twilight + } +} + +impl TryFrom for ZonePointer { + type Error = HintErrorKind; + + fn try_from(value: i32) -> Result { + match value { + 0 => Ok(Self::Twilight), + 1 => Ok(Self::Glyph), + _ => Err(HintErrorKind::InvalidZoneIndex(value)), + } + } +} + +/// Glyph zone for TrueType hinting. +/// +/// See +#[derive(Default, Debug)] +pub struct Zone<'a> { + /// Outline points prior to applying scale. + pub unscaled: &'a [Point], + /// Copy of the outline points after applying scale. + pub original: &'a mut [Point], + /// Scaled outline points. + pub points: &'a mut [Point], + pub flags: &'a mut [PointFlags], + pub contours: &'a [u16], +} + +impl<'a> Zone<'a> { + /// Creates a new hinting zone. + pub fn new( + unscaled: &'a [Point], + original: &'a mut [Point], + points: &'a mut [Point], + flags: &'a mut [PointFlags], + contours: &'a [u16], + ) -> Self { + Self { + unscaled, + original, + points, + flags, + contours, + } + } + + pub fn point(&self, index: usize) -> Result, HintErrorKind> { + self.points + .get(index) + .copied() + .ok_or(InvalidPointIndex(index)) + } + + pub fn point_mut(&mut self, index: usize) -> Result<&mut Point, HintErrorKind> { + self.points.get_mut(index).ok_or(InvalidPointIndex(index)) + } + + pub fn original(&self, index: usize) -> Result, HintErrorKind> { + self.original + .get(index) + .copied() + .ok_or(InvalidPointIndex(index)) + } + + pub fn original_mut(&mut self, index: usize) -> Result<&mut Point, HintErrorKind> { + self.original.get_mut(index).ok_or(InvalidPointIndex(index)) + } + + pub fn unscaled(&self, index: usize) -> Point { + // Unscaled points in the twilight zone are always (0, 0). This allows + // us to avoid the allocation for that zone and back it with an empty + // slice. + self.unscaled.get(index).copied().unwrap_or_default() + } + + pub fn contour(&self, index: usize) -> Result { + self.contours + .get(index) + .copied() + .ok_or(HintErrorKind::InvalidContourIndex(index)) + } + + pub fn touch(&mut self, index: usize, axis: CoordAxis) -> Result<(), HintErrorKind> { + let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; + flag.set_marker(axis.touched_marker()); + Ok(()) + } + + pub fn untouch(&mut self, index: usize, axis: CoordAxis) -> Result<(), HintErrorKind> { + let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; + flag.clear_marker(axis.touched_marker()); + Ok(()) + } + + pub fn is_touched(&self, index: usize, axis: CoordAxis) -> Result { + let flag = self.flags.get(index).ok_or(InvalidPointIndex(index))?; + Ok(flag.has_marker(axis.touched_marker())) + } + + pub fn flip_on_curve(&mut self, index: usize) -> Result<(), HintErrorKind> { + let flag = self.flags.get_mut(index).ok_or(InvalidPointIndex(index))?; + flag.flip_on_curve(); + Ok(()) + } + + pub fn set_on_curve( + &mut self, + start: usize, + end: usize, + on: bool, + ) -> Result<(), HintErrorKind> { + let flags = self + .flags + .get_mut(start..end) + .ok_or(InvalidPointRange(start, end))?; + if on { + for flag in flags { + flag.set_on_curve(); + } + } else { + for flag in flags { + flag.clear_on_curve(); + } + } + Ok(()) + } + + /// Interpolate untouched points. + /// + /// Based on + pub fn iup(&mut self, axis: CoordAxis) -> Result<(), HintErrorKind> { + let mut point = 0; + for i in 0..self.contours.len() { + let mut end_point = self.contour(i)? as usize; + let first_point = point; + if end_point >= self.points.len() { + end_point = self.points.len() - 1; + } + while point <= end_point && !self.is_touched(point, axis)? { + point += 1; + } + if point <= end_point { + let first_touched = point; + let mut cur_touched = point; + point += 1; + while point <= end_point { + if self.is_touched(point, axis)? { + self.iup_interpolate(axis, cur_touched + 1, point - 1, cur_touched, point)?; + cur_touched = point; + } + point += 1; + } + if cur_touched == first_touched { + self.iup_shift(axis, first_point, end_point, cur_touched)?; + } else { + self.iup_interpolate( + axis, + cur_touched + 1, + end_point, + cur_touched, + first_touched, + )?; + if first_touched > 0 { + self.iup_interpolate( + axis, + first_point, + first_touched - 1, + cur_touched, + first_touched, + )?; + } + } + } + } + Ok(()) + } + + /// Shift the range of points p1..=p2 based on the delta given by the + /// reference point p. + /// + /// Based on + fn iup_shift( + &mut self, + axis: CoordAxis, + p1: usize, + p2: usize, + p: usize, + ) -> Result<(), HintErrorKind> { + if p1 > p2 || p1 > p || p > p2 { + return Ok(()); + } + macro_rules! shift_coord { + ($coord:ident) => { + let delta = self.point(p)?.$coord - self.original(p)?.$coord; + if delta != F26Dot6::ZERO { + let (first, second) = self + .points + .get_mut(p1..=p2) + .ok_or(InvalidPointRange(p1, p2 + 1))? + .split_at_mut(p - p1); + for point in first + .iter_mut() + .chain(second.get_mut(1..).ok_or(InvalidPointIndex(p - p1))?) + { + point.$coord += delta; + } + } + }; + } + if axis == CoordAxis::X { + shift_coord!(x); + } else { + shift_coord!(y); + } + Ok(()) + } + + /// Interpolate the range of points p1..=p2 based on the deltas + /// given by the two reference points. + /// + /// Based on + fn iup_interpolate( + &mut self, + axis: CoordAxis, + p1: usize, + p2: usize, + mut ref1: usize, + mut ref2: usize, + ) -> Result<(), HintErrorKind> { + if p1 > p2 { + return Ok(()); + } + let max_points = self.points.len(); + if ref1 >= max_points || ref2 >= max_points { + return Ok(()); + } + macro_rules! interpolate_coord { + ($coord:ident) => { + let mut orus1 = self.unscaled(ref1).$coord; + let mut orus2 = self.unscaled(ref2).$coord; + if orus1 > orus2 { + use core::mem::swap; + swap(&mut orus1, &mut orus2); + swap(&mut ref1, &mut ref2); + } + let org1 = self.original(ref1)?.$coord; + let org2 = self.original(ref2)?.$coord; + let cur1 = self.point(ref1)?.$coord; + let cur2 = self.point(ref2)?.$coord; + let delta1 = cur1 - org1; + let delta2 = cur2 - org2; + let iter = self + .original + .get(p1..=p2) + .ok_or(InvalidPointRange(p1, p2 + 1))? + .iter() + .zip( + self.unscaled + .get(p1..=p2) + .ok_or(InvalidPointRange(p1, p2 + 1))?, + ) + .zip( + self.points + .get_mut(p1..=p2) + .ok_or(InvalidPointRange(p1, p2 + 1))?, + ); + if cur1 == cur2 || orus1 == orus2 { + for ((orig, _unscaled), point) in iter { + let a = orig.$coord; + point.$coord = if a <= org1 { + a + delta1 + } else if a >= org2 { + a + delta2 + } else { + cur1 + }; + } + } else { + let scale = math::div((cur2 - cur1).to_bits(), orus2 - orus1); + for ((orig, unscaled), point) in iter { + let a = orig.$coord; + point.$coord = if a <= org1 { + a + delta1 + } else if a >= org2 { + a + delta2 + } else { + cur1 + F26Dot6::from_bits(math::mul(unscaled.$coord - orus1, scale)) + }; + } + } + }; + } + if axis == CoordAxis::X { + interpolate_coord!(x); + } else { + interpolate_coord!(y); + } + Ok(()) + } +} + +impl<'a> GraphicsState<'a> { + /// Takes an array of (zone pointer, point index) pairs and returns true if + /// all accesses would be valid. + pub fn in_bounds(&self, pairs: [(ZonePointer, usize); N]) -> bool { + for (zp, index) in pairs { + if index > self.zone(zp).points.len() { + return false; + } + } + true + } + + #[inline(always)] + pub fn zone(&self, pointer: ZonePointer) -> &Zone<'a> { + &self.zones[pointer as usize] + } + + #[inline(always)] + pub fn zone_mut(&mut self, pointer: ZonePointer) -> &mut Zone<'a> { + &mut self.zones[pointer as usize] + } + + #[inline(always)] + pub fn zp0(&self) -> &Zone<'a> { + self.zone(self.zp0) + } + + #[inline(always)] + pub fn zp0_mut(&mut self) -> &mut Zone<'a> { + self.zone_mut(self.zp0) + } + + #[inline(always)] + pub fn zp1(&self) -> &Zone { + self.zone(self.zp1) + } + + #[inline(always)] + pub fn zp1_mut(&mut self) -> &mut Zone<'a> { + self.zone_mut(self.zp1) + } + + #[inline(always)] + pub fn zp2(&self) -> &Zone { + self.zone(self.zp2) + } + + #[inline(always)] + pub fn zp2_mut(&mut self) -> &mut Zone<'a> { + self.zone_mut(self.zp2) + } +} + +impl GraphicsState<'_> { + /// Moves the requested original point by the given distance. + // See + pub(crate) fn move_original( + &mut self, + zone: ZonePointer, + point_ix: usize, + distance: F26Dot6, + ) -> Result<(), HintErrorKind> { + let fv = self.freedom_vector; + let fdotp = self.fdotp; + let axis = self.freedom_axis; + let point = self.zone_mut(zone).original_mut(point_ix)?; + match axis { + CoordAxis::X => point.x += distance, + CoordAxis::Y => point.y += distance, + CoordAxis::Both => { + let distance = distance.to_bits(); + if fv.x != 0 { + point.x += F26Dot6::from_bits(math::mul_div(distance, fv.x, fdotp)); + } + if fv.y != 0 { + point.y += F26Dot6::from_bits(math::mul_div(distance, fv.y, fdotp)); + } + } + } + Ok(()) + } + + /// Moves the requested scaled point by the given distance. + /// See + pub(crate) fn move_point( + &mut self, + zone: ZonePointer, + point_ix: usize, + distance: F26Dot6, + ) -> Result<(), HintErrorKind> { + // Note: we never adjust x in backward compatibility mode and we never + // adjust y in backward compatibility mode after IUP has been done in + // both directions. + // + // The primary motivation is to avoid horizontal adjustments in cases + // where subpixel rendering provides better fidelity. + // + // For more detail, see + let back_compat = self.backward_compatibility; + let back_compat_and_did_iup = back_compat && self.did_iup_x && self.did_iup_y; + let zone = &mut self.zones[zone as usize]; + let point = zone.point_mut(point_ix)?; + match self.freedom_axis { + CoordAxis::X => { + if !back_compat { + point.x += distance; + } + zone.touch(point_ix, CoordAxis::X)?; + } + CoordAxis::Y => { + if !back_compat_and_did_iup { + point.y += distance; + } + zone.touch(point_ix, CoordAxis::Y)?; + } + CoordAxis::Both => { + // + let fv = self.freedom_vector; + let distance = distance.to_bits(); + if fv.x != 0 { + if !back_compat { + point.x += F26Dot6::from_bits(math::mul_div(distance, fv.x, self.fdotp)); + } + zone.touch(point_ix, CoordAxis::X)?; + } + if fv.y != 0 { + if !back_compat_and_did_iup { + zone.point_mut(point_ix)?.y += + F26Dot6::from_bits(math::mul_div(distance, fv.y, self.fdotp)); + } + zone.touch(point_ix, CoordAxis::Y)?; + } + } + } + Ok(()) + } + + /// Moves the requested scaled point in the zone referenced by zp2 by the + /// given delta. + /// + /// This is a helper function for SHP, SHC, SHZ, and SHPIX instructions. + /// + /// See + pub(crate) fn move_zp2_point( + &mut self, + point_ix: usize, + dx: F26Dot6, + dy: F26Dot6, + do_touch: bool, + ) -> Result<(), HintErrorKind> { + // See notes above in move_point() about how this is used. + let back_compat = self.backward_compatibility; + let back_compat_and_did_iup = back_compat && self.did_iup_x && self.did_iup_y; + let fv = self.freedom_vector; + let zone = self.zp2_mut(); + if fv.x != 0 { + if !back_compat { + zone.point_mut(point_ix)?.x += dx; + } + if do_touch { + zone.touch(point_ix, CoordAxis::X)?; + } + } + if fv.y != 0 { + if !back_compat_and_did_iup { + zone.point_mut(point_ix)?.y += dy; + } + if do_touch { + zone.touch(point_ix, CoordAxis::Y)?; + } + } + Ok(()) + } + + /// Computes the adjustment made to a point along the current freedom vector. + /// See + pub(crate) fn point_displacement( + &mut self, + opcode: u8, + ) -> Result { + let (zone, point_ix) = if (opcode & 1) != 0 { + (self.zp0, self.rp1) + } else { + (self.zp1, self.rp2) + }; + let zone_data = self.zone(zone); + let point = zone_data.point(point_ix)?; + let original_point = zone_data.original(point_ix)?; + let distance = self.project(point, original_point); + let fv = self.freedom_vector; + let dx = F26Dot6::from_bits(math::mul_div(distance.to_bits(), fv.x, self.fdotp)); + let dy = F26Dot6::from_bits(math::mul_div(distance.to_bits(), fv.y, self.fdotp)); + Ok(PointDisplacement { + zone, + point_ix, + dx, + dy, + }) + } +} + +#[derive(PartialEq, Debug)] +pub(crate) struct PointDisplacement { + pub zone: ZonePointer, + pub point_ix: usize, + pub dx: F26Dot6, + pub dy: F26Dot6, +} + +impl CoordAxis { + fn touched_marker(self) -> PointMarker { + match self { + CoordAxis::Both => PointMarker::TOUCHED, + CoordAxis::X => PointMarker::TOUCHED_X, + CoordAxis::Y => PointMarker::TOUCHED_Y, + } + } +} + +#[cfg(test)] +mod tests { + use super::{math, CoordAxis, GraphicsState, PointDisplacement, Zone, ZonePointer}; + use raw::{ + tables::glyf::{PointFlags, PointMarker}, + types::{F26Dot6, Point}, + }; + + #[test] + fn flip_on_curve_point() { + let on_curve = PointFlags::on_curve(); + let off_curve = PointFlags::off_curve_quad(); + let mut zone = Zone { + unscaled: &mut [], + original: &mut [], + points: &mut [], + contours: &[], + flags: &mut [on_curve, off_curve, off_curve, on_curve], + }; + for i in 0..4 { + zone.flip_on_curve(i).unwrap(); + } + assert_eq!(zone.flags, &[off_curve, on_curve, on_curve, off_curve]); + } + + #[test] + fn set_on_curve_regions() { + let on_curve = PointFlags::on_curve(); + let off_curve = PointFlags::off_curve_quad(); + let mut zone = Zone { + unscaled: &mut [], + original: &mut [], + points: &mut [], + contours: &[], + flags: &mut [on_curve, off_curve, off_curve, on_curve], + }; + zone.set_on_curve(0, 2, true).unwrap(); + zone.set_on_curve(2, 4, false).unwrap(); + assert_eq!(zone.flags, &[on_curve, on_curve, off_curve, off_curve]); + } + + #[test] + fn iup_shift() { + let [untouched, touched] = point_markers(); + // A single touched point shifts the whole contour + let mut original = f26dot6_points([(0, 0), (10, 10), (20, 20)]); + let mut points = f26dot6_points([(-5, -20), (10, 10), (20, 20)]); + let mut zone = Zone { + unscaled: &mut [], + original: &mut original, + points: &mut points, + contours: &[3], + flags: &mut [touched, untouched, untouched], + }; + zone.iup(CoordAxis::X).unwrap(); + assert_eq!(zone.points, &f26dot6_points([(-5, -20), (5, 10), (15, 20)]),); + zone.iup(CoordAxis::Y).unwrap(); + assert_eq!(zone.points, &f26dot6_points([(-5, -20), (5, -10), (15, 0)]),); + } + + #[test] + fn iup_interpolate() { + let [untouched, touched] = point_markers(); + // Two touched points interpolates the intermediate point(s) + let mut original = f26dot6_points([(0, 0), (10, 10), (20, 20)]); + let mut points = f26dot6_points([(-5, -20), (10, 10), (27, 56)]); + let mut zone = Zone { + unscaled: &mut [ + Point::new(0, 0), + Point::new(500, 500), + Point::new(1000, 1000), + ], + original: &mut original, + points: &mut points, + contours: &[3], + flags: &mut [touched, untouched, touched], + }; + zone.iup(CoordAxis::X).unwrap(); + assert_eq!( + zone.points, + &f26dot6_points([(-5, -20), (11, 10), (27, 56)]), + ); + zone.iup(CoordAxis::Y).unwrap(); + assert_eq!( + zone.points, + &f26dot6_points([(-5, -20), (11, 18), (27, 56)]), + ); + } + + #[test] + fn move_point_x() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 0); + let point_ix = 0; + let orig_x = gs.zones[1].point(point_ix).unwrap().x; + let dx = F26Dot6::from_bits(10); + // backward compatibility is on by default and we don't move x coord + gs.move_point(ZonePointer::Glyph, 0, dx).unwrap(); + assert_eq!(orig_x, gs.zones[1].point(point_ix).unwrap().x); + // disable so we actually move + gs.backward_compatibility = false; + gs.move_point(ZonePointer::Glyph, 0, dx).unwrap(); + let new_x = gs.zones[1].point(point_ix).unwrap().x; + assert_ne!(orig_x, new_x); + assert_eq!(new_x, orig_x + dx) + } + + #[test] + fn move_point_y() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(0, 100); + let point_ix = 0; + let orig_y = gs.zones[1].point(point_ix).unwrap().y; + let dy = F26Dot6::from_bits(10); + // movement in y is prevented post-iup when backward + // compatibility is enabled + gs.did_iup_x = true; + gs.did_iup_y = true; + gs.move_point(ZonePointer::Glyph, 0, dy).unwrap(); + assert_eq!(orig_y, gs.zones[1].point(point_ix).unwrap().y); + // allow movement + gs.did_iup_x = false; + gs.did_iup_y = false; + gs.move_point(ZonePointer::Glyph, 0, dy).unwrap(); + let new_y = gs.zones[1].point(point_ix).unwrap().y; + assert_ne!(orig_y, new_y); + assert_eq!(new_y, orig_y + dy) + } + + #[test] + fn move_point_x_and_y() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 50); + let point_ix = 0; + let orig_point = gs.zones[1].point(point_ix).unwrap(); + let dist = F26Dot6::from_bits(10); + // prevent movement in x and y + gs.did_iup_x = true; + gs.did_iup_y = true; + gs.move_point(ZonePointer::Glyph, 0, dist).unwrap(); + assert_eq!(orig_point, gs.zones[1].point(point_ix).unwrap()); + // allow movement + gs.backward_compatibility = false; + gs.did_iup_x = false; + gs.did_iup_y = false; + gs.move_point(ZonePointer::Glyph, 0, dist).unwrap(); + let point = gs.zones[1].point(point_ix).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(4, -16)); + } + + #[test] + fn move_original_x() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 0); + let point_ix = 0; + let orig_x = gs.zones[1].original(point_ix).unwrap().x; + let dx = F26Dot6::from_bits(10); + gs.move_original(ZonePointer::Glyph, 0, dx).unwrap(); + let new_x = gs.zones[1].original(point_ix).unwrap().x; + assert_eq!(new_x, orig_x + dx) + } + + #[test] + fn move_original_y() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(0, 100); + let point_ix = 0; + let orig_y = gs.zones[1].original(point_ix).unwrap().y; + let dy = F26Dot6::from_bits(10); + gs.move_original(ZonePointer::Glyph, 0, dy).unwrap(); + let new_y = gs.zones[1].original(point_ix).unwrap().y; + assert_eq!(new_y, orig_y + dy) + } + + #[test] + fn move_original_x_and_y() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 50); + let point_ix = 0; + let dist = F26Dot6::from_bits(10); + gs.move_original(ZonePointer::Glyph, 0, dist).unwrap(); + let point = gs.zones[1].original(point_ix).unwrap(); + assert_eq!(point.map(F26Dot6::to_bits), Point::new(9, 4)); + } + + #[test] + fn move_zp2_point() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 50); + gs.zp2 = ZonePointer::Glyph; + let point_ix = 0; + let orig_point = gs.zones[1].point(point_ix).unwrap(); + let dx = F26Dot6::from_bits(10); + let dy = F26Dot6::from_bits(-10); + // prevent movement in x and y + gs.did_iup_x = true; + gs.did_iup_y = true; + gs.move_zp2_point(point_ix, dx, dy, false).unwrap(); + assert_eq!(orig_point, gs.zones[1].point(point_ix).unwrap()); + // allow movement + gs.backward_compatibility = false; + gs.did_iup_x = false; + gs.did_iup_y = false; + gs.move_zp2_point(point_ix, dx, dy, false).unwrap(); + let point = gs.zones[1].point(point_ix).unwrap(); + assert_eq!(point, orig_point + Point::new(dx, dy)); + } + + #[test] + fn point_displacement() { + let mut mock = MockGraphicsState::new(); + let mut gs = mock.graphics_state(100, 50); + gs.zp0 = ZonePointer::Glyph; + gs.rp1 = 0; + assert_eq!( + gs.point_displacement(1).unwrap(), + PointDisplacement { + zone: ZonePointer::Glyph, + point_ix: 0, + dx: F26Dot6::from_f64(-0.1875), + dy: F26Dot6::from_f64(-0.09375), + } + ); + gs.rp2 = 2; + assert_eq!( + gs.point_displacement(0).unwrap(), + PointDisplacement { + zone: ZonePointer::Glyph, + point_ix: 2, + dx: F26Dot6::from_f64(0.390625), + dy: F26Dot6::from_f64(0.203125), + } + ); + } + + struct MockGraphicsState { + points: [Point; 3], + original: [Point; 3], + contours: [u16; 1], + flags: [PointFlags; 3], + } + + impl MockGraphicsState { + fn new() -> Self { + Self { + points: f26dot6_points([(-5, -20), (10, 10), (20, 20)]), + original: f26dot6_points([(0, 0), (10, 10), (20, -42)]), + flags: [PointFlags::default(); 3], + contours: [3], + } + } + + fn graphics_state(&mut self, fv_x: i32, fv_y: i32) -> GraphicsState { + let glyph = Zone { + unscaled: &mut [], + original: &mut self.original, + points: &mut self.points, + contours: &self.contours, + flags: &mut self.flags, + }; + let v = math::normalize14(fv_x, fv_y); + let mut gs = GraphicsState { + zones: [Zone::default(), glyph], + freedom_vector: v, + proj_vector: v, + zp0: ZonePointer::Glyph, + ..Default::default() + }; + gs.update_projection_state(); + gs + } + } + + fn point_markers() -> [PointFlags; 2] { + let untouched = PointFlags::default(); + let mut touched = untouched; + touched.set_marker(PointMarker::TOUCHED); + [untouched, touched] + } + + fn f26dot6_points(points: [(i32, i32); N]) -> [Point; N] { + points.map(|point| Point::new(F26Dot6::from_bits(point.0), F26Dot6::from_bits(point.1))) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,271 @@ +//! Memory allocation for TrueType scaling. + +use std::mem::{align_of, size_of}; + +use read_fonts::{ + tables::glyf::PointFlags, + types::{F26Dot6, Fixed, Point}, +}; + +use super::{super::Hinting, Outline}; + +/// Buffers used during HarfBuzz-style glyph scaling. +pub(crate) struct HarfBuzzOutlineMemory<'a> { + pub points: &'a mut [Point], + pub contours: &'a mut [u16], + pub flags: &'a mut [PointFlags], + pub deltas: &'a mut [Point], + pub iup_buffer: &'a mut [Point], + pub composite_deltas: &'a mut [Point], +} + +impl<'a> HarfBuzzOutlineMemory<'a> { + pub(super) fn new(outline: &Outline, buf: &'a mut [u8]) -> Option { + let (points, buf) = alloc_slice(buf, outline.points)?; + let (contours, buf) = alloc_slice(buf, outline.contours)?; + let (flags, buf) = alloc_slice(buf, outline.points)?; + // Don't allocate any delta buffers if we don't have variations + let (deltas, iup_buffer, composite_deltas, _buf) = if outline.has_variations { + let (deltas, buf) = alloc_slice(buf, outline.max_simple_points)?; + let (iup_buffer, buf) = alloc_slice(buf, outline.max_simple_points)?; + let (composite_deltas, buf) = alloc_slice(buf, outline.max_component_delta_stack)?; + (deltas, iup_buffer, composite_deltas, buf) + } else { + ( + Default::default(), + Default::default(), + Default::default(), + buf, + ) + }; + Some(Self { + points, + contours, + flags, + deltas, + iup_buffer, + composite_deltas, + }) + } +} + +/// Buffers used during glyph scaling. +pub(crate) struct FreeTypeOutlineMemory<'a> { + pub unscaled: &'a mut [Point], + pub scaled: &'a mut [Point], + pub original_scaled: &'a mut [Point], + pub contours: &'a mut [u16], + pub flags: &'a mut [PointFlags], + pub deltas: &'a mut [Point], + pub iup_buffer: &'a mut [Point], + pub composite_deltas: &'a mut [Point], + pub stack: &'a mut [i32], + pub cvt: &'a mut [i32], + pub storage: &'a mut [i32], + pub twilight_scaled: &'a mut [Point], + pub twilight_original_scaled: &'a mut [Point], + pub twilight_flags: &'a mut [PointFlags], +} + +impl<'a> FreeTypeOutlineMemory<'a> { + pub(super) fn new(outline: &Outline, buf: &'a mut [u8], hinting: Hinting) -> Option { + let hinted = outline.has_hinting && hinting == Hinting::Embedded; + let (scaled, buf) = alloc_slice(buf, outline.points)?; + let (unscaled, buf) = alloc_slice(buf, outline.max_other_points)?; + // We only need original scaled points when hinting + let (original_scaled, buf) = if hinted { + alloc_slice(buf, outline.max_other_points)? + } else { + (Default::default(), buf) + }; + // Don't allocate any delta buffers if we don't have variations + let (deltas, iup_buffer, composite_deltas, buf) = if outline.has_variations { + let (deltas, buf) = alloc_slice(buf, outline.max_simple_points)?; + let (iup_buffer, buf) = alloc_slice(buf, outline.max_simple_points)?; + let (composite_deltas, buf) = alloc_slice(buf, outline.max_component_delta_stack)?; + (deltas, iup_buffer, composite_deltas, buf) + } else { + ( + Default::default(), + Default::default(), + Default::default(), + buf, + ) + }; + // Hinting value stack + let (stack, buf) = if hinted { + alloc_slice(buf, outline.max_stack)? + } else { + (Default::default(), buf) + }; + // Copy-on-write buffers for CVT and storage area + let (cvt, storage, buf) = if hinted { + let (cvt, buf) = alloc_slice(buf, outline.cvt_count)?; + let (storage, buf) = alloc_slice(buf, outline.storage_count)?; + (cvt, storage, buf) + } else { + (Default::default(), Default::default(), buf) + }; + // Twilight zone point buffers + let (twilight_scaled, twilight_original_scaled, buf) = if hinted { + let (scaled, buf) = alloc_slice(buf, outline.max_twilight_points)?; + let (original_scaled, buf) = alloc_slice(buf, outline.max_twilight_points)?; + (scaled, original_scaled, buf) + } else { + (Default::default(), Default::default(), buf) + }; + let (contours, buf) = alloc_slice(buf, outline.contours)?; + let (flags, buf) = alloc_slice(buf, outline.points)?; + // Twilight zone point flags + let twilight_flags = if hinted { + alloc_slice(buf, outline.max_twilight_points)?.0 + } else { + Default::default() + }; + Some(Self { + unscaled, + scaled, + original_scaled, + contours, + flags, + deltas, + iup_buffer, + composite_deltas, + stack, + cvt, + storage, + twilight_scaled, + twilight_original_scaled, + twilight_flags, + }) + } +} + +/// Allocates a mutable slice of `T` of the given length from the specified +/// buffer. +/// +/// Returns the allocated slice and the remainder of the buffer. +fn alloc_slice(buf: &mut [u8], len: usize) -> Option<(&mut [T], &mut [u8])> +where + T: bytemuck::AnyBitPattern + bytemuck::NoUninit, +{ + if len == 0 { + return Some((Default::default(), buf)); + } + // 1) Ensure we slice the buffer at a position that is properly aligned + // for T. + let base_ptr = buf.as_ptr() as usize; + let aligned_ptr = align_up(base_ptr, align_of::()); + let aligned_offset = aligned_ptr - base_ptr; + let buf = buf.get_mut(aligned_offset..)?; + // 2) Ensure we have enough space in the buffer to allocate our slice. + let len_in_bytes = len * size_of::(); + if len_in_bytes > buf.len() { + return None; + } + let (slice_buf, rest) = buf.split_at_mut(len_in_bytes); + // Bytemuck handles all safety guarantees here. + let slice = bytemuck::try_cast_slice_mut(slice_buf).ok()?; + Some((slice, rest)) +} + +fn align_up(len: usize, alignment: usize) -> usize { + len + (len.wrapping_neg() & (alignment - 1)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn unaligned_buffer() { + let mut buf = [0u8; 40]; + let alignment = align_of::(); + let addr = buf.as_ptr() as usize; + let mut unaligned_addr = addr; + // Force an unaligned offset + if unaligned_addr % alignment == 0 { + unaligned_addr += 1; + } + let unaligned_offset = unaligned_addr - addr; + let unaligned = &mut buf[unaligned_offset..]; + assert!(unaligned.as_ptr() as usize % alignment != 0); + let (slice, _) = alloc_slice::(unaligned, 8).unwrap(); + assert_eq!(slice.as_ptr() as usize % alignment, 0); + } + + #[test] + fn fail_unaligned_buffer() { + let mut buf = [0u8; 40]; + let alignment = align_of::(); + let addr = buf.as_ptr() as usize; + let mut unaligned_addr = addr; + // Force an unaligned offset + if unaligned_addr % alignment == 0 { + unaligned_addr += 1; + } + let unaligned_offset = unaligned_addr - addr; + let unaligned = &mut buf[unaligned_offset..]; + assert_eq!(alloc_slice::(unaligned, 16), None); + } + + #[test] + fn outline_memory() { + let outline_info = Outline { + glyph: None, + glyph_id: Default::default(), + points: 10, + contours: 4, + max_simple_points: 4, + max_other_points: 4, + max_component_delta_stack: 4, + max_stack: 0, + cvt_count: 0, + storage_count: 0, + max_twilight_points: 0, + has_hinting: false, + has_variations: true, + has_overlaps: false, + }; + let required_size = outline_info.required_buffer_size(Hinting::None); + let mut buf = vec![0u8; required_size]; + let memory = FreeTypeOutlineMemory::new(&outline_info, &mut buf, Hinting::None).unwrap(); + assert_eq!(memory.scaled.len(), outline_info.points); + assert_eq!(memory.unscaled.len(), outline_info.max_other_points); + // We don't allocate this buffer when hinting is disabled + assert_eq!(memory.original_scaled.len(), 0); + assert_eq!(memory.flags.len(), outline_info.points); + assert_eq!(memory.contours.len(), outline_info.contours); + assert_eq!(memory.deltas.len(), outline_info.max_simple_points); + assert_eq!(memory.iup_buffer.len(), outline_info.max_simple_points); + assert_eq!( + memory.composite_deltas.len(), + outline_info.max_component_delta_stack + ); + } + + #[test] + fn fail_outline_memory() { + let outline_info = Outline { + glyph: None, + glyph_id: Default::default(), + points: 10, + contours: 4, + max_simple_points: 4, + max_other_points: 4, + max_component_delta_stack: 4, + max_stack: 0, + cvt_count: 0, + storage_count: 0, + max_twilight_points: 0, + has_hinting: false, + has_variations: true, + has_overlaps: false, + }; + // Required size adds 4 bytes slop to account for internal alignment + // requirements. So subtract 5 to force a failure. + let not_enough = outline_info.required_buffer_size(Hinting::None) - 5; + let mut buf = vec![0u8; not_enough]; + assert!(FreeTypeOutlineMemory::new(&outline_info, &mut buf, Hinting::None).is_none()); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1427 @@ +//! Scaling support for TrueType outlines. + +mod deltas; +mod hint; +mod memory; +mod outline; + +#[cfg(feature = "libm")] +#[allow(unused_imports)] +use core_maths::CoreFloat; + +use deltas::AvailableVarMetrics; +pub use hint::{HintError, HintInstance, HintOutline}; +pub use outline::{Outline, ScaledOutline}; +use raw::FontRef; + +use super::{DrawError, GlyphHMetrics, Hinting}; +use crate::GLYF_COMPOSITE_RECURSION_LIMIT; +use memory::{FreeTypeOutlineMemory, HarfBuzzOutlineMemory}; + +use read_fonts::{ + tables::{ + glyf::{ + Anchor, CompositeGlyph, CompositeGlyphFlags, Glyf, Glyph, PointMarker, SimpleGlyph, + }, + gvar::Gvar, + hdmx::Hdmx, + loca::Loca, + }, + types::{F26Dot6, F2Dot14, Fixed, GlyphId, Point, Tag}, + TableProvider, +}; + +/// Number of phantom points generated at the end of an outline. +pub const PHANTOM_POINT_COUNT: usize = 4; + +/// Scaler state for TrueType outlines. +#[derive(Clone)] +pub struct Outlines<'a> { + pub(crate) font: FontRef<'a>, + pub(crate) glyph_metrics: GlyphHMetrics<'a>, + loca: Loca<'a>, + glyf: Glyf<'a>, + gvar: Option>, + hdmx: Option>, + fpgm: &'a [u8], + prep: &'a [u8], + cvt_len: u32, + max_function_defs: u16, + max_instruction_defs: u16, + max_twilight_points: u16, + max_stack_elements: u16, + max_storage: u16, + glyph_count: u16, + units_per_em: u16, + os2_vmetrics: [i16; 2], + var_metrics: AvailableVarMetrics, + prefer_interpreter: bool, +} + +impl<'a> Outlines<'a> { + pub fn new(font: &FontRef<'a>) -> Option { + let loca = font.loca(None).ok()?; + let glyf = font.glyf().ok()?; + let glyph_metrics = GlyphHMetrics::new(font)?; + let var_metrics = match glyph_metrics.hvar.as_ref() { + Some(hvar) => { + if hvar.lsb_mapping().is_some() { + AvailableVarMetrics::All + } else { + AvailableVarMetrics::Advances + } + } + None => AvailableVarMetrics::None, + }; + let ( + glyph_count, + max_function_defs, + max_instruction_defs, + max_twilight_points, + max_stack_elements, + max_storage, + max_instructions, + ) = font + .maxp() + .map(|maxp| { + ( + maxp.num_glyphs(), + maxp.max_function_defs().unwrap_or_default(), + maxp.max_instruction_defs().unwrap_or_default(), + // Add 4 for phantom points + // See + maxp.max_twilight_points() + .unwrap_or_default() + .saturating_add(4), + // Add 32 to match FreeType's heuristic for buggy fonts + // See + maxp.max_stack_elements() + .unwrap_or_default() + .saturating_add(32), + maxp.max_storage().unwrap_or_default(), + maxp.max_size_of_instructions().unwrap_or_default(), + ) + }) + .unwrap_or_default(); + let os2_vmetrics = font + .os2() + .map(|os2| [os2.s_typo_ascender(), os2.s_typo_descender()]) + .unwrap_or_default(); + let fpgm = font + .data_for_tag(Tag::new(b"fpgm")) + .unwrap_or_default() + .as_bytes(); + let prep = font + .data_for_tag(Tag::new(b"prep")) + .unwrap_or_default() + .as_bytes(); + // Copy FreeType's logic on whether to use the interpreter: + // + let prefer_interpreter = !(max_instructions == 0 && fpgm.is_empty() && prep.is_empty()); + let cvt_len = font.cvt().map(|cvt| cvt.len() as u32).unwrap_or_default(); + Some(Self { + font: font.clone(), + glyph_metrics, + loca, + glyf, + gvar: font.gvar().ok(), + hdmx: font.hdmx().ok(), + fpgm, + prep, + cvt_len, + max_function_defs, + max_instruction_defs, + max_twilight_points, + max_stack_elements, + max_storage, + glyph_count, + units_per_em: font.head().ok()?.units_per_em(), + os2_vmetrics, + var_metrics, + prefer_interpreter, + }) + } + + pub fn units_per_em(&self) -> u16 { + self.units_per_em + } + + pub fn glyph_count(&self) -> usize { + self.glyph_count as usize + } + + pub fn prefer_interpreter(&self) -> bool { + self.prefer_interpreter + } + + pub fn outline(&self, glyph_id: GlyphId) -> Result, DrawError> { + let mut outline = Outline { + glyph_id, + has_variations: self.gvar.is_some(), + ..Default::default() + }; + let glyph = self.loca.get_glyf(glyph_id, &self.glyf)?; + if let Some(glyph) = glyph.as_ref() { + self.outline_rec(glyph, &mut outline, 0, 0)?; + } + outline.points += PHANTOM_POINT_COUNT; + outline.max_stack = self.max_stack_elements as usize; + outline.cvt_count = self.cvt_len as usize; + outline.storage_count = self.max_storage as usize; + outline.max_twilight_points = self.max_twilight_points as usize; + outline.glyph = glyph; + Ok(outline) + } + + pub fn compute_scale(&self, ppem: Option) -> (bool, F26Dot6) { + if let Some(ppem) = ppem { + if self.units_per_em > 0 { + return ( + true, + F26Dot6::from_bits((ppem * 64.) as i32) + / F26Dot6::from_bits(self.units_per_em as i32), + ); + } + } + (false, F26Dot6::from_bits(0x10000)) + } +} + +impl Outlines<'_> { + fn outline_rec( + &self, + glyph: &Glyph, + outline: &mut Outline, + component_depth: usize, + recurse_depth: usize, + ) -> Result<(), DrawError> { + if recurse_depth > GLYF_COMPOSITE_RECURSION_LIMIT { + return Err(DrawError::RecursionLimitExceeded(outline.glyph_id)); + } + match glyph { + Glyph::Simple(simple) => { + let num_points = simple.num_points(); + let num_points_with_phantom = num_points + PHANTOM_POINT_COUNT; + outline.max_simple_points = outline.max_simple_points.max(num_points_with_phantom); + outline.points += num_points; + outline.contours += simple.end_pts_of_contours().len(); + outline.has_hinting = outline.has_hinting || simple.instruction_length() != 0; + outline.max_other_points = outline.max_other_points.max(num_points_with_phantom); + outline.has_overlaps |= simple.has_overlapping_contours(); + } + Glyph::Composite(composite) => { + let (mut count, instructions) = composite.count_and_instructions(); + count += PHANTOM_POINT_COUNT; + let point_base = outline.points; + for (component, flags) in composite.component_glyphs_and_flags() { + outline.has_overlaps |= flags.contains(CompositeGlyphFlags::OVERLAP_COMPOUND); + let component_glyph = self.loca.get_glyf(component.into(), &self.glyf)?; + let Some(component_glyph) = component_glyph else { + continue; + }; + self.outline_rec( + &component_glyph, + outline, + component_depth + count, + recurse_depth + 1, + )?; + } + let has_hinting = !instructions.unwrap_or_default().is_empty(); + if has_hinting { + // We only need the "other points" buffers if the + // composite glyph has instructions. + let num_points_in_composite = outline.points - point_base + PHANTOM_POINT_COUNT; + outline.max_other_points = + outline.max_other_points.max(num_points_in_composite); + } + outline.max_component_delta_stack = outline + .max_component_delta_stack + .max(component_depth + count); + outline.has_hinting = outline.has_hinting || has_hinting; + } + } + Ok(()) + } + + fn hdmx_width(&self, ppem: f32, glyph_id: GlyphId) -> Option { + let hdmx = self.hdmx.as_ref()?; + let ppem_u8 = ppem as u8; + // Make sure our ppem is integral and fits into u8 + if ppem_u8 as f32 == ppem { + // + hdmx.record_for_size(ppem_u8)? + .widths + .get(glyph_id.to_u32() as usize) + .copied() + } else { + None + } + } +} + +trait Scaler { + fn coords(&self) -> &[F2Dot14]; + fn outlines(&self) -> &Outlines; + fn setup_phantom_points( + &mut self, + bounds: [i16; 4], + lsb: i32, + advance: i32, + tsb: i32, + vadvance: i32, + ); + fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError>; + fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError>; + fn load_composite( + &mut self, + glyph: &CompositeGlyph, + glyph_id: GlyphId, + recurse_depth: usize, + ) -> Result<(), DrawError>; + + fn load( + &mut self, + glyph: &Option, + glyph_id: GlyphId, + recurse_depth: usize, + ) -> Result<(), DrawError> { + if recurse_depth > GLYF_COMPOSITE_RECURSION_LIMIT { + return Err(DrawError::RecursionLimitExceeded(glyph_id)); + } + let bounds = match &glyph { + Some(glyph) => [glyph.x_min(), glyph.x_max(), glyph.y_min(), glyph.y_max()], + _ => [0; 4], + }; + let outlines = self.outlines(); + let coords: &[F2Dot14] = self.coords(); + let lsb = outlines.glyph_metrics.lsb(glyph_id, coords); + let advance = outlines.glyph_metrics.advance_width(glyph_id, coords); + let [ascent, descent] = outlines.os2_vmetrics.map(|x| x as i32); + let tsb = ascent - bounds[3] as i32; + let vadvance = ascent - descent; + self.setup_phantom_points(bounds, lsb, advance, tsb, vadvance); + match glyph { + Some(Glyph::Simple(simple)) => self.load_simple(simple, glyph_id), + Some(Glyph::Composite(composite)) => { + self.load_composite(composite, glyph_id, recurse_depth) + } + None => self.load_empty(glyph_id), + } + } +} + +/// f32 all the things. Hold your rounding. No hinting. +pub(crate) struct HarfBuzzScaler<'a> { + outlines: &'a Outlines<'a>, + memory: HarfBuzzOutlineMemory<'a>, + coords: &'a [F2Dot14], + point_count: usize, + contour_count: usize, + component_delta_count: usize, + ppem: f32, + scale: F26Dot6, + is_scaled: bool, + /// Phantom points. These are 4 extra points appended to the end of an + /// outline that allow the bytecode interpreter to produce hinted + /// metrics. + /// + /// See + phantom: [Point; PHANTOM_POINT_COUNT], +} + +impl<'a> HarfBuzzScaler<'a> { + pub(crate) fn unhinted( + outlines: &'a Outlines<'a>, + outline: &'a Outline, + buf: &'a mut [u8], + ppem: Option, + coords: &'a [F2Dot14], + ) -> Result { + let (is_scaled, scale) = outlines.compute_scale(ppem); + let memory = + HarfBuzzOutlineMemory::new(outline, buf).ok_or(DrawError::InsufficientMemory)?; + Ok(Self { + outlines, + memory, + coords, + point_count: 0, + contour_count: 0, + component_delta_count: 0, + ppem: ppem.unwrap_or_default(), + scale, + is_scaled, + phantom: Default::default(), + }) + } + + pub(crate) fn scale( + mut self, + glyph: &Option, + glyph_id: GlyphId, + ) -> Result, DrawError> { + self.load(glyph, glyph_id, 0)?; + Ok(ScaledOutline::new( + &mut self.memory.points[..self.point_count], + self.phantom, + &mut self.memory.flags[..self.point_count], + &mut self.memory.contours[..self.contour_count], + self.outlines.hdmx_width(self.ppem, glyph_id), + )) + } +} + +/// F26Dot6 coords, Fixed deltas, and a penchant for rounding +pub(crate) struct FreeTypeScaler<'a> { + outlines: &'a Outlines<'a>, + memory: FreeTypeOutlineMemory<'a>, + coords: &'a [F2Dot14], + point_count: usize, + contour_count: usize, + component_delta_count: usize, + ppem: f32, + scale: F26Dot6, + is_scaled: bool, + is_hinted: bool, + pedantic_hinting: bool, + /// Phantom points. These are 4 extra points appended to the end of an + /// outline that allow the bytecode interpreter to produce hinted + /// metrics. + /// + /// See + phantom: [Point; PHANTOM_POINT_COUNT], + hinter: Option<&'a HintInstance>, +} + +impl<'a> FreeTypeScaler<'a> { + pub(crate) fn unhinted( + outlines: &'a Outlines<'a>, + outline: &'a Outline, + buf: &'a mut [u8], + ppem: Option, + coords: &'a [F2Dot14], + ) -> Result { + let (is_scaled, scale) = outlines.compute_scale(ppem); + let memory = FreeTypeOutlineMemory::new(outline, buf, Hinting::None) + .ok_or(DrawError::InsufficientMemory)?; + Ok(Self { + outlines, + memory, + coords, + point_count: 0, + contour_count: 0, + component_delta_count: 0, + ppem: ppem.unwrap_or_default(), + scale, + is_scaled, + is_hinted: false, + pedantic_hinting: false, + phantom: Default::default(), + hinter: None, + }) + } + + pub(crate) fn hinted( + outlines: &'a Outlines<'a>, + outline: &'a Outline, + buf: &'a mut [u8], + ppem: Option, + coords: &'a [F2Dot14], + hinter: &'a HintInstance, + pedantic_hinting: bool, + ) -> Result { + let (is_scaled, scale) = outlines.compute_scale(ppem); + let memory = FreeTypeOutlineMemory::new(outline, buf, Hinting::Embedded) + .ok_or(DrawError::InsufficientMemory)?; + Ok(Self { + outlines, + memory, + coords, + point_count: 0, + contour_count: 0, + component_delta_count: 0, + ppem: ppem.unwrap_or_default(), + scale, + is_scaled, + // We don't hint unscaled outlines + is_hinted: is_scaled, + pedantic_hinting, + phantom: Default::default(), + hinter: Some(hinter), + }) + } + + pub(crate) fn scale( + mut self, + glyph: &Option, + glyph_id: GlyphId, + ) -> Result, DrawError> { + self.load(glyph, glyph_id, 0)?; + // Use hdmx if hinting is requested and backward compatibility mode + // is not enabled. + // + let hdmx_width = if self.is_hinted + && self + .hinter + .as_ref() + .map(|hinter| !hinter.backward_compatibility()) + .unwrap_or(true) + { + self.outlines.hdmx_width(self.ppem, glyph_id) + } else { + None + }; + Ok(ScaledOutline::new( + &mut self.memory.scaled[..self.point_count], + self.phantom, + &mut self.memory.flags[..self.point_count], + &mut self.memory.contours[..self.contour_count], + hdmx_width, + )) + } +} + +impl Scaler for FreeTypeScaler<'_> { + fn setup_phantom_points( + &mut self, + bounds: [i16; 4], + lsb: i32, + advance: i32, + tsb: i32, + vadvance: i32, + ) { + // The four "phantom" points as computed by FreeType. + // See + // horizontal: + self.phantom[0].x = F26Dot6::from_bits(bounds[0] as i32 - lsb); + self.phantom[0].y = F26Dot6::ZERO; + self.phantom[1].x = self.phantom[0].x + F26Dot6::from_bits(advance); + self.phantom[1].y = F26Dot6::ZERO; + // vertical: + self.phantom[2].x = F26Dot6::ZERO; + self.phantom[2].y = F26Dot6::from_bits(bounds[3] as i32 + tsb); + self.phantom[3].x = F26Dot6::ZERO; + self.phantom[3].y = self.phantom[2].y - F26Dot6::from_bits(vadvance); + } + + fn coords(&self) -> &[F2Dot14] { + self.coords + } + + fn outlines(&self) -> &Outlines { + self.outlines + } + + fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError> { + // Roughly corresponds to the FreeType code at + // + let scale = self.scale; + let mut unscaled = self.phantom.map(|point| point.map(|x| x.to_bits())); + if self.outlines.glyph_metrics.hvar.is_none() + && self.outlines.gvar.is_some() + && !self.coords.is_empty() + { + if let Ok(deltas) = self.outlines.gvar.as_ref().unwrap().phantom_point_deltas( + &self.outlines.glyf, + &self.outlines.loca, + self.coords, + glyph_id, + ) { + unscaled[0] += deltas[0].map(Fixed::to_i32); + unscaled[1] += deltas[1].map(Fixed::to_i32); + } + } + if self.is_scaled { + for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { + *phantom = unscaled.map(F26Dot6::from_bits) * scale; + } + } else { + for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { + *phantom = unscaled.map(F26Dot6::from_i32); + } + } + Ok(()) + } + + fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError> { + use DrawError::InsufficientMemory; + // Compute the ranges for our point/flag buffers and slice them. + let points_start = self.point_count; + let point_count = glyph.num_points(); + let phantom_start = point_count; + let points_end = points_start + point_count + PHANTOM_POINT_COUNT; + let point_range = points_start..points_end; + let other_points_end = point_count + PHANTOM_POINT_COUNT; + // Scaled points and flags are accumulated as we load the outline. + let scaled = self + .memory + .scaled + .get_mut(point_range.clone()) + .ok_or(InsufficientMemory)?; + let flags = self + .memory + .flags + .get_mut(point_range) + .ok_or(InsufficientMemory)?; + // Unscaled points are temporary and are allocated as needed. We only + // ever need one copy in memory for any simple or composite glyph so + // allocate from the base of the buffer. + let unscaled = self + .memory + .unscaled + .get_mut(..other_points_end) + .ok_or(InsufficientMemory)?; + // Read our unscaled points and flags (up to point_count which does not + // include phantom points). + glyph.read_points_fast(&mut unscaled[..point_count], &mut flags[..point_count])?; + // Compute the range for our contour end point buffer and slice it. + let contours_start = self.contour_count; + let contour_end_pts = glyph.end_pts_of_contours(); + let contour_count = contour_end_pts.len(); + let contours_end = contours_start + contour_count; + let contours = self + .memory + .contours + .get_mut(contours_start..contours_end) + .ok_or(InsufficientMemory)?; + // Read the contour end points. + for (end_pt, contour) in contour_end_pts.iter().zip(contours.iter_mut()) { + *contour = end_pt.get(); + } + // Adjust the running point/contour total counts + self.point_count += point_count; + self.contour_count += contour_count; + // Append phantom points to the outline. + for (i, phantom) in self.phantom.iter().enumerate() { + unscaled[phantom_start + i] = phantom.map(|x| x.to_bits()); + flags[phantom_start + i] = Default::default(); + } + let mut have_deltas = false; + if self.outlines.gvar.is_some() && !self.coords.is_empty() { + let gvar = self.outlines.gvar.as_ref().unwrap(); + let glyph = deltas::SimpleGlyph { + points: &mut unscaled[..], + flags: &mut flags[..], + contours, + }; + let deltas = self + .memory + .deltas + .get_mut(..point_count + PHANTOM_POINT_COUNT) + .ok_or(InsufficientMemory)?; + let iup_buffer = self + .memory + .iup_buffer + .get_mut(..point_count + PHANTOM_POINT_COUNT) + .ok_or(InsufficientMemory)?; + if deltas::simple_glyph( + gvar, + glyph_id, + self.coords, + self.outlines.var_metrics, + glyph, + iup_buffer, + deltas, + ) + .is_ok() + { + have_deltas = true; + } + } + let ins = glyph.instructions(); + let is_hinted = self.is_hinted; + if self.is_scaled { + let scale = self.scale; + if have_deltas { + for ((point, unscaled), delta) in scaled + .iter_mut() + .zip(unscaled.iter_mut()) + .zip(self.memory.deltas.iter()) + { + let delta = delta.map(Fixed::to_f26dot6); + let scaled = (unscaled.map(F26Dot6::from_i32) + delta) * scale; + // The computed scale factor has an i32 -> 26.26 conversion built in. This undoes the + // extra shift. + *point = scaled.map(|v| F26Dot6::from_bits(v.to_i32())); + } + if is_hinted { + // For hinting, we need to adjust the unscaled points as well. + // Round off deltas for unscaled outlines. + for (unscaled, delta) in unscaled.iter_mut().zip(self.memory.deltas.iter()) { + *unscaled += delta.map(Fixed::to_i32); + } + } + } else { + for (point, unscaled) in scaled.iter_mut().zip(unscaled.iter_mut()) { + *point = unscaled.map(|v| F26Dot6::from_bits(v) * scale); + } + } + } else { + if have_deltas { + // Round off deltas for unscaled outlines. + for (unscaled, delta) in unscaled.iter_mut().zip(self.memory.deltas.iter()) { + *unscaled += delta.map(Fixed::to_i32); + } + } + // Unlike FreeType, we also store unscaled outlines in 26.6. + for (point, unscaled) in scaled.iter_mut().zip(unscaled.iter()) { + *point = unscaled.map(F26Dot6::from_i32); + } + } + // Commit our potentially modified phantom points. + if self.outlines.glyph_metrics.hvar.is_some() && self.is_hinted { + self.phantom[0] *= self.scale; + self.phantom[1] *= self.scale; + } else { + for (i, point) in scaled[phantom_start..] + .iter() + .enumerate() + .take(PHANTOM_POINT_COUNT) + { + self.phantom[i] = *point; + } + } + if let (Some(hinter), true) = (self.hinter.as_ref(), is_hinted) { + if !ins.is_empty() { + // Create a copy of our scaled points in original_scaled. + let original_scaled = self + .memory + .original_scaled + .get_mut(..other_points_end) + .ok_or(InsufficientMemory)?; + original_scaled.copy_from_slice(scaled); + // When hinting, round the phantom points. + for point in &mut scaled[phantom_start..] { + point.x = point.x.round(); + point.y = point.y.round(); + } + let mut input = HintOutline { + glyph_id, + unscaled, + scaled, + original_scaled, + flags, + contours, + bytecode: ins, + phantom: &mut self.phantom, + stack: self.memory.stack, + cvt: self.memory.cvt, + storage: self.memory.storage, + twilight_scaled: self.memory.twilight_scaled, + twilight_original_scaled: self.memory.twilight_original_scaled, + twilight_flags: self.memory.twilight_flags, + is_composite: false, + coords: self.coords, + }; + let hint_res = hinter.hint(self.outlines, &mut input, self.pedantic_hinting); + if let (Err(e), true) = (hint_res, self.pedantic_hinting) { + return Err(e)?; + } + } else if !hinter.backward_compatibility() { + // Even when missing instructions, FreeType uses rounded + // phantom points when hinting is requested and backward + // compatibility mode is disabled. + // See + // Notably, FreeType never calls TT_Hint_Glyph for composite + // glyphs when instructions are missing so this only applies + // to simple glyphs. + for (scaled, phantom) in scaled[phantom_start..].iter().zip(&mut self.phantom) { + *phantom = scaled.map(|x| x.round()); + } + } + } + if points_start != 0 { + // If we're not the first component, shift our contour end points. + for contour_end in contours.iter_mut() { + *contour_end += points_start as u16; + } + } + Ok(()) + } + + fn load_composite( + &mut self, + glyph: &CompositeGlyph, + glyph_id: GlyphId, + recurse_depth: usize, + ) -> Result<(), DrawError> { + use DrawError::InsufficientMemory; + let scale = self.scale; + // The base indices of the points and contours for the current glyph. + let point_base = self.point_count; + let contour_base = self.contour_count; + // Compute the per component deltas. Since composites can be nested, we + // use a stack and keep track of the base. + let mut have_deltas = false; + let delta_base = self.component_delta_count; + if self.outlines.gvar.is_some() && !self.coords.is_empty() { + let gvar = self.outlines.gvar.as_ref().unwrap(); + let count = glyph.components().count() + PHANTOM_POINT_COUNT; + let deltas = self + .memory + .composite_deltas + .get_mut(delta_base..delta_base + count) + .ok_or(InsufficientMemory)?; + if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { + // Apply selective deltas to phantom points. + self.outlines.var_metrics.phantom_deltas( + &mut self.phantom, + deltas, + |phantom, delta| { + phantom.x += F26Dot6::from_bits(delta.x.to_i32()); + }, + ); + have_deltas = true; + } + self.component_delta_count += count; + } + if self.is_scaled { + for point in self.phantom.iter_mut() { + *point *= scale; + } + } else { + for point in self.phantom.iter_mut() { + *point = point.map(|x| F26Dot6::from_i32(x.to_bits())); + } + } + for (i, component) in glyph.components().enumerate() { + // Loading a component glyph will override phantom points so save a copy. We'll + // restore them unless the USE_MY_METRICS flag is set. + let phantom = self.phantom; + // Load the component glyph and keep track of the points range. + let start_point = self.point_count; + let component_glyph = self + .outlines + .loca + .get_glyf(component.glyph.into(), &self.outlines.glyf)?; + self.load(&component_glyph, component.glyph.into(), recurse_depth + 1)?; + let end_point = self.point_count; + if !component + .flags + .contains(CompositeGlyphFlags::USE_MY_METRICS) + { + // If the USE_MY_METRICS flag is missing, we restore the phantom points we + // saved at the start of the loop. + self.phantom = phantom; + } + // Prepares the transform components for our conversion math below. + fn scale_component(x: F2Dot14) -> F26Dot6 { + F26Dot6::from_bits(x.to_bits() as i32 * 4) + } + let xform = &component.transform; + let xx = scale_component(xform.xx); + let yx = scale_component(xform.yx); + let xy = scale_component(xform.xy); + let yy = scale_component(xform.yy); + let have_xform = component.flags.intersects( + CompositeGlyphFlags::WE_HAVE_A_SCALE + | CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE + | CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO, + ); + if have_xform { + let scaled = &mut self.memory.scaled[start_point..end_point]; + if self.is_scaled { + for point in scaled { + let x = point.x * xx + point.y * xy; + let y = point.x * yx + point.y * yy; + point.x = x; + point.y = y; + } + } else { + for point in scaled { + // This juggling is necessary because, unlike FreeType, we also + // return unscaled outlines in 26.6 format for a consistent interface. + let unscaled = point.map(|c| F26Dot6::from_bits(c.to_i32())); + let x = unscaled.x * xx + unscaled.y * xy; + let y = unscaled.x * yx + unscaled.y * yy; + *point = Point::new(x, y).map(|c| F26Dot6::from_i32(c.to_bits())); + } + } + } + let anchor_offset = match component.anchor { + Anchor::Offset { x, y } => { + let (mut x, mut y) = (x as i32, y as i32); + if have_xform + && component.flags + & (CompositeGlyphFlags::SCALED_COMPONENT_OFFSET + | CompositeGlyphFlags::UNSCALED_COMPONENT_OFFSET) + == CompositeGlyphFlags::SCALED_COMPONENT_OFFSET + { + // According to FreeType, this algorithm is a "guess" + // and works better than the one documented by Apple. + // https://github.com/freetype/freetype/blob/b1c90733ee6a04882b133101d61b12e352eeb290/src/truetype/ttgload.c#L1259 + fn hypot(a: F26Dot6, b: F26Dot6) -> Fixed { + let a = a.to_bits().abs(); + let b = b.to_bits().abs(); + Fixed::from_bits(if a > b { + a + ((3 * b) >> 3) + } else { + b + ((3 * a) >> 3) + }) + } + // FreeType uses a fixed point multiplication here. + x = (Fixed::from_bits(x) * hypot(xx, xy)).to_bits(); + y = (Fixed::from_bits(y) * hypot(yy, yx)).to_bits(); + } + if have_deltas { + let delta = self + .memory + .composite_deltas + .get(delta_base + i) + .copied() + .unwrap_or_default(); + // For composite glyphs, we copy FreeType and round off + // the fractional parts of deltas. + x += delta.x.to_i32(); + y += delta.y.to_i32(); + } + if self.is_scaled { + let mut offset = Point::new(x, y).map(F26Dot6::from_bits) * scale; + if self.is_hinted + && component + .flags + .contains(CompositeGlyphFlags::ROUND_XY_TO_GRID) + { + // Only round the y-coordinate, per FreeType. + offset.y = offset.y.round(); + } + offset + } else { + Point::new(x, y).map(F26Dot6::from_i32) + } + } + Anchor::Point { base, component } => { + let (base_offset, component_offset) = (base as usize, component as usize); + let base_point = self + .memory + .scaled + .get(point_base + base_offset) + .ok_or(DrawError::InvalidAnchorPoint(glyph_id, base))?; + let component_point = self + .memory + .scaled + .get(start_point + component_offset) + .ok_or(DrawError::InvalidAnchorPoint(glyph_id, component))?; + *base_point - *component_point + } + }; + if anchor_offset.x != F26Dot6::ZERO || anchor_offset.y != F26Dot6::ZERO { + for point in &mut self.memory.scaled[start_point..end_point] { + *point += anchor_offset; + } + } + } + if have_deltas { + self.component_delta_count = delta_base; + } + if let (Some(hinter), true) = (self.hinter.as_ref(), self.is_hinted) { + let ins = glyph.instructions().unwrap_or_default(); + if !ins.is_empty() { + // For composite glyphs, the unscaled and original points are + // simply copies of the current point set. + let start_point = point_base; + let end_point = self.point_count + PHANTOM_POINT_COUNT; + let point_range = start_point..end_point; + let phantom_start = point_range.len() - PHANTOM_POINT_COUNT; + let scaled = &mut self.memory.scaled[point_range.clone()]; + let flags = self + .memory + .flags + .get_mut(point_range.clone()) + .ok_or(InsufficientMemory)?; + // Append the current phantom points to the outline. + for (i, phantom) in self.phantom.iter().enumerate() { + scaled[phantom_start + i] = *phantom; + flags[phantom_start + i] = Default::default(); + } + let other_points_end = point_range.len(); + let unscaled = self + .memory + .unscaled + .get_mut(..other_points_end) + .ok_or(InsufficientMemory)?; + for (scaled, unscaled) in scaled.iter().zip(unscaled.iter_mut()) { + *unscaled = scaled.map(|x| x.to_bits()); + } + let original_scaled = self + .memory + .original_scaled + .get_mut(..other_points_end) + .ok_or(InsufficientMemory)?; + original_scaled.copy_from_slice(scaled); + let contours = self + .memory + .contours + .get_mut(contour_base..self.contour_count) + .ok_or(InsufficientMemory)?; + // Round the phantom points. + for p in &mut scaled[phantom_start..] { + p.x = p.x.round(); + p.y = p.y.round(); + } + // Clear the "touched" flags that are used during IUP processing. + for flag in flags.iter_mut() { + flag.clear_marker(PointMarker::TOUCHED); + } + // Make sure our contour end points accurately reflect the + // outline slices. + if point_base != 0 { + let delta = point_base as u16; + for contour in contours.iter_mut() { + *contour -= delta; + } + } + let mut input = HintOutline { + glyph_id, + unscaled, + scaled, + original_scaled, + flags, + contours, + bytecode: ins, + phantom: &mut self.phantom, + stack: self.memory.stack, + cvt: self.memory.cvt, + storage: self.memory.storage, + twilight_scaled: self.memory.twilight_scaled, + twilight_original_scaled: self.memory.twilight_original_scaled, + twilight_flags: self.memory.twilight_flags, + is_composite: true, + coords: self.coords, + }; + let hint_res = hinter.hint(self.outlines, &mut input, self.pedantic_hinting); + if let (Err(e), true) = (hint_res, self.pedantic_hinting) { + return Err(e)?; + } + // Undo the contour shifts if we applied them above. + if point_base != 0 { + let delta = point_base as u16; + for contour in contours.iter_mut() { + *contour += delta; + } + } + } + } + Ok(()) + } +} + +impl Scaler for HarfBuzzScaler<'_> { + fn setup_phantom_points( + &mut self, + bounds: [i16; 4], + lsb: i32, + advance: i32, + tsb: i32, + vadvance: i32, + ) { + // Same pattern as FreeType, just f32 + // horizontal: + self.phantom[0].x = bounds[0] as f32 - lsb as f32; + self.phantom[0].y = 0.0; + self.phantom[1].x = self.phantom[0].x + advance as f32; + self.phantom[1].y = 0.0; + // vertical: + self.phantom[2].x = 0.0; + self.phantom[2].y = bounds[3] as f32 + tsb as f32; + self.phantom[3].x = 0.0; + self.phantom[3].y = self.phantom[2].y - vadvance as f32; + } + + fn coords(&self) -> &[F2Dot14] { + self.coords + } + + fn outlines(&self) -> &Outlines { + self.outlines + } + + fn load_empty(&mut self, glyph_id: GlyphId) -> Result<(), DrawError> { + // HB doesn't have an equivalent so this version just copies the + // FreeType version above but changed to use floating point + let scale = self.scale.to_f32(); + let mut unscaled = self.phantom; + if self.outlines.glyph_metrics.hvar.is_none() + && self.outlines.gvar.is_some() + && !self.coords.is_empty() + { + if let Ok(deltas) = self.outlines.gvar.as_ref().unwrap().phantom_point_deltas( + &self.outlines.glyf, + &self.outlines.loca, + self.coords, + glyph_id, + ) { + unscaled[0] += deltas[0].map(Fixed::to_f32); + unscaled[1] += deltas[1].map(Fixed::to_f32); + } + } + if self.is_scaled { + for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { + *phantom = *unscaled * scale; + } + } else { + for (phantom, unscaled) in self.phantom.iter_mut().zip(&unscaled) { + *phantom = *unscaled; + } + } + Ok(()) + } + + fn load_simple(&mut self, glyph: &SimpleGlyph, glyph_id: GlyphId) -> Result<(), DrawError> { + use DrawError::InsufficientMemory; + // Compute the ranges for our point/flag buffers and slice them. + let points_start = self.point_count; + let point_count = glyph.num_points(); + let phantom_start = point_count; + let points_end = points_start + point_count + PHANTOM_POINT_COUNT; + let point_range = points_start..points_end; + // Points and flags are accumulated as we load the outline. + let points = self + .memory + .points + .get_mut(point_range.clone()) + .ok_or(InsufficientMemory)?; + let flags = self + .memory + .flags + .get_mut(point_range) + .ok_or(InsufficientMemory)?; + glyph.read_points_fast(&mut points[..point_count], &mut flags[..point_count])?; + // Compute the range for our contour end point buffer and slice it. + let contours_start = self.contour_count; + let contour_end_pts = glyph.end_pts_of_contours(); + let contour_count = contour_end_pts.len(); + let contours_end = contours_start + contour_count; + let contours = self + .memory + .contours + .get_mut(contours_start..contours_end) + .ok_or(InsufficientMemory)?; + // Read the contour end points. + for (end_pt, contour) in contour_end_pts.iter().zip(contours.iter_mut()) { + *contour = end_pt.get(); + } + // Adjust the running point/contour total counts + self.point_count += point_count; + self.contour_count += contour_count; + // Append phantom points to the outline. + for (i, phantom) in self.phantom.iter().enumerate() { + points[phantom_start + i] = *phantom; + flags[phantom_start + i] = Default::default(); + } + // Acquire deltas + if self.outlines.gvar.is_some() && !self.coords.is_empty() { + let gvar = self.outlines.gvar.as_ref().unwrap(); + let glyph = deltas::SimpleGlyph { + points: &mut points[..], + flags: &mut flags[..], + contours, + }; + let deltas = self + .memory + .deltas + .get_mut(..point_count + PHANTOM_POINT_COUNT) + .ok_or(InsufficientMemory)?; + let iup_buffer = self + .memory + .iup_buffer + .get_mut(..point_count + PHANTOM_POINT_COUNT) + .ok_or(InsufficientMemory)?; + if deltas::simple_glyph( + gvar, + glyph_id, + self.coords, + self.outlines.var_metrics, + glyph, + iup_buffer, + deltas, + ) + .is_ok() + { + for (point, delta) in points.iter_mut().zip(deltas) { + *point += *delta; + } + } + } + // Apply scaling + if self.is_scaled { + let scale = self.scale.to_f32(); + for point in points.iter_mut() { + *point = point.map(|c| c * scale); + } + } + + if points_start != 0 { + // If we're not the first component, shift our contour end points. + for contour_end in contours.iter_mut() { + *contour_end += points_start as u16; + } + } + Ok(()) + } + + fn load_composite( + &mut self, + glyph: &CompositeGlyph, + glyph_id: GlyphId, + recurse_depth: usize, + ) -> Result<(), DrawError> { + use DrawError::InsufficientMemory; + let scale = self.scale.to_f32(); + // The base indices of the points for the current glyph. + let point_base = self.point_count; + // Compute the per component deltas. Since composites can be nested, we + // use a stack and keep track of the base. + let mut have_deltas = false; + let delta_base = self.component_delta_count; + if self.outlines.gvar.is_some() && !self.coords.is_empty() { + let gvar = self.outlines.gvar.as_ref().unwrap(); + let count = glyph.components().count() + PHANTOM_POINT_COUNT; + let deltas = self + .memory + .composite_deltas + .get_mut(delta_base..delta_base + count) + .ok_or(InsufficientMemory)?; + if deltas::composite_glyph(gvar, glyph_id, self.coords, &mut deltas[..]).is_ok() { + // Apply selective deltas to phantom points. + self.outlines.var_metrics.phantom_deltas( + &mut self.phantom, + deltas, + |phantom, delta| { + phantom.x += delta.x; + }, + ); + have_deltas = true; + } + self.component_delta_count += count; + } + if self.is_scaled { + for point in self.phantom.iter_mut() { + *point *= scale; + } + } + for (i, component) in glyph.components().enumerate() { + // Loading a component glyph will override phantom points so save a copy. We'll + // restore them unless the USE_MY_METRICS flag is set. + let phantom = self.phantom; + // Load the component glyph and keep track of the points range. + let start_point = self.point_count; + let component_glyph = self + .outlines + .loca + .get_glyf(component.glyph.into(), &self.outlines.glyf)?; + self.load(&component_glyph, component.glyph.into(), recurse_depth + 1)?; + let end_point = self.point_count; + if !component + .flags + .contains(CompositeGlyphFlags::USE_MY_METRICS) + { + // If the USE_MY_METRICS flag is missing, we restore the phantom points we + // saved at the start of the loop. + self.phantom = phantom; + } + let have_xform = component.flags.intersects( + CompositeGlyphFlags::WE_HAVE_A_SCALE + | CompositeGlyphFlags::WE_HAVE_AN_X_AND_Y_SCALE + | CompositeGlyphFlags::WE_HAVE_A_TWO_BY_TWO, + ); + let mut transform = if have_xform { + let xform = &component.transform; + [ + xform.xx, + xform.yx, + xform.xy, + xform.yy, + F2Dot14::ZERO, + F2Dot14::ZERO, + ] + .map(|x| x.to_f32()) + } else { + [1.0, 0.0, 0.0, 1.0, 0.0, 0.0] // identity + }; + + let anchor_offset = match component.anchor { + Anchor::Offset { x, y } => { + let (mut x, mut y) = (x as f32, y as f32); + if have_xform + && component.flags + & (CompositeGlyphFlags::SCALED_COMPONENT_OFFSET + | CompositeGlyphFlags::UNSCALED_COMPONENT_OFFSET) + == CompositeGlyphFlags::SCALED_COMPONENT_OFFSET + { + // Scale x by the magnitude of the x-basis, y by the y-basis + // FreeType implements hypot, we can just use the provided implementation + x *= hypot(transform[0], transform[2]); + y *= hypot(transform[1], transform[3]); + } + Point::new(x, y) + + self + .memory + .composite_deltas + .get(delta_base + i) + .copied() + .unwrap_or_default() + } + Anchor::Point { base, component } => { + let (base_offset, component_offset) = (base as usize, component as usize); + let base_point = self + .memory + .points + .get(point_base + base_offset) + .ok_or(DrawError::InvalidAnchorPoint(glyph_id, base))?; + let component_point = self + .memory + .points + .get(start_point + component_offset) + .ok_or(DrawError::InvalidAnchorPoint(glyph_id, component))?; + *base_point - *component_point + } + }; + transform[4] = anchor_offset.x; + transform[5] = anchor_offset.y; + + let points = &mut self.memory.points[start_point..end_point]; + for point in points.iter_mut() { + *point = map_point(transform, *point); + } + } + if have_deltas { + self.component_delta_count = delta_base; + } + Ok(()) + } +} + +/// Magnitude of the vector (x, y) +fn hypot(x: f32, y: f32) -> f32 { + x.hypot(y) +} + +fn map_point(transform: [f32; 6], p: Point) -> Point { + Point { + x: transform[0] * p.x + transform[2] * p.y + transform[4], + y: transform[1] * p.x + transform[3] * p.y + transform[5], + } +} + +impl AvailableVarMetrics { + /// Calls `f` for each combination of phantom point and its associated + /// delta based on the available metrics present in `self`. + fn phantom_deltas( + self, + phantom: &mut [Point

    ; 4], + deltas: &[Point], + f: impl Fn(&mut Point

    , &Point), + ) { + match self { + Self::None => { + f(&mut phantom[0], &deltas[deltas.len() - 4]); + f(&mut phantom[1], &deltas[deltas.len() - 3]); + } + Self::Advances => { + f(&mut phantom[0], &deltas[deltas.len() - 4]); + } + Self::All => {} + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::MetadataProvider; + use read_fonts::{FontRef, TableProvider}; + + #[test] + fn overlap_flags() { + let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); + let scaler = Outlines::new(&font).unwrap(); + let glyph_count = font.maxp().unwrap().num_glyphs(); + // GID 2 is a composite glyph with the overlap bit on a component + // GID 3 is a simple glyph with the overlap bit on the first flag + let expected_gids_with_overlap = vec![2, 3]; + assert_eq!( + expected_gids_with_overlap, + (0..glyph_count) + .filter(|gid| scaler.outline(GlyphId::from(*gid)).unwrap().has_overlaps) + .collect::>() + ); + } + + #[test] + fn interpreter_preference() { + // no instructions in this font... + let font = FontRef::new(font_test_data::COLRV0V1).unwrap(); + let outlines = Outlines::new(&font).unwrap(); + // thus no preference for the interpreter + assert!(!outlines.prefer_interpreter()); + // but this one has instructions... + let font = FontRef::new(font_test_data::TTHINT_SUBSET).unwrap(); + let outlines = Outlines::new(&font).unwrap(); + // so let's use it + assert!(outlines.prefer_interpreter()); + } + + #[test] + fn empty_glyph_advance() { + let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); + let mut outlines = Outlines::new(&font).unwrap(); + let coords = [F2Dot14::from_f32(0.5)]; + let ppem = Some(24.0); + let gid = font.charmap().map(' ').unwrap(); + let outline = outlines.outline(gid).unwrap(); + // Make sure this is an empty outline since that's what we're testing + assert!(outline.glyph.is_none()); + let mut buf = [0u8; 128]; + let scaler = + FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); + let scaled = scaler.scale(&outline.glyph, gid).unwrap(); + let advance_hvar = scaled.adjusted_advance_width(); + // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar + outlines.glyph_metrics.hvar = None; + outlines.var_metrics = AvailableVarMetrics::None; + let scaler = + FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); + let scaled = scaler.scale(&outline.glyph, gid).unwrap(); + let advance_gvar = scaled.adjusted_advance_width(); + // Make sure we have an advance and that the two are the same + assert!(advance_hvar != F26Dot6::ZERO); + assert_eq!(advance_hvar, advance_gvar); + } + + #[test] + fn empty_glyphs_have_phantom_points_too() { + let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); + let outlines = Outlines::new(&font).unwrap(); + let gid = font.charmap().map(' ').unwrap(); + let outline = outlines.outline(gid).unwrap(); + assert!(outline.glyph.is_none()); + assert_eq!(outline.points, PHANTOM_POINT_COUNT); + } + + // Pull metric deltas from gvar when hvar is not present + // + #[test] + fn missing_hvar_advance() { + let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); + let mut outlines = Outlines::new(&font).unwrap(); + let coords = [F2Dot14::from_f32(0.5)]; + let ppem = Some(24.0); + let gid = font.charmap().map('A').unwrap(); + let outline = outlines.outline(gid).unwrap(); + let mut buf = [0u8; 1024]; + let scaler = + FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); + let scaled = scaler.scale(&outline.glyph, gid).unwrap(); + let advance_hvar = scaled.adjusted_advance_width(); + // Set HVAR to None and mark var metrics as missing so we pull deltas from gvar + outlines.glyph_metrics.hvar = None; + outlines.var_metrics = AvailableVarMetrics::None; + let scaler = + FreeTypeScaler::unhinted(&outlines, &outline, &mut buf, ppem, &coords).unwrap(); + let scaled = scaler.scale(&outline.glyph, gid).unwrap(); + let advance_gvar = scaled.adjusted_advance_width(); + // Make sure we have an advance and that the two are the same + assert!(advance_hvar != F26Dot6::ZERO); + assert_eq!(advance_hvar, advance_gvar); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,160 @@ +//! TrueType outline types. + +use std::mem::size_of; + +use super::super::{ + path::{to_path, ToPathError}, + pen::PathStyle, + Hinting, OutlinePen, +}; +use raw::tables::glyf::PointCoord; +use read_fonts::{ + tables::glyf::{Glyph, PointFlags}, + types::{F26Dot6, Fixed, GlyphId, Point}, +}; + +/// Represents the information necessary to scale a glyph outline. +/// +/// Contains a reference to the glyph data itself as well as metrics that +/// can be used to compute the memory requirements for scaling the glyph. +#[derive(Clone, Default)] +pub struct Outline<'a> { + pub glyph_id: GlyphId, + /// The associated top-level glyph for the outline. + pub glyph: Option>, + /// Sum of the point counts of all simple glyphs in an outline. + pub points: usize, + /// Sum of the contour counts of all simple glyphs in an outline. + pub contours: usize, + /// Maximum number of points in a single simple glyph. + pub max_simple_points: usize, + /// "Other" points are the unscaled or original scaled points. + /// + /// The size of these buffer is the same and this value tracks the size + /// for one (not both) of the buffers. This is the maximum of + /// `max_simple_points` and the total number of points for all component + /// glyphs in a single composite glyph. + pub max_other_points: usize, + /// Maximum size of the component delta stack. + /// + /// For composite glyphs in variable fonts, delta values are computed + /// for each component. This tracks the maximum stack depth necessary + /// to store those values during processing. + pub max_component_delta_stack: usize, + /// Number of entries in the hinting value stack. + pub max_stack: usize, + /// Number of CVT entries for copy-on-write support. + pub cvt_count: usize, + /// Number of storage area entries for copy-on-write support. + pub storage_count: usize, + /// Maximum number of points in the twilight zone for hinting. + pub max_twilight_points: usize, + /// True if any component of a glyph has bytecode instructions. + pub has_hinting: bool, + /// True if the glyph requires variation delta processing. + pub has_variations: bool, + /// True if the glyph contains any simple or compound overlap flags. + pub has_overlaps: bool, +} + +impl Outline<'_> { + /// Returns the minimum size in bytes required to scale an outline based + /// on the computed sizes. + pub fn required_buffer_size(&self, hinting: Hinting) -> usize { + let mut size = 0; + let hinting = self.has_hinting && hinting == Hinting::Embedded; + // Scaled, unscaled and (for hinting) original scaled points + size += self.points * size_of::>(); + // Unscaled and (if hinted) original scaled points + size += self.max_other_points * size_of::>() * if hinting { 2 } else { 1 }; + // Contour end points + size += self.contours * size_of::(); + // Point flags + size += self.points * size_of::(); + if self.has_variations { + // Interpolation buffer for delta IUP + size += self.max_simple_points * size_of::>(); + // Delta buffer for points + size += self.max_simple_points * size_of::>(); + // Delta buffer for composite components + size += self.max_component_delta_stack * size_of::>(); + } + if hinting { + // Hinting value stack + size += self.max_stack * size_of::(); + // CVT and storage area copy-on-write buffers + size += (self.cvt_count + self.storage_count) * size_of::(); + // Twilight zone storage. Two point buffers plus one point flags buffer + size += self.max_twilight_points + * (size_of::>() * 2 + size_of::()); + } + if size != 0 { + // If we're given a buffer that is not aligned, we'll need to + // adjust, so add our maximum alignment requirement in bytes. + size += std::mem::align_of::(); + } + size + } +} + +#[derive(Debug)] +pub struct ScaledOutline<'a, C> +where + C: PointCoord, +{ + pub points: &'a mut [Point], + pub flags: &'a mut [PointFlags], + pub contours: &'a mut [u16], + pub phantom_points: [Point; 4], + pub hdmx_width: Option, +} + +impl<'a, C> ScaledOutline<'a, C> +where + C: PointCoord, +{ + pub(crate) fn new( + points: &'a mut [Point], + phantom_points: [Point; 4], + flags: &'a mut [PointFlags], + contours: &'a mut [u16], + hdmx_width: Option, + ) -> Self { + let x_shift = phantom_points[0].x; + if x_shift != C::zeroed() { + for point in points.iter_mut() { + point.x = point.x - x_shift; + } + } + Self { + points, + flags, + contours, + phantom_points, + hdmx_width, + } + } + + pub fn adjusted_lsb(&self) -> C { + self.phantom_points[0].x + } + + pub fn adjusted_advance_width(&self) -> C { + // Prefer widths from hdmx, otherwise take difference between first + // two phantom points + // + if let Some(hdmx_width) = self.hdmx_width { + C::from_i32(hdmx_width as i32) + } else { + self.phantom_points[1].x - self.phantom_points[0].x + } + } + + pub fn to_path( + &self, + path_style: PathStyle, + pen: &mut impl OutlinePen, + ) -> Result<(), ToPathError> { + to_path(self.points, self.flags, self.contours, path_style, pen) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,599 @@ +//! Support for applying embedded hinting instructions. + +use super::{ + autohint, cff, + glyf::{self, FreeTypeScaler}, + pen::PathStyle, + AdjustedMetrics, DrawError, GlyphStyles, Hinting, LocationRef, NormalizedCoord, + OutlineCollectionKind, OutlineGlyph, OutlineGlyphCollection, OutlineKind, OutlinePen, Size, +}; +use crate::alloc::{boxed::Box, vec::Vec}; + +/// Configuration settings for a hinting instance. +#[derive(Clone, Default, Debug)] +pub struct HintingOptions { + /// Specifies the hinting engine to use. + /// + /// Defaults to [`Engine::AutoFallback`]. + pub engine: Engine, + /// Defines the properties of the intended target of a hinted outline. + /// + /// Defaults to a target with [`SmoothMode::Normal`] which is equivalent + /// to `FT_RENDER_MODE_NORMAL` in FreeType. + pub target: Target, +} + +impl From for HintingOptions { + fn from(value: Target) -> Self { + Self { + engine: Engine::AutoFallback, + target: value, + } + } +} + +/// Specifies the backend to use when applying hints. +#[derive(Clone, Default, Debug)] +pub enum Engine { + /// The TrueType or PostScript interpreter. + Interpreter, + /// The automatic hinter that performs just-in-time adjustment of + /// outlines. + /// + /// Glyph styles can be precomputed per font and may be provided here + /// as an optimization to avoid recomputing them for each instance. + Auto(Option), + /// Selects the engine based on the same rules that FreeType uses when + /// neither of the `FT_LOAD_NO_AUTOHINT` or `FT_LOAD_FORCE_AUTOHINT` + /// load flags are specified. + /// + /// Specifically, PostScript (CFF/CFF2) fonts will always use the hinting + /// engine in the PostScript interpreter and TrueType fonts will use the + /// interpreter for TrueType instructions if one of the `fpgm` or `prep` + /// tables is non-empty, falling back to the automatic hinter otherwise. + /// + /// This uses [`OutlineGlyphCollection::prefer_interpreter`] to make a + /// selection. + #[default] + AutoFallback, +} + +impl Engine { + /// Converts the `AutoFallback` variant into either `Interpreter` or + /// `Auto` based on the given outline set's preference for interpreter + /// mode. + fn resolve_auto_fallback(self, outlines: &OutlineGlyphCollection) -> Engine { + match self { + Self::Interpreter => Self::Interpreter, + Self::Auto(styles) => Self::Auto(styles), + Self::AutoFallback => { + if outlines.prefer_interpreter() { + Self::Interpreter + } else { + Self::Auto(None) + } + } + } + } +} + +impl From for HintingOptions { + fn from(value: Engine) -> Self { + Self { + engine: value, + target: Default::default(), + } + } +} + +/// Defines the target settings for hinting. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Target { + /// Strong hinting style that should only be used for aliased, monochromatic + /// rasterization. + /// + /// Corresponds to `FT_LOAD_TARGET_MONO` in FreeType. + Mono, + /// Hinting style that is suitable for anti-aliased rasterization. + /// + /// Corresponds to the non-monochrome load targets in FreeType. See + /// [`SmoothMode`] for more detail. + Smooth { + /// The basic mode for smooth hinting. + /// + /// Defaults to [`SmoothMode::Normal`]. + mode: SmoothMode, + /// If true, TrueType bytecode may assume that the resulting outline + /// will be rasterized with supersampling in the vertical direction. + /// + /// When this is enabled, ClearType fonts will often generate wider + /// horizontal stems that may lead to blurry images when rendered with + /// an analytical area rasterizer (such as the one in FreeType). + /// + /// The effect of this setting is to control the "ClearType symmetric + /// rendering bit" of the TrueType `GETINFO` instruction. For more + /// detail, see this [issue](https://github.com/googlefonts/fontations/issues/1080). + /// + /// FreeType has no corresponding setting and behaves as if this is + /// always enabled. + /// + /// This only applies to the TrueType interpreter. + /// + /// Defaults to `true`. + symmetric_rendering: bool, + /// If true, prevents adjustment of the outline in the horizontal + /// direction and preserves inter-glyph spacing. + /// + /// This is useful for performing layout without concern that hinting + /// will modify the advance width of a glyph. Specifically, it means + /// that layout will not require evaluation of glyph outlines. + /// + /// FreeType has no corresponding setting and behaves as if this is + /// always disabled. + /// + /// This applies to the TrueType interpreter and the automatic hinter. + /// + /// Defaults to `false`. + preserve_linear_metrics: bool, + }, +} + +impl Default for Target { + fn default() -> Self { + SmoothMode::Normal.into() + } +} + +/// Mode selector for a smooth hinting target. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub enum SmoothMode { + /// The standard smooth hinting mode. + /// + /// Corresponds to `FT_LOAD_TARGET_NORMAL` in FreeType. + #[default] + Normal, + /// Hinting with a lighter touch, typically meaning less aggressive + /// adjustment in the horizontal direction. + /// + /// Corresponds to `FT_LOAD_TARGET_LIGHT` in FreeType. + Light, + /// Hinting that is optimized for subpixel rendering with horizontal LCD + /// layouts. + /// + /// Corresponds to `FT_LOAD_TARGET_LCD` in FreeType. + Lcd, + /// Hinting that is optimized for subpixel rendering with vertical LCD + /// layouts. + /// + /// Corresponds to `FT_LOAD_TARGET_LCD_V` in FreeType. + VerticalLcd, +} + +impl From for Target { + fn from(value: SmoothMode) -> Self { + Self::Smooth { + mode: value, + symmetric_rendering: true, + preserve_linear_metrics: false, + } + } +} + +/// Modes that control hinting when using embedded instructions. +/// +/// Only the TrueType interpreter supports all hinting modes. +/// +/// # FreeType compatibility +/// +/// The following table describes how to map FreeType hinting modes: +/// +/// | FreeType mode | Variant | +/// |-----------------------|--------------------------------------------------------------------------------------| +/// | FT_LOAD_TARGET_MONO | Strong | +/// | FT_LOAD_TARGET_NORMAL | Smooth { lcd_subpixel: None, preserve_linear_metrics: false } | +/// | FT_LOAD_TARGET_LCD | Smooth { lcd_subpixel: Some(LcdLayout::Horizontal), preserve_linear_metrics: false } | +/// | FT_LOAD_TARGET_LCD_V | Smooth { lcd_subpixel: Some(LcdLayout::Vertical), preserve_linear_metrics: false } | +/// +/// Note: `FT_LOAD_TARGET_LIGHT` is equivalent to `FT_LOAD_TARGET_NORMAL` since +/// FreeType 2.7. +/// +/// The default value of this type is equivalent to `FT_LOAD_TARGET_NORMAL`. +#[doc(hidden)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum HintingMode { + /// Strong hinting mode that should only be used for aliased, monochromatic + /// rasterization. + /// + /// Corresponds to `FT_LOAD_TARGET_MONO` in FreeType. + Strong, + /// Lighter hinting mode that is intended for anti-aliased rasterization. + Smooth { + /// If set, enables support for optimized hinting that takes advantage + /// of subpixel layouts in LCD displays and corresponds to + /// `FT_LOAD_TARGET_LCD` or `FT_LOAD_TARGET_LCD_V` in FreeType. + /// + /// If unset, corresponds to `FT_LOAD_TARGET_NORMAL` in FreeType. + lcd_subpixel: Option, + /// If true, prevents adjustment of the outline in the horizontal + /// direction and preserves inter-glyph spacing. + /// + /// This is useful for performing layout without concern that hinting + /// will modify the advance width of a glyph. Specifically, it means + /// that layout will not require evaluation of glyph outlines. + /// + /// FreeType has no corresponding setting. + preserve_linear_metrics: bool, + }, +} + +impl Default for HintingMode { + fn default() -> Self { + Self::Smooth { + lcd_subpixel: None, + preserve_linear_metrics: false, + } + } +} + +impl From for HintingOptions { + fn from(value: HintingMode) -> Self { + let target = match value { + HintingMode::Strong => Target::Mono, + HintingMode::Smooth { + lcd_subpixel, + preserve_linear_metrics, + } => { + let mode = match lcd_subpixel { + Some(LcdLayout::Horizontal) => SmoothMode::Lcd, + Some(LcdLayout::Vertical) => SmoothMode::VerticalLcd, + None => SmoothMode::Normal, + }; + Target::Smooth { + mode, + preserve_linear_metrics, + symmetric_rendering: true, + } + } + }; + target.into() + } +} + +/// Specifies direction of pixel layout for LCD based subpixel hinting. +#[doc(hidden)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum LcdLayout { + /// Subpixels are ordered horizontally. + /// + /// Corresponds to `FT_LOAD_TARGET_LCD` in FreeType. + Horizontal, + /// Subpixels are ordered vertically. + /// + /// Corresponds to `FT_LOAD_TARGET_LCD_V` in FreeType. + Vertical, +} + +/// Hinting instance that uses information embedded in the font to perform +/// grid-fitting. +#[derive(Clone)] +pub struct HintingInstance { + size: Size, + coords: Vec, + target: Target, + kind: HinterKind, +} + +impl HintingInstance { + /// Creates a new embedded hinting instance for the given outline + /// collection, size, location in variation space and hinting mode. + pub fn new<'a>( + outline_glyphs: &OutlineGlyphCollection, + size: Size, + location: impl Into>, + options: impl Into, + ) -> Result { + let options = options.into(); + let mut hinter = Self { + size: Size::unscaled(), + coords: vec![], + target: options.target, + kind: HinterKind::None, + }; + hinter.reconfigure(outline_glyphs, size, location, options)?; + Ok(hinter) + } + + /// Returns the currently configured size. + pub fn size(&self) -> Size { + self.size + } + + /// Returns the currently configured normalized location in variation space. + pub fn location(&self) -> LocationRef { + LocationRef::new(&self.coords) + } + + /// Returns the currently configured hinting target. + pub fn target(&self) -> Target { + self.target + } + + /// Resets the hinter state for a new font instance with the given + /// outline collection and settings. + pub fn reconfigure<'a>( + &mut self, + outlines: &OutlineGlyphCollection, + size: Size, + location: impl Into>, + options: impl Into, + ) -> Result<(), DrawError> { + self.size = size; + self.coords.clear(); + self.coords.extend_from_slice(location.into().coords()); + let options = options.into(); + self.target = options.target; + let engine = options.engine.resolve_auto_fallback(outlines); + // Reuse memory if the font contains the same outline format + let current_kind = core::mem::replace(&mut self.kind, HinterKind::None); + match engine { + Engine::Interpreter => match &outlines.kind { + OutlineCollectionKind::Glyf(glyf) => { + let mut hint_instance = match current_kind { + HinterKind::Glyf(instance) => instance, + _ => Box::::default(), + }; + let ppem = size.ppem(); + let scale = glyf.compute_scale(ppem).1.to_bits(); + hint_instance.reconfigure( + glyf, + scale, + ppem.unwrap_or_default() as i32, + self.target, + &self.coords, + )?; + self.kind = HinterKind::Glyf(hint_instance); + } + OutlineCollectionKind::Cff(cff) => { + let mut subfonts = match current_kind { + HinterKind::Cff(subfonts) => subfonts, + _ => vec![], + }; + subfonts.clear(); + let ppem = size.ppem(); + for i in 0..cff.subfont_count() { + subfonts.push(cff.subfont(i, ppem, &self.coords)?); + } + self.kind = HinterKind::Cff(subfonts); + } + OutlineCollectionKind::None => {} + }, + Engine::Auto(styles) => { + let Some(font) = outlines.font() else { + return Ok(()); + }; + let instance = autohint::Instance::new( + font, + outlines, + &self.coords, + self.target, + styles, + true, + ); + self.kind = HinterKind::Auto(instance); + } + _ => {} + } + Ok(()) + } + + /// Returns true if hinting should actually be applied for this instance. + /// + /// Some TrueType fonts disable hinting dynamically based on the instance + /// configuration. + pub fn is_enabled(&self) -> bool { + match &self.kind { + HinterKind::Glyf(instance) => instance.is_enabled(), + HinterKind::Cff(_) | HinterKind::Auto(_) => true, + _ => false, + } + } + + pub(super) fn draw( + &self, + glyph: &OutlineGlyph, + memory: Option<&mut [u8]>, + path_style: PathStyle, + pen: &mut impl OutlinePen, + is_pedantic: bool, + ) -> Result { + let ppem = self.size.ppem(); + let coords = self.coords.as_slice(); + match (&self.kind, &glyph.kind) { + (HinterKind::Auto(instance), _) => { + instance.draw(self.size, coords, glyph, path_style, pen) + } + (HinterKind::Glyf(instance), OutlineKind::Glyf(glyf, outline)) => { + if matches!(path_style, PathStyle::HarfBuzz) { + return Err(DrawError::HarfBuzzHintingUnsupported); + } + super::with_glyf_memory(outline, Hinting::Embedded, memory, |buf| { + let scaled_outline = FreeTypeScaler::hinted( + glyf, + outline, + buf, + ppem, + coords, + instance, + is_pedantic, + )? + .scale(&outline.glyph, outline.glyph_id)?; + scaled_outline.to_path(path_style, pen)?; + Ok(AdjustedMetrics { + has_overlaps: outline.has_overlaps, + lsb: Some(scaled_outline.adjusted_lsb().to_f32()), + // When hinting is requested, we round the advance + // + advance_width: Some( + scaled_outline.adjusted_advance_width().round().to_f32(), + ), + }) + }) + } + (HinterKind::Cff(subfonts), OutlineKind::Cff(cff, glyph_id, subfont_ix)) => { + let Some(subfont) = subfonts.get(*subfont_ix as usize) else { + return Err(DrawError::NoSources); + }; + cff.draw(subfont, *glyph_id, &self.coords, true, pen)?; + Ok(AdjustedMetrics::default()) + } + _ => Err(DrawError::NoSources), + } + } +} + +#[derive(Clone)] +enum HinterKind { + /// Represents a hinting instance that is associated with an empty outline + /// collection. + None, + Glyf(Box), + Cff(Vec), + Auto(autohint::Instance), +} + +// Internal helpers for deriving various flags from the mode which +// change the behavior of certain instructions. +// See +impl Target { + pub(crate) fn is_smooth(&self) -> bool { + matches!(self, Self::Smooth { .. }) + } + + pub(crate) fn is_grayscale_cleartype(&self) -> bool { + match self { + Self::Smooth { mode, .. } => matches!(mode, SmoothMode::Normal | SmoothMode::Light), + _ => false, + } + } + + pub(crate) fn is_light(&self) -> bool { + matches!( + self, + Self::Smooth { + mode: SmoothMode::Light, + .. + } + ) + } + + pub(crate) fn is_lcd(&self) -> bool { + matches!( + self, + Self::Smooth { + mode: SmoothMode::Lcd, + .. + } + ) + } + + pub(crate) fn is_vertical_lcd(&self) -> bool { + matches!( + self, + Self::Smooth { + mode: SmoothMode::VerticalLcd, + .. + } + ) + } + + pub(crate) fn symmetric_rendering(&self) -> bool { + matches!( + self, + Self::Smooth { + symmetric_rendering: true, + .. + } + ) + } + + pub(crate) fn preserve_linear_metrics(&self) -> bool { + matches!( + self, + Self::Smooth { + preserve_linear_metrics: true, + .. + } + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{ + outline::{pen::NullPen, DrawSettings}, + raw::TableProvider, + FontRef, MetadataProvider, + }; + + // FreeType ignores the hdmx table when backward compatibility mode + // is enabled in the TrueType interpreter. + #[test] + fn ignore_hdmx_when_back_compat_enabled() { + let font = FontRef::new(font_test_data::TINOS_SUBSET).unwrap(); + let outlines = font.outline_glyphs(); + // Double quote was the most egregious failure + let gid = font.charmap().map('"').unwrap(); + let font_size = 16; + let hinter = HintingInstance::new( + &outlines, + Size::new(font_size as f32), + LocationRef::default(), + HintingOptions::default(), + ) + .unwrap(); + let HinterKind::Glyf(tt_hinter) = &hinter.kind else { + panic!("this is definitely a TrueType hinter"); + }; + // Make sure backward compatibility mode is enabled + assert!(tt_hinter.backward_compatibility()); + let outline = outlines.get(gid).unwrap(); + let metrics = outline.draw(&hinter, &mut NullPen).unwrap(); + // FreeType computes an advance width of 7 when hinting but hdmx contains 5 + let scaler_advance = metrics.advance_width.unwrap(); + assert_eq!(scaler_advance, 7.0); + let hdmx_advance = font + .hdmx() + .unwrap() + .record_for_size(font_size) + .unwrap() + .widths()[gid.to_u32() as usize]; + assert_eq!(hdmx_advance, 5); + } + + // When hinting is disabled by the prep table, FreeType still returns + // rounded advance widths + #[test] + fn round_advance_when_prep_disables_hinting() { + let font = FontRef::new(font_test_data::TINOS_SUBSET).unwrap(); + let outlines = font.outline_glyphs(); + let gid = font.charmap().map('"').unwrap(); + let size = Size::new(16.0); + let location = LocationRef::default(); + let mut hinter = + HintingInstance::new(&outlines, size, location, HintingOptions::default()).unwrap(); + let HinterKind::Glyf(tt_hinter) = &mut hinter.kind else { + panic!("this is definitely a TrueType hinter"); + }; + tt_hinter.simulate_prep_flag_suppress_hinting(); + let outline = outlines.get(gid).unwrap(); + // And we still have a rounded advance + let metrics = outline.draw(&hinter, &mut NullPen).unwrap(); + assert_eq!(metrics.advance_width, Some(7.0)); + // Unhinted advance has some fractional bits + let metrics = outline + .draw(DrawSettings::unhinted(size, location), &mut NullPen) + .unwrap(); + assert_eq!(metrics.advance_width, Some(6.53125)); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,374 @@ +//! Name detection for fonts that require hinting to be run for correct +//! contours (FreeType calls these "tricky" fonts). + +use crate::{string::StringId, FontRef, MetadataProvider, Tag}; + +pub(super) fn require_interpreter(font: &FontRef) -> bool { + is_hint_reliant_by_name(font) || matches_hint_reliant_id_list(FontId::from_font(font)) +} + +fn is_hint_reliant_by_name(font: &FontRef) -> bool { + font.localized_strings(StringId::FAMILY_NAME) + .english_or_first() + .map(|name| { + let mut buf = [0u8; MAX_HINT_RELIANT_NAME_LEN]; + let mut len = 0; + let mut chars = name.chars(); + for ch in chars.by_ref().take(MAX_HINT_RELIANT_NAME_LEN) { + buf[len] = ch as u8; + len += 1; + } + if chars.next().is_some() { + return false; + } + matches_hint_reliant_name_list(core::str::from_utf8(&buf[..len]).unwrap_or_default()) + }) + .unwrap_or_default() +} + +/// Is this name on the list of fonts that require hinting? +/// +/// +fn matches_hint_reliant_name_list(name: &str) -> bool { + let name = skip_pdf_random_tag(name); + HINT_RELIANT_NAMES + .iter() + // FreeType uses strstr(name, tricky_name) so we use contains() to + // match behavior. + .any(|tricky_name| name.contains(*tricky_name)) +} + +/// Fonts embedded in PDFs add random prefixes. Strip these +/// for tricky font comparison purposes. +/// +/// +fn skip_pdf_random_tag(name: &str) -> &str { + let bytes = name.as_bytes(); + // Random tag is 6 uppercase letters followed by a + + if bytes.len() < 8 || bytes[6] != b'+' || !bytes.iter().take(6).all(|b| b.is_ascii_uppercase()) + { + return name; + } + core::str::from_utf8(&bytes[7..]).unwrap_or(name) +} + +/// +#[rustfmt::skip] +const HINT_RELIANT_NAMES: &[&str] = &[ + "cpop", /* dftt-p7.ttf; version 1.00, 1992 [DLJGyShoMedium] */ + "DFGirl-W6-WIN-BF", /* dftt-h6.ttf; version 1.00, 1993 */ + "DFGothic-EB", /* DynaLab Inc. 1992-1995 */ + "DFGyoSho-Lt", /* DynaLab Inc. 1992-1995 */ + "DFHei", /* DynaLab Inc. 1992-1995 [DFHei-Bd-WIN-HK-BF] */ + /* covers "DFHei-Md-HK-BF", maybe DynaLab Inc. */ + + "DFHSGothic-W5", /* DynaLab Inc. 1992-1995 */ + "DFHSMincho-W3", /* DynaLab Inc. 1992-1995 */ + "DFHSMincho-W7", /* DynaLab Inc. 1992-1995 */ + "DFKaiSho-SB", /* dfkaisb.ttf */ + "DFKaiShu", /* covers "DFKaiShu-Md-HK-BF", maybe DynaLab Inc. */ + "DFKai-SB", /* kaiu.ttf; version 3.00, 1998 [DFKaiShu-SB-Estd-BF] */ + + "DFMing", /* DynaLab Inc. 1992-1995 [DFMing-Md-WIN-HK-BF] */ + /* covers "DFMing-Bd-HK-BF", maybe DynaLab Inc. */ + + "DLC", /* dftt-m7.ttf; version 1.00, 1993 [DLCMingBold] */ + /* dftt-f5.ttf; version 1.00, 1993 [DLCFongSung] */ + /* covers following */ + /* "DLCHayMedium", dftt-b5.ttf; version 1.00, 1993 */ + /* "DLCHayBold", dftt-b7.ttf; version 1.00, 1993 */ + /* "DLCKaiMedium", dftt-k5.ttf; version 1.00, 1992 */ + /* "DLCLiShu", dftt-l5.ttf; version 1.00, 1992 */ + /* "DLCRoundBold", dftt-r7.ttf; version 1.00, 1993 */ + + "HuaTianKaiTi?", /* htkt2.ttf */ + "HuaTianSongTi?", /* htst3.ttf */ + "Ming(for ISO10646)", /* hkscsiic.ttf; version 0.12, 2007 [Ming] */ + /* iicore.ttf; version 0.07, 2007 [Ming] */ + "MingLiU", /* mingliu.ttf */ + /* mingliu.ttc; version 3.21, 2001 */ + "MingMedium", /* dftt-m5.ttf; version 1.00, 1993 [DLCMingMedium] */ + "PMingLiU", /* mingliu.ttc; version 3.21, 2001 */ + "MingLi43", /* mingli.ttf; version 1.00, 1992 */ +]; + +const MAX_HINT_RELIANT_NAME_LEN: usize = 18; + +#[derive(Copy, Clone, PartialEq, Default, Debug)] +struct TableId { + checksum: u32, + len: u32, +} + +impl TableId { + fn from_font_and_tag(font: &FontRef, tag: Tag) -> Option { + let data = font.table_data(tag)?; + Some(Self { + // Note: FreeType always just computes the checksum + // + checksum: raw::tables::compute_checksum(data.as_bytes()), + len: data.len() as u32, + }) + } +} + +#[derive(Copy, Clone, PartialEq, Default, Debug)] +struct FontId { + cvt: TableId, + fpgm: TableId, + prep: TableId, +} + +impl FontId { + fn from_font(font: &FontRef) -> Self { + Self { + cvt: TableId::from_font_and_tag(font, Tag::new(b"cvt ")).unwrap_or_default(), + fpgm: TableId::from_font_and_tag(font, Tag::new(b"fpgm")).unwrap_or_default(), + prep: TableId::from_font_and_tag(font, Tag::new(b"prep")).unwrap_or_default(), + } + } +} + +/// Checks for fonts that require hinting based on the length and checksum of +/// the cvt, fpgm and prep tables. +/// +/// Roughly equivalent to +fn matches_hint_reliant_id_list(font_id: FontId) -> bool { + HINT_RELIANT_IDS.contains(&font_id) +} + +/// +#[rustfmt::skip] +const HINT_RELIANT_IDS: &[FontId] = &[ + // MingLiU 1995 + FontId { + cvt: TableId { checksum: 0x05BCF058, len: 0x000002E4 }, + fpgm: TableId { checksum: 0x28233BF1, len: 0x000087C4 }, + prep: TableId { checksum: 0xA344A1EA, len: 0x000001E1 }, + }, + // MingLiU 1996- + FontId { + cvt: TableId { checksum: 0x05BCF058, len: 0x000002E4 }, + fpgm: TableId { checksum: 0x28233BF1, len: 0x000087C4 }, + prep: TableId { checksum: 0xA344A1EB, len: 0x000001E1 }, + }, + // DFGothic-EB + FontId { + cvt: TableId { checksum: 0x12C3EBB2, len: 0x00000350 }, + fpgm: TableId { checksum: 0xB680EE64, len: 0x000087A7 }, + prep: TableId { checksum: 0xCE939563, len: 0x00000758 }, + }, + // DFGyoSho-Lt + FontId { + cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, + fpgm: TableId { checksum: 0xCE5956E9, len: 0x0000BC85 }, + prep: TableId { checksum: 0x8272F416, len: 0x00000045 }, + }, + // DFHei-Md-HK-BF + FontId { + cvt: TableId { checksum: 0x1257EB46, len: 0x00000350 }, + fpgm: TableId { checksum: 0xF699D160, len: 0x0000715F }, + prep: TableId { checksum: 0xD222F568, len: 0x000003BC }, + }, + // DFHSGothic-W5 + FontId { + cvt: TableId { checksum: 0x1262EB4E, len: 0x00000350 }, + fpgm: TableId { checksum: 0xE86A5D64, len: 0x00007940 }, + prep: TableId { checksum: 0x7850F729, len: 0x000005FF }, + }, + // DFHSMincho-W3 + FontId { + cvt: TableId { checksum: 0x122DEB0A, len: 0x00000350 }, + fpgm: TableId { checksum: 0x3D16328A, len: 0x0000859B }, + prep: TableId { checksum: 0xA93FC33B, len: 0x000002CB }, + }, + // DFHSMincho-W7 + FontId { + cvt: TableId { checksum: 0x125FEB26, len: 0x00000350 }, + fpgm: TableId { checksum: 0xA5ACC982, len: 0x00007EE1 }, + prep: TableId { checksum: 0x90999196, len: 0x0000041F }, + }, + // DFKaiShu + FontId { + cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, + fpgm: TableId { checksum: 0x5A30CA3B, len: 0x00009063 }, + prep: TableId { checksum: 0x13A42602, len: 0x0000007E }, + }, + // DFKaiShu, variant + FontId { + cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000350 }, + fpgm: TableId { checksum: 0xA6E78C01, len: 0x00008998 }, + prep: TableId { checksum: 0x13A42602, len: 0x0000007E }, + }, + // DFKaiShu-Md-HK-BF + FontId { + cvt: TableId { checksum: 0x11E5EAD4, len: 0x00000360 }, + fpgm: TableId { checksum: 0x9DB282B2, len: 0x0000C06E }, + prep: TableId { checksum: 0x53E6D7CA, len: 0x00000082 }, + }, + // DFMing-Bd-HK-BF + FontId { + cvt: TableId { checksum: 0x1243EB18, len: 0x00000350 }, + fpgm: TableId { checksum: 0xBA0A8C30, len: 0x000074AD }, + prep: TableId { checksum: 0xF3D83409, len: 0x0000037B }, + }, + // DLCLiShu + FontId { + cvt: TableId { checksum: 0x07DCF546, len: 0x00000308 }, + fpgm: TableId { checksum: 0x40FE7C90, len: 0x00008E2A }, + prep: TableId { checksum: 0x608174B5, len: 0x0000007A }, + }, + // DLCHayBold + FontId { + cvt: TableId { checksum: 0xEB891238, len: 0x00000308 }, + fpgm: TableId { checksum: 0xD2E4DCD4, len: 0x0000676F }, + prep: TableId { checksum: 0x8EA5F293, len: 0x000003B8 }, + }, + // HuaTianKaiTi + FontId { + cvt: TableId { checksum: 0xFFFBFFFC, len: 0x00000008 }, + fpgm: TableId { checksum: 0x9C9E48B8, len: 0x0000BEA2 }, + prep: TableId { checksum: 0x70020112, len: 0x00000008 }, + }, + // HuaTianSongTi + FontId { + cvt: TableId { checksum: 0xFFFBFFFC, len: 0x00000008 }, + fpgm: TableId { checksum: 0x0A5A0483, len: 0x00017C39 }, + prep: TableId { checksum: 0x70020112, len: 0x00000008 }, + }, + // NEC fadpop7.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x40C92555, len: 0x000000E5 }, + prep: TableId { checksum: 0xA39B58E3, len: 0x0000117C }, + }, + // NEC fadrei5.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x33C41652, len: 0x000000E5 }, + prep: TableId { checksum: 0x26D6C52A, len: 0x00000F6A }, + }, + // NEC fangot7.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x6DB1651D, len: 0x0000019D }, + prep: TableId { checksum: 0x6C6E4B03, len: 0x00002492 }, + }, + // NEC fangyo5.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x40C92555, len: 0x000000E5 }, + prep: TableId { checksum: 0xDE51FAD0, len: 0x0000117C }, + }, + // NEC fankyo5.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x85E47664, len: 0x000000E5 }, + prep: TableId { checksum: 0xA6C62831, len: 0x00001CAA }, + }, + // NEC fanrgo5.ttf + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x2D891CFD, len: 0x0000019D }, + prep: TableId { checksum: 0xA0604633, len: 0x00001DE8 }, + }, + // NEC fangot5.ttc + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x40AA774C, len: 0x000001CB }, + prep: TableId { checksum: 0x9B5CAA96, len: 0x00001F9A }, + }, + // NEC fanmin3.ttc + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x0D3DE9CB, len: 0x00000141 }, + prep: TableId { checksum: 0xD4127766, len: 0x00002280 }, + }, + // NEC FA-Gothic, 1996 + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x4A692698, len: 0x000001F0 }, + prep: TableId { checksum: 0x340D4346, len: 0x00001FCA }, + }, + // NEC FA-Minchou, 1996 + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0xCD34C604, len: 0x00000166 }, + prep: TableId { checksum: 0x6CF31046, len: 0x000022B0 }, + }, + // NEC FA-RoundGothicB, 1996 + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0x5DA75315, len: 0x0000019D }, + prep: TableId { checksum: 0x40745A5F, len: 0x000022E0 }, + }, + // NEC FA-RoundGothicM, 1996 + FontId { + cvt: TableId { checksum: 0x00000000, len: 0x00000000 }, + fpgm: TableId { checksum: 0xF055FC48, len: 0x000001C2 }, + prep: TableId { checksum: 0x3900DED3, len: 0x00001E18 }, + }, + // MINGLI.TTF, 1992 + FontId { + cvt: TableId { checksum: 0x00170003, len: 0x00000060 }, + fpgm: TableId { checksum: 0xDBB4306E, len: 0x000058AA }, + prep: TableId { checksum: 0xD643482A, len: 0x00000035 }, + }, + // DFHei-Bd-WIN-HK-BF, issue #1087 + FontId { + cvt: TableId { checksum: 0x1269EB58, len: 0x00000350 }, + fpgm: TableId { checksum: 0x5CD5957A, len: 0x00006A4E }, + prep: TableId { checksum: 0xF758323A, len: 0x00000380 }, + }, + // DFMing-Md-WIN-HK-BF, issue #1087 + FontId { + cvt: TableId { checksum: 0x122FEB0B, len: 0x00000350 }, + fpgm: TableId { checksum: 0x7F10919A, len: 0x000070A9 }, + prep: TableId { checksum: 0x7CD7E7B7, len: 0x0000025C }, + }, +]; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn ensure_max_name_len() { + let max_len = HINT_RELIANT_NAMES + .iter() + .fold(0, |acc, name| acc.max(name.len())); + assert_eq!(max_len, MAX_HINT_RELIANT_NAME_LEN); + } + + #[test] + fn skip_pdf_tags() { + // length must be at least 8 + assert_eq!(skip_pdf_random_tag("ABCDEF+"), "ABCDEF+"); + // first six chars must be ascii uppercase + assert_eq!(skip_pdf_random_tag("AbCdEF+Arial"), "AbCdEF+Arial"); + // no numbers + assert_eq!(skip_pdf_random_tag("Ab12EF+Arial"), "Ab12EF+Arial"); + // missing + + assert_eq!(skip_pdf_random_tag("ABCDEFArial"), "ABCDEFArial"); + // too long + assert_eq!(skip_pdf_random_tag("ABCDEFG+Arial"), "ABCDEFG+Arial"); + // too short + assert_eq!(skip_pdf_random_tag("ABCDE+Arial"), "ABCDE+Arial"); + // just right + assert_eq!(skip_pdf_random_tag("ABCDEF+Arial"), "Arial"); + } + + #[test] + fn all_hint_reliant_names() { + for name in HINT_RELIANT_NAMES { + assert!(matches_hint_reliant_name_list(name)); + } + } + + #[test] + fn non_hint_reliant_names() { + for not_tricky in ["Roboto", "Arial", "Helvetica", "Blah", ""] { + assert!(!matches_hint_reliant_name_list(not_tricky)); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,25 @@ +//! Support for temporary memory allocation, making use of the stack for +//! small sizes. + +/// Invokes the callback with a memory buffer of the requested size. +pub(super) fn with_temporary_memory(size: usize, mut f: impl FnMut(&mut [u8]) -> R) -> R { + // Wrap in a function and prevent inlining to avoid stack allocation + // and zeroing if we don't take this code path. + #[inline(never)] + fn stack_mem(size: usize, mut f: impl FnMut(&mut [u8]) -> R) -> R { + f(&mut [0u8; STACK_SIZE][..size]) + } + // Use bucketed stack allocations to prevent excessive zeroing of + // memory + if size <= 512 { + stack_mem::<512, _>(size, f) + } else if size <= 1024 { + stack_mem::<1024, _>(size, f) + } else if size <= 2048 { + stack_mem::<2048, _>(size, f) + } else if size <= 4096 { + stack_mem::<4096, _>(size, f) + } else { + f(&mut vec![0u8; size]) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,51 @@ +//! Helper for loading (possibly variable) horizontal glyph metrics. + +use raw::{ + tables::{hmtx::Hmtx, hvar::Hvar}, + types::{F2Dot14, GlyphId}, + FontRef, TableProvider, +}; + +/// Access to horizontal glyph metrics. +#[derive(Clone)] +pub(crate) struct GlyphHMetrics<'a> { + pub hmtx: Hmtx<'a>, + pub hvar: Option>, +} + +impl<'a> GlyphHMetrics<'a> { + pub fn new(font: &FontRef<'a>) -> Option { + // Note: hmtx is required and HVAR is optional + let hmtx = font.hmtx().ok()?; + let hvar = font.hvar().ok(); + Some(Self { hmtx, hvar }) + } + + /// Returns the advance width (in font units) for the given glyph and + /// the location in variation space represented by the set of normalized + /// coordinates in 2.14 fixed point. + pub fn advance_width(&self, gid: GlyphId, coords: &'a [F2Dot14]) -> i32 { + let mut advance = self.hmtx.advance(gid).unwrap_or_default() as i32; + if let Some(hvar) = &self.hvar { + advance += hvar + .advance_width_delta(gid, coords) + .map(|delta| delta.to_i32()) + .unwrap_or(0); + } + advance + } + + /// Returns the left side bearing (in font units) for the given glyph and + /// the location in variation space represented by the set of normalized + /// coordinates in 2.14 fixed point. + pub fn lsb(&self, gid: GlyphId, coords: &'a [F2Dot14]) -> i32 { + let mut lsb = self.hmtx.side_bearing(gid).unwrap_or_default() as i32; + if let Some(hvar) = &self.hvar { + lsb += hvar + .lsb_delta(gid, coords) + .map(|delta| delta.to_i32()) + .unwrap_or(0); + } + lsb + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,1445 @@ +//! Loading, scaling and hinting of glyph outlines. +//! +//! This module provides support for retrieving (optionally scaled and hinted) +//! glyph outlines in the form of vector paths. +//! +//! # Drawing a glyph +//! +//! Generating SVG [path commands](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#path_commands) +//! for a character (this assumes a local variable `font` of type [`FontRef`]): +//! +//! ```rust +//! use skrifa::{ +//! instance::{LocationRef, Size}, +//! outline::{DrawSettings, OutlinePen}, +//! FontRef, MetadataProvider, +//! }; +//! +//! # fn wrapper(font: FontRef) { +//! // First, grab the set of outline glyphs from the font. +//! let outlines = font.outline_glyphs(); +//! +//! // Find the glyph identifier for our character. +//! let glyph_id = font.charmap().map('Q').unwrap(); +//! +//! // Grab the outline glyph. +//! let glyph = outlines.get(glyph_id).unwrap(); +//! +//! // Define how we want the glyph to be drawn. This creates +//! // settings for an instance without hinting at a size of +//! // 16px with no variations applied. +//! let settings = DrawSettings::unhinted(Size::new(16.0), LocationRef::default()); +//! +//! // Alternatively, we can apply variations like so: +//! let var_location = font.axes().location(&[("wght", 650.0), ("wdth", 100.0)]); +//! let settings = DrawSettings::unhinted(Size::new(16.0), &var_location); +//! +//! // At this point, we need a "sink" to receive the resulting path. This +//! // is done by creating an implementation of the OutlinePen trait. +//! +//! // Let's make one that generates SVG path data. +//! #[derive(Default)] +//! struct SvgPath(String); +//! +//! // Implement the OutlinePen trait for this type. This emits the appropriate +//! // SVG path commands for each element type. +//! impl OutlinePen for SvgPath { +//! fn move_to(&mut self, x: f32, y: f32) { +//! self.0.push_str(&format!("M{x:.1},{y:.1} ")); +//! } +//! +//! fn line_to(&mut self, x: f32, y: f32) { +//! self.0.push_str(&format!("L{x:.1},{y:.1} ")); +//! } +//! +//! fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { +//! self.0 +//! .push_str(&format!("Q{cx0:.1},{cy0:.1} {x:.1},{y:.1} ")); +//! } +//! +//! fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { +//! self.0.push_str(&format!( +//! "C{cx0:.1},{cy0:.1} {cx1:.1},{cy1:.1} {x:.1},{y:.1} " +//! )); +//! } +//! +//! fn close(&mut self) { +//! self.0.push_str("Z "); +//! } +//! } +//! // Now, construct an instance of our pen. +//! let mut svg_path = SvgPath::default(); +//! +//! // And draw the glyph! +//! glyph.draw(settings, &mut svg_path).unwrap(); +//! +//! // See what we've drawn. +//! println!("{}", svg_path.0); +//! # } +//! ``` + +mod autohint; +mod cff; +mod glyf; +mod hint; +mod hint_reliant; +mod memory; +mod metrics; +mod path; +mod unscaled; + +#[cfg(test)] +mod testing; + +pub mod error; +pub mod pen; + +pub use autohint::GlyphStyles; +pub use hint::{ + Engine, HintingInstance, HintingMode, HintingOptions, LcdLayout, SmoothMode, Target, +}; +use metrics::GlyphHMetrics; +use raw::FontRef; +#[doc(inline)] +pub use {error::DrawError, pen::OutlinePen}; + +use self::glyf::{FreeTypeScaler, HarfBuzzScaler}; +use super::{ + instance::{LocationRef, NormalizedCoord, Size}, + GLYF_COMPOSITE_RECURSION_LIMIT, +}; +use core::fmt::Debug; +use pen::PathStyle; +use read_fonts::{types::GlyphId, TableProvider}; + +#[cfg(feature = "libm")] +#[allow(unused_imports)] +use core_maths::CoreFloat; + +/// Source format for an outline glyph. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum OutlineGlyphFormat { + /// TrueType outlines sourced from the `glyf` table. + Glyf, + /// PostScript outlines sourced from the `CFF` table. + Cff, + /// PostScript outlines sourced from the `CFF2` table. + Cff2, +} + +/// Specifies the hinting strategy for memory size calculations. +#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] +pub enum Hinting { + /// Hinting is disabled. + #[default] + None, + /// Application of hints that are embedded in the font. + /// + /// For TrueType, these are bytecode instructions associated with each + /// glyph outline. For PostScript (CFF/CFF2), these are stem hints + /// encoded in the character string. + Embedded, +} + +/// Information and adjusted metrics generated while drawing an outline glyph. +/// +/// When applying hints to a TrueType glyph, the outline may be shifted in +/// the horizontal direction, affecting the left side bearing and advance width +/// of the glyph. This captures those metrics. +#[derive(Copy, Clone, Default, Debug)] +pub struct AdjustedMetrics { + /// True if the underlying glyph contains flags indicating the + /// presence of overlapping contours or components. + pub has_overlaps: bool, + /// If present, an adjusted left side bearing value generated by the + /// scaler. + /// + /// This is equivalent to the `horiBearingX` value in + /// [`FT_Glyph_Metrics`](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_glyph_metrics). + pub lsb: Option, + /// If present, an adjusted advance width value generated by the + /// scaler. + /// + /// This is equivalent to the `advance.x` value in + /// [`FT_GlyphSlotRec`](https://freetype.org/freetype2/docs/reference/ft2-glyph_retrieval.html#ft_glyphslotrec). + pub advance_width: Option, +} + +/// Options that define how a [glyph](OutlineGlyph) is drawn to a +/// [pen](OutlinePen). +pub struct DrawSettings<'a> { + instance: DrawInstance<'a>, + memory: Option<&'a mut [u8]>, + path_style: PathStyle, +} + +impl<'a> DrawSettings<'a> { + /// Creates settings for an unhinted draw operation with the given size and + /// location in variation space. + pub fn unhinted(size: Size, location: impl Into>) -> Self { + Self { + instance: DrawInstance::Unhinted(size, location.into()), + memory: None, + path_style: PathStyle::default(), + } + } + + /// Creates settings for a hinted draw operation using hinting data + /// contained in the font. + /// + /// If `is_pedantic` is true then any error that occurs during hinting will + /// cause drawing to fail. This is equivalent to the `FT_LOAD_PEDANTIC` flag + /// in FreeType. + /// + /// The font size, location in variation space and hinting mode are + /// defined by the current configuration of the given hinting instance. + pub fn hinted(instance: &'a HintingInstance, is_pedantic: bool) -> Self { + Self { + instance: DrawInstance::Hinted { + instance, + is_pedantic, + }, + memory: None, + path_style: PathStyle::default(), + } + } + + /// Builder method to associate a user memory buffer to be used for + /// temporary allocations during drawing. + /// + /// The required size of this buffer can be computed using the + /// [`OutlineGlyph::draw_memory_size`] method. + /// + /// If not provided, any necessary memory will be allocated internally. + pub fn with_memory(mut self, memory: Option<&'a mut [u8]>) -> Self { + self.memory = memory; + self + } + + /// Builder method to control nuances of [`glyf`](https://learn.microsoft.com/en-us/typography/opentype/spec/glyf) pointstream interpretation. + /// + /// Meant for use when trying to match legacy code behavior in Rust. + pub fn with_path_style(mut self, path_style: PathStyle) -> Self { + self.path_style = path_style; + self + } +} + +enum DrawInstance<'a> { + Unhinted(Size, LocationRef<'a>), + Hinted { + instance: &'a HintingInstance, + is_pedantic: bool, + }, +} + +impl<'a, L> From<(Size, L)> for DrawSettings<'a> +where + L: Into>, +{ + fn from(value: (Size, L)) -> Self { + DrawSettings::unhinted(value.0, value.1.into()) + } +} + +impl From for DrawSettings<'_> { + fn from(value: Size) -> Self { + DrawSettings::unhinted(value, LocationRef::default()) + } +} + +impl<'a> From<&'a HintingInstance> for DrawSettings<'a> { + fn from(value: &'a HintingInstance) -> Self { + DrawSettings::hinted(value, false) + } +} + +/// A scalable glyph outline. +/// +/// This can be sourced from the [`glyf`](https://learn.microsoft.com/en-us/typography/opentype/spec/glyf), +/// [`CFF`](https://learn.microsoft.com/en-us/typography/opentype/spec/cff) or +/// [`CFF2`](https://learn.microsoft.com/en-us/typography/opentype/spec/cff2) +/// tables. Use the [`format`](OutlineGlyph::format) method to determine which +/// was chosen for this glyph. +#[derive(Clone)] +pub struct OutlineGlyph<'a> { + kind: OutlineKind<'a>, +} + +impl<'a> OutlineGlyph<'a> { + /// Returns the underlying source format for this outline. + pub fn format(&self) -> OutlineGlyphFormat { + match &self.kind { + OutlineKind::Glyf(..) => OutlineGlyphFormat::Glyf, + OutlineKind::Cff(cff, ..) => { + if cff.is_cff2() { + OutlineGlyphFormat::Cff2 + } else { + OutlineGlyphFormat::Cff + } + } + } + } + + /// Returns the glyph identifier for this outline. + pub fn glyph_id(&self) -> GlyphId { + match &self.kind { + OutlineKind::Glyf(_, glyph) => glyph.glyph_id, + OutlineKind::Cff(_, gid, _) => *gid, + } + } + + /// Returns a value indicating if the outline may contain overlapping + /// contours or components. + /// + /// For CFF outlines, returns `None` since this information is unavailable. + pub fn has_overlaps(&self) -> Option { + match &self.kind { + OutlineKind::Glyf(_, outline) => Some(outline.has_overlaps), + _ => None, + } + } + + /// Returns a value indicating whether the outline has hinting + /// instructions. + /// + /// For CFF outlines, returns `None` since this is unknown prior + /// to loading the outline. + pub fn has_hinting(&self) -> Option { + match &self.kind { + OutlineKind::Glyf(_, outline) => Some(outline.has_hinting), + _ => None, + } + } + + /// Returns the size (in bytes) of the temporary memory required to draw + /// this outline. + /// + /// This is used to compute the size of the memory buffer required for the + /// [`DrawSettings::with_memory`] method. + /// + /// The `hinting` parameter determines which hinting method, if any, will + /// be used for drawing which has an effect on memory requirements. + /// + /// The appropriate hinting types are as follows: + /// + /// | For draw settings | Use hinting | + /// |------------------------------------|-----------------------| + /// | [`DrawSettings::unhinted`] | [`Hinting::None`] | + /// | [`DrawSettings::hinted`] | [`Hinting::Embedded`] | + pub fn draw_memory_size(&self, hinting: Hinting) -> usize { + match &self.kind { + OutlineKind::Glyf(_, outline) => outline.required_buffer_size(hinting), + _ => 0, + } + } + + /// Draws the outline glyph with the given settings and emits the resulting + /// path commands to the specified pen. + pub fn draw<'s>( + &self, + settings: impl Into>, + pen: &mut impl OutlinePen, + ) -> Result { + let settings: DrawSettings<'a> = settings.into(); + match (settings.instance, settings.path_style) { + (DrawInstance::Unhinted(size, location), PathStyle::FreeType) => { + self.draw_unhinted(size, location, settings.memory, settings.path_style, pen) + } + (DrawInstance::Unhinted(size, location), PathStyle::HarfBuzz) => { + self.draw_unhinted(size, location, settings.memory, settings.path_style, pen) + } + ( + DrawInstance::Hinted { + instance: hinting_instance, + is_pedantic, + }, + PathStyle::FreeType, + ) => { + if hinting_instance.is_enabled() { + hinting_instance.draw( + self, + settings.memory, + settings.path_style, + pen, + is_pedantic, + ) + } else { + let mut metrics = self.draw_unhinted( + hinting_instance.size(), + hinting_instance.location(), + settings.memory, + settings.path_style, + pen, + )?; + // Round advance width when hinting is requested, even if + // the instance is disabled. + if let Some(advance) = metrics.advance_width.as_mut() { + *advance = advance.round(); + } + Ok(metrics) + } + } + (DrawInstance::Hinted { .. }, PathStyle::HarfBuzz) => { + Err(DrawError::HarfBuzzHintingUnsupported) + } + } + } + + fn draw_unhinted( + &self, + size: Size, + location: impl Into>, + user_memory: Option<&mut [u8]>, + path_style: PathStyle, + pen: &mut impl OutlinePen, + ) -> Result { + let ppem = size.ppem(); + let coords = location.into().coords(); + match &self.kind { + OutlineKind::Glyf(glyf, outline) => { + with_glyf_memory(outline, Hinting::None, user_memory, |buf| { + let (lsb, advance_width) = match path_style { + PathStyle::FreeType => { + let scaled_outline = + FreeTypeScaler::unhinted(glyf, outline, buf, ppem, coords)? + .scale(&outline.glyph, outline.glyph_id)?; + scaled_outline.to_path(path_style, pen)?; + ( + scaled_outline.adjusted_lsb().to_f32(), + scaled_outline.adjusted_advance_width().to_f32(), + ) + } + PathStyle::HarfBuzz => { + let scaled_outline = + HarfBuzzScaler::unhinted(glyf, outline, buf, ppem, coords)? + .scale(&outline.glyph, outline.glyph_id)?; + scaled_outline.to_path(path_style, pen)?; + ( + scaled_outline.adjusted_lsb(), + scaled_outline.adjusted_advance_width(), + ) + } + }; + + Ok(AdjustedMetrics { + has_overlaps: outline.has_overlaps, + lsb: Some(lsb), + advance_width: Some(advance_width), + }) + }) + } + OutlineKind::Cff(cff, glyph_id, subfont_ix) => { + let subfont = cff.subfont(*subfont_ix, ppem, coords)?; + cff.draw(&subfont, *glyph_id, coords, false, pen)?; + Ok(AdjustedMetrics::default()) + } + } + } + + /// Internal drawing API for autohinting that offers unified compact + /// storage for unscaled outlines. + #[allow(dead_code)] + fn draw_unscaled( + &self, + location: impl Into>, + user_memory: Option<&mut [u8]>, + sink: &mut impl unscaled::UnscaledOutlineSink, + ) -> Result { + let coords = location.into().coords(); + let ppem = None; + match &self.kind { + OutlineKind::Glyf(glyf, outline) => { + with_glyf_memory(outline, Hinting::None, user_memory, |buf| { + let outline = FreeTypeScaler::unhinted(glyf, outline, buf, ppem, coords)? + .scale(&outline.glyph, outline.glyph_id)?; + sink.try_reserve(outline.points.len())?; + let mut contour_start = 0; + for contour_end in outline.contours.iter().map(|contour| *contour as usize) { + if contour_end >= contour_start { + if let Some(points) = outline.points.get(contour_start..=contour_end) { + let flags = &outline.flags[contour_start..=contour_end]; + sink.extend(points.iter().zip(flags).enumerate().map( + |(ix, (point, flags))| { + unscaled::UnscaledPoint::from_glyf_point( + *point, + *flags, + ix == 0, + ) + }, + ))?; + } + } + contour_start = contour_end + 1; + } + Ok(outline.adjusted_advance_width().to_bits() >> 6) + }) + } + OutlineKind::Cff(cff, glyph_id, subfont_ix) => { + let subfont = cff.subfont(*subfont_ix, ppem, coords)?; + let mut adapter = unscaled::UnscaledPenAdapter::new(sink); + cff.draw(&subfont, *glyph_id, coords, false, &mut adapter)?; + adapter.finish()?; + let advance = cff.glyph_metrics.advance_width(*glyph_id, coords); + Ok(advance) + } + } + } + + pub(crate) fn font(&self) -> &FontRef<'a> { + match &self.kind { + OutlineKind::Glyf(glyf, ..) => &glyf.font, + OutlineKind::Cff(cff, ..) => &cff.font, + } + } + + fn units_per_em(&self) -> u16 { + match &self.kind { + OutlineKind::Cff(cff, ..) => cff.units_per_em(), + OutlineKind::Glyf(glyf, ..) => glyf.units_per_em(), + } + } +} + +#[derive(Clone)] +enum OutlineKind<'a> { + Glyf(glyf::Outlines<'a>, glyf::Outline<'a>), + // Third field is subfont index + Cff(cff::Outlines<'a>, GlyphId, u32), +} + +impl Debug for OutlineKind<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Glyf(_, outline) => f.debug_tuple("Glyf").field(&outline.glyph_id).finish(), + Self::Cff(_, gid, subfont_index) => f + .debug_tuple("Cff") + .field(gid) + .field(subfont_index) + .finish(), + } + } +} + +/// Collection of scalable glyph outlines. +#[derive(Debug, Clone)] +pub struct OutlineGlyphCollection<'a> { + kind: OutlineCollectionKind<'a>, +} + +impl<'a> OutlineGlyphCollection<'a> { + /// Creates a new outline collection for the given font. + pub fn new(font: &FontRef<'a>) -> Self { + let kind = if let Some(glyf) = glyf::Outlines::new(font) { + OutlineCollectionKind::Glyf(glyf) + } else if let Some(cff) = cff::Outlines::new(font) { + OutlineCollectionKind::Cff(cff) + } else { + OutlineCollectionKind::None + }; + Self { kind } + } + + /// Creates a new outline collection for the given font and outline + /// format. + /// + /// Returns `None` if the font does not contain outlines in the requested + /// format. + pub fn with_format(font: &FontRef<'a>, format: OutlineGlyphFormat) -> Option { + let kind = match format { + OutlineGlyphFormat::Glyf => OutlineCollectionKind::Glyf(glyf::Outlines::new(font)?), + OutlineGlyphFormat::Cff => { + let upem = font.head().ok()?.units_per_em(); + OutlineCollectionKind::Cff(cff::Outlines::from_cff(font, upem)?) + } + OutlineGlyphFormat::Cff2 => { + let upem = font.head().ok()?.units_per_em(); + OutlineCollectionKind::Cff(cff::Outlines::from_cff2(font, upem)?) + } + }; + Some(Self { kind }) + } + + /// Returns the underlying format of the source outline tables. + pub fn format(&self) -> Option { + match &self.kind { + OutlineCollectionKind::Glyf(..) => Some(OutlineGlyphFormat::Glyf), + OutlineCollectionKind::Cff(cff) => cff + .is_cff2() + .then_some(OutlineGlyphFormat::Cff2) + .or(Some(OutlineGlyphFormat::Cff)), + _ => None, + } + } + + /// Returns the outline for the given glyph identifier. + pub fn get(&self, glyph_id: GlyphId) -> Option> { + match &self.kind { + OutlineCollectionKind::None => None, + OutlineCollectionKind::Glyf(glyf) => Some(OutlineGlyph { + kind: OutlineKind::Glyf(glyf.clone(), glyf.outline(glyph_id).ok()?), + }), + OutlineCollectionKind::Cff(cff) => Some(OutlineGlyph { + kind: OutlineKind::Cff(cff.clone(), glyph_id, cff.subfont_index(glyph_id)), + }), + } + } + + /// Returns an iterator over all of the outline glyphs in the collection. + pub fn iter(&self) -> impl Iterator)> + 'a + Clone { + let len = match &self.kind { + OutlineCollectionKind::Glyf(glyf) => glyf.glyph_count(), + OutlineCollectionKind::Cff(cff) => cff.glyph_count(), + _ => 0, + } as u16; + let copy = self.clone(); + (0..len).filter_map(move |gid| { + let gid = GlyphId::from(gid); + let glyph = copy.get(gid)?; + Some((gid, glyph)) + }) + } + + /// Returns true if the interpreter engine should be used for hinting this + /// set of outlines. + /// + /// When this returns false, you likely want to use the automatic hinter + /// instead. + /// + /// This matches the logic used in FreeType when neither of the + /// `FT_LOAD_FORCE_AUTOHINT` or `FT_LOAD_NO_AUTOHINT` load flags are + /// specified. + /// + /// When setting [`HintingOptions::engine`] to [`Engine::AutoFallback`], + /// this is used to determine whether to use the interpreter or automatic + /// hinter. + pub fn prefer_interpreter(&self) -> bool { + match &self.kind { + OutlineCollectionKind::Glyf(glyf) => glyf.prefer_interpreter(), + _ => true, + } + } + + /// Returns true when the interpreter engine _must_ be used for hinting + /// this set of outlines to produce correct results. + /// + /// This corresponds so FreeType's `FT_FACE_FLAG_TRICKY` face flag. See + /// the documentation for that [flag](https://freetype.org/freetype2/docs/reference/ft2-face_creation.html#ft_face_flag_xxx) + /// for more detail. + /// + /// When this returns `true`, you should construct a [`HintingInstance`] + /// with [`HintingOptions::engine`] set to [`Engine::Interpreter`] and + /// [`HintingOptions::target`] set to [`Target::Mono`]. + /// + /// # Performance + /// This digs through the name table and potentially computes checksums + /// so it may be slow. You should cache the result of this function if + /// possible. + pub fn require_interpreter(&self) -> bool { + self.font() + .map(|font| hint_reliant::require_interpreter(font)) + .unwrap_or_default() + } + + pub(crate) fn font(&self) -> Option<&FontRef<'a>> { + match &self.kind { + OutlineCollectionKind::Glyf(glyf) => Some(&glyf.font), + OutlineCollectionKind::Cff(cff) => Some(&cff.font), + _ => None, + } + } +} + +#[derive(Clone)] +enum OutlineCollectionKind<'a> { + None, + Glyf(glyf::Outlines<'a>), + Cff(cff::Outlines<'a>), +} + +impl Debug for OutlineCollectionKind<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::None => write!(f, "None"), + Self::Glyf(..) => f.debug_tuple("Glyf").finish(), + Self::Cff(..) => f.debug_tuple("Cff").finish(), + } + } +} + +/// Invokes the callback with a memory buffer suitable for drawing +/// the given TrueType outline. +pub(super) fn with_glyf_memory( + outline: &glyf::Outline, + hinting: Hinting, + memory: Option<&mut [u8]>, + mut f: impl FnMut(&mut [u8]) -> R, +) -> R { + match memory { + Some(buf) => f(buf), + None => { + let buf_size = outline.required_buffer_size(hinting); + memory::with_temporary_memory(buf_size, f) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{instance::Location, MetadataProvider}; + use kurbo::{Affine, BezPath, PathEl, Point}; + use read_fonts::{types::GlyphId, FontRef, TableProvider}; + + use pretty_assertions::assert_eq; + + const PERIOD: u32 = 0x2E_u32; + const COMMA: u32 = 0x2C_u32; + + #[test] + fn outline_glyph_formats() { + let font_format_pairs = [ + (font_test_data::VAZIRMATN_VAR, OutlineGlyphFormat::Glyf), + ( + font_test_data::CANTARELL_VF_TRIMMED, + OutlineGlyphFormat::Cff2, + ), + ( + font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, + OutlineGlyphFormat::Cff, + ), + (font_test_data::COLRV0V1_VARIABLE, OutlineGlyphFormat::Glyf), + ]; + for (font_data, format) in font_format_pairs { + assert_eq!( + FontRef::new(font_data).unwrap().outline_glyphs().format(), + Some(format) + ); + } + } + + #[test] + fn vazirmatin_var() { + compare_glyphs( + font_test_data::VAZIRMATN_VAR, + font_test_data::VAZIRMATN_VAR_GLYPHS, + ); + } + + #[test] + fn cantarell_vf() { + compare_glyphs( + font_test_data::CANTARELL_VF_TRIMMED, + font_test_data::CANTARELL_VF_TRIMMED_GLYPHS, + ); + } + + #[test] + fn noto_serif_display() { + compare_glyphs( + font_test_data::NOTO_SERIF_DISPLAY_TRIMMED, + font_test_data::NOTO_SERIF_DISPLAY_TRIMMED_GLYPHS, + ); + } + + #[test] + fn overlap_flags() { + let font = FontRef::new(font_test_data::VAZIRMATN_VAR).unwrap(); + let outlines = font.outline_glyphs(); + let glyph_count = font.maxp().unwrap().num_glyphs(); + // GID 2 is a composite glyph with the overlap bit on a component + // GID 3 is a simple glyph with the overlap bit on the first flag + let expected_gids_with_overlap = vec![2, 3]; + assert_eq!( + expected_gids_with_overlap, + (0..glyph_count) + .filter( + |gid| outlines.get(GlyphId::from(*gid)).unwrap().has_overlaps() == Some(true) + ) + .collect::>() + ); + } + + fn compare_glyphs(font_data: &[u8], expected_outlines: &str) { + let font = FontRef::new(font_data).unwrap(); + let expected_outlines = testing::parse_glyph_outlines(expected_outlines); + let mut path = testing::Path::default(); + for expected_outline in &expected_outlines { + if expected_outline.size == 0.0 && !expected_outline.coords.is_empty() { + continue; + } + let size = if expected_outline.size != 0.0 { + Size::new(expected_outline.size) + } else { + Size::unscaled() + }; + path.elements.clear(); + font.outline_glyphs() + .get(expected_outline.glyph_id) + .unwrap() + .draw( + DrawSettings::unhinted(size, expected_outline.coords.as_slice()), + &mut path, + ) + .unwrap(); + assert_eq!(path.elements, expected_outline.path, "mismatch in glyph path for id {} (size: {}, coords: {:?}): path: {:?} expected_path: {:?}", + expected_outline.glyph_id, + expected_outline.size, + expected_outline.coords, + &path.elements, + &expected_outline.path + ); + } + } + + #[derive(Copy, Clone, Debug, PartialEq)] + enum GlyphPoint { + On { x: f32, y: f32 }, + Off { x: f32, y: f32 }, + } + + impl GlyphPoint { + fn implied_oncurve(&self, other: Self) -> Self { + let (x1, y1) = self.xy(); + let (x2, y2) = other.xy(); + Self::On { + x: (x1 + x2) / 2.0, + y: (y1 + y2) / 2.0, + } + } + + fn xy(&self) -> (f32, f32) { + match self { + GlyphPoint::On { x, y } | GlyphPoint::Off { x, y } => (*x, *y), + } + } + } + + #[derive(Debug)] + struct PointPen { + points: Vec, + } + + impl PointPen { + fn new() -> Self { + Self { points: Vec::new() } + } + + fn into_points(self) -> Vec { + self.points + } + } + + impl OutlinePen for PointPen { + fn move_to(&mut self, x: f32, y: f32) { + self.points.push(GlyphPoint::On { x, y }); + } + + fn line_to(&mut self, x: f32, y: f32) { + self.points.push(GlyphPoint::On { x, y }); + } + + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { + self.points.push(GlyphPoint::Off { x: cx0, y: cy0 }); + self.points.push(GlyphPoint::On { x, y }); + } + + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { + self.points.push(GlyphPoint::Off { x: cx0, y: cy0 }); + self.points.push(GlyphPoint::Off { x: cx1, y: cy1 }); + self.points.push(GlyphPoint::On { x, y }); + } + + fn close(&mut self) { + // We can't drop a 0-length closing line for fear of breaking interpolation compatibility + // - some other instance might have it not 0-length + // However, if the last command isn't a line and ends at the subpath start we can drop the endpoint + // - if any instance had it other than at the start there would be a closing line + // - and it wouldn't be interpolation compatible + // See + let np = self.points.len(); + // We need at least 3 points to satisfy subsequent conditions + if np > 2 + && self.points[0] == self.points[np - 1] + && matches!( + (self.points[0], self.points[np - 2]), + (GlyphPoint::On { .. }, GlyphPoint::Off { .. }) + ) + { + self.points.pop(); + } + } + } + + const STARTING_OFF_CURVE_POINTS: [GlyphPoint; 4] = [ + GlyphPoint::Off { x: 278.0, y: 710.0 }, + GlyphPoint::On { x: 278.0, y: 470.0 }, + GlyphPoint::On { x: 998.0, y: 470.0 }, + GlyphPoint::On { x: 998.0, y: 710.0 }, + ]; + + const MOSTLY_OFF_CURVE_POINTS: [GlyphPoint; 5] = [ + GlyphPoint::Off { x: 278.0, y: 710.0 }, + GlyphPoint::Off { x: 278.0, y: 470.0 }, + GlyphPoint::On { x: 998.0, y: 470.0 }, + GlyphPoint::Off { x: 998.0, y: 710.0 }, + GlyphPoint::Off { x: 750.0, y: 500.0 }, + ]; + + /// Captures the svg drawing command sequence, e.g. MLLZ. + /// + /// Intended use is to confirm the command sequence pushed to the pen is interpolation compatible. + #[derive(Default, Debug)] + struct CommandPen { + commands: String, + } + + impl OutlinePen for CommandPen { + fn move_to(&mut self, _x: f32, _y: f32) { + self.commands.push('M'); + } + + fn line_to(&mut self, _x: f32, _y: f32) { + self.commands.push('L'); + } + + fn quad_to(&mut self, _cx0: f32, _cy0: f32, _x: f32, _y: f32) { + self.commands.push('Q'); + } + + fn curve_to(&mut self, _cx0: f32, _cy0: f32, _cx1: f32, _cy1: f32, _x: f32, _y: f32) { + self.commands.push('C'); + } + + fn close(&mut self) { + self.commands.push('Z'); + } + } + + fn draw_to_pen(font: &[u8], codepoint: u32, settings: DrawSettings, pen: &mut impl OutlinePen) { + let font = FontRef::new(font).unwrap(); + let gid = font + .cmap() + .unwrap() + .map_codepoint(codepoint) + .unwrap_or_else(|| panic!("No gid for 0x{codepoint:04x}")); + let outlines = font.outline_glyphs(); + let outline = outlines.get(gid).unwrap_or_else(|| { + panic!( + "No outline for {gid:?} in collection of {:?}", + outlines.format() + ) + }); + + outline.draw(settings, pen).unwrap(); + } + + fn draw_commands(font: &[u8], codepoint: u32, settings: DrawSettings) -> String { + let mut pen = CommandPen::default(); + draw_to_pen(font, codepoint, settings, &mut pen); + pen.commands + } + + fn drawn_points(font: &[u8], codepoint: u32, settings: DrawSettings) -> Vec { + let mut pen = PointPen::new(); + draw_to_pen(font, codepoint, settings, &mut pen); + pen.into_points() + } + + fn insert_implicit_oncurve(pointstream: &[GlyphPoint]) -> Vec { + let mut expanded_points = Vec::new(); + + for i in 0..pointstream.len() - 1 { + expanded_points.push(pointstream[i]); + if matches!( + (pointstream[i], pointstream[i + 1]), + (GlyphPoint::Off { .. }, GlyphPoint::Off { .. }) + ) { + expanded_points.push(pointstream[i].implied_oncurve(pointstream[i + 1])); + } + } + + expanded_points.push(*pointstream.last().unwrap()); + + expanded_points + } + + fn as_on_off_sequence(points: &[GlyphPoint]) -> Vec<&'static str> { + points + .iter() + .map(|p| match p { + GlyphPoint::On { .. } => "On", + GlyphPoint::Off { .. } => "Off", + }) + .collect() + } + + #[test] + fn always_get_closing_lines() { + // + let period = draw_commands( + font_test_data::INTERPOLATE_THIS, + PERIOD, + Size::unscaled().into(), + ); + let comma = draw_commands( + font_test_data::INTERPOLATE_THIS, + COMMA, + Size::unscaled().into(), + ); + + assert_eq!( + period, comma, + "Incompatible\nperiod\n{period:#?}\ncomma\n{comma:#?}\n" + ); + assert_eq!( + "MLLLZ", period, + "We should get an explicit L for close even when it's a nop" + ); + } + + #[test] + fn triangle_and_square_retain_compatibility() { + // + let period = drawn_points( + font_test_data::INTERPOLATE_THIS, + PERIOD, + Size::unscaled().into(), + ); + let comma = drawn_points( + font_test_data::INTERPOLATE_THIS, + COMMA, + Size::unscaled().into(), + ); + + assert_ne!(period, comma); + assert_eq!( + as_on_off_sequence(&period), + as_on_off_sequence(&comma), + "Incompatible\nperiod\n{period:#?}\ncomma\n{comma:#?}\n" + ); + assert_eq!( + 4, + period.len(), + "we should have the same # of points we started with" + ); + } + + fn assert_walked_backwards_like_freetype(pointstream: &[GlyphPoint], font: &[u8]) { + assert!( + matches!(pointstream[0], GlyphPoint::Off { .. }), + "Bad testdata, should start off curve" + ); + + // The default: look for an oncurve at the back, as freetype would do + let mut expected_points = pointstream.to_vec(); + let last = *expected_points.last().unwrap(); + let first_move = if matches!(last, GlyphPoint::Off { .. }) { + expected_points[0].implied_oncurve(last) + } else { + expected_points.pop().unwrap() + }; + expected_points.insert(0, first_move); + + expected_points = insert_implicit_oncurve(&expected_points); + let actual = drawn_points(font, PERIOD, Size::unscaled().into()); + assert_eq!( + expected_points, actual, + "expected\n{expected_points:#?}\nactual\n{actual:#?}" + ); + } + + fn assert_walked_forwards_like_harfbuzz(pointstream: &[GlyphPoint], font: &[u8]) { + assert!( + matches!(pointstream[0], GlyphPoint::Off { .. }), + "Bad testdata, should start off curve" + ); + + // look for an oncurve at the front, as harfbuzz would do + let mut expected_points = pointstream.to_vec(); + let first = expected_points.remove(0); + expected_points.push(first); + if matches!(expected_points[0], GlyphPoint::Off { .. }) { + expected_points.insert(0, first.implied_oncurve(expected_points[0])) + }; + + expected_points = insert_implicit_oncurve(&expected_points); + + let settings: DrawSettings = Size::unscaled().into(); + let settings = settings.with_path_style(PathStyle::HarfBuzz); + let actual = drawn_points(font, PERIOD, settings); + assert_eq!( + expected_points, actual, + "expected\n{expected_points:#?}\nactual\n{actual:#?}" + ); + } + + #[test] + fn starting_off_curve_walk_backwards_like_freetype() { + assert_walked_backwards_like_freetype( + &STARTING_OFF_CURVE_POINTS, + font_test_data::STARTING_OFF_CURVE, + ); + } + + #[test] + fn mostly_off_curve_walk_backwards_like_freetype() { + assert_walked_backwards_like_freetype( + &MOSTLY_OFF_CURVE_POINTS, + font_test_data::MOSTLY_OFF_CURVE, + ); + } + + #[test] + fn starting_off_curve_walk_forwards_like_hbdraw() { + assert_walked_forwards_like_harfbuzz( + &STARTING_OFF_CURVE_POINTS, + font_test_data::STARTING_OFF_CURVE, + ); + } + + #[test] + fn mostly_off_curve_walk_forwards_like_hbdraw() { + assert_walked_forwards_like_harfbuzz( + &MOSTLY_OFF_CURVE_POINTS, + font_test_data::MOSTLY_OFF_CURVE, + ); + } + + // A location noted for making FreeType and HarfBuzz results differ + // See https://github.com/googlefonts/sleipnir/pull/15 + fn icon_loc_off_default(font: &FontRef) -> Location { + font.axes().location(&[ + ("wght", 700.0), + ("opsz", 48.0), + ("GRAD", 200.0), + ("FILL", 1.0), + ]) + } + + fn pt(x: f32, y: f32) -> Point { + (x as f64, y as f64).into() + } + + // String command rounded to two decimal places, suitable for assert comparison + fn svg_commands(elements: &[PathEl]) -> Vec { + elements + .iter() + .map(|e| match e { + PathEl::MoveTo(p) => format!("M{:.2},{:.2}", p.x, p.y), + PathEl::LineTo(p) => format!("L{:.2},{:.2}", p.x, p.y), + PathEl::QuadTo(c0, p) => format!("Q{:.2},{:.2} {:.2},{:.2}", c0.x, c0.y, p.x, p.y), + PathEl::CurveTo(c0, c1, p) => format!( + "C{:.2},{:.2} {:.2},{:.2} {:.2},{:.2}", + c0.x, c0.y, c1.x, c1.y, p.x, p.y + ), + PathEl::ClosePath => "Z".to_string(), + }) + .collect() + } + + // Declared here to avoid a write-fonts dependency that is awkward for google3 at time of writing + #[derive(Default)] + struct BezPen { + path: BezPath, + } + + impl OutlinePen for BezPen { + fn move_to(&mut self, x: f32, y: f32) { + self.path.move_to(pt(x, y)); + } + + fn line_to(&mut self, x: f32, y: f32) { + self.path.line_to(pt(x, y)); + } + + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { + self.path.quad_to(pt(cx0, cy0), pt(x, y)); + } + + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { + self.path.curve_to(pt(cx0, cy0), pt(cx1, cy1), pt(x, y)); + } + + fn close(&mut self) { + self.path.close_path(); + } + } + + // We take glyph id here to bypass the need to resolve codepoint:gid and apply substitutions + fn assert_glyph_path_start_with( + font: &FontRef, + gid: GlyphId, + loc: Location, + path_style: PathStyle, + expected_path_start: &[PathEl], + ) { + let glyph = font + .outline_glyphs() + .get(gid) + .unwrap_or_else(|| panic!("No glyph for {gid}")); + + let mut pen = BezPen::default(); + glyph + .draw( + DrawSettings::unhinted(Size::unscaled(), &loc).with_path_style(path_style), + &mut pen, + ) + .unwrap_or_else(|e| panic!("Unable to draw {gid}: {e}")); + let bez = Affine::FLIP_Y * pen.path; // like an icon svg + let actual_path_start = &bez.elements()[..expected_path_start.len()]; + // round2 can still leave very small differences from the typed 2-decimal value + // and the diff isn't pleasant so just compare as svg string fragments + assert_eq!( + svg_commands(expected_path_start), + svg_commands(actual_path_start) + ); + } + + const MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT: GlyphId = GlyphId::new(1); + const MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT: GlyphId = GlyphId::new(2); + + #[test] + fn draw_icon_freetype_style_at_default() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + assert_glyph_path_start_with( + &font, + MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT, + Location::default(), + PathStyle::FreeType, + &[ + PathEl::MoveTo((160.0, -160.0).into()), + PathEl::QuadTo((127.0, -160.0).into(), (103.5, -183.5).into()), + PathEl::QuadTo((80.0, -207.0).into(), (80.0, -240.0).into()), + ], + ); + } + + #[test] + fn draw_icon_harfbuzz_style_at_default() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + assert_glyph_path_start_with( + &font, + MATERIAL_SYMBOL_GID_MAIL_AT_DEFAULT, + Location::default(), + PathStyle::HarfBuzz, + &[ + PathEl::MoveTo((160.0, -160.0).into()), + PathEl::QuadTo((127.0, -160.0).into(), (103.5, -183.5).into()), + PathEl::QuadTo((80.0, -207.0).into(), (80.0, -240.0).into()), + ], + ); + } + + #[test] + fn draw_icon_freetype_style_off_default() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + assert_glyph_path_start_with( + &font, + MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT, + icon_loc_off_default(&font), + PathStyle::FreeType, + &[ + PathEl::MoveTo((150.0, -138.0).into()), + PathEl::QuadTo((113.0, -138.0).into(), (86.0, -165.5).into()), + PathEl::QuadTo((59.0, -193.0).into(), (59.0, -229.0).into()), + ], + ); + } + + #[test] + fn draw_icon_harfbuzz_style_off_default() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + assert_glyph_path_start_with( + &font, + MATERIAL_SYMBOL_GID_MAIL_OFF_DEFAULT, + icon_loc_off_default(&font), + PathStyle::HarfBuzz, + &[ + PathEl::MoveTo((150.0, -138.0).into()), + PathEl::QuadTo((113.22, -138.0).into(), (86.11, -165.61).into()), + PathEl::QuadTo((59.0, -193.22).into(), (59.0, -229.0).into()), + ], + ); + } + + const GLYF_COMPONENT_GID_NON_UNIFORM_SCALE: GlyphId = GlyphId::new(3); + const GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET: GlyphId = GlyphId::new(7); + const GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET: GlyphId = GlyphId::new(8); + + #[test] + fn draw_nonuniform_scale_component_freetype() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_NON_UNIFORM_SCALE, + Location::default(), + PathStyle::FreeType, + &[ + PathEl::MoveTo((-138.0, -185.0).into()), + PathEl::LineTo((-32.0, -259.0).into()), + PathEl::LineTo((26.0, -175.0).into()), + PathEl::LineTo((-80.0, -101.0).into()), + PathEl::ClosePath, + ], + ); + } + + #[test] + fn draw_nonuniform_scale_component_harfbuzz() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_NON_UNIFORM_SCALE, + Location::default(), + PathStyle::HarfBuzz, + &[ + PathEl::MoveTo((-137.8, -184.86).into()), + PathEl::LineTo((-32.15, -258.52).into()), + PathEl::LineTo((25.9, -175.24).into()), + PathEl::LineTo((-79.75, -101.58).into()), + PathEl::ClosePath, + ], + ); + } + + #[test] + fn draw_scaled_component_offset_freetype() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET, + Location::default(), + PathStyle::FreeType, + &[ + // Adds (x-transform magnitude * x-offset, y-transform magnitude * y-offset) to x/y offset + PathEl::MoveTo((715.0, -360.0).into()), + ], + ); + } + + #[test] + fn draw_no_scaled_component_offset_freetype() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET, + Location::default(), + PathStyle::FreeType, + &[PathEl::MoveTo((705.0, -340.0).into())], + ); + } + + #[test] + fn draw_scaled_component_offset_harfbuzz() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_SCALED_COMPONENT_OFFSET, + Location::default(), + PathStyle::HarfBuzz, + &[ + // Adds (x-transform magnitude * x-offset, y-transform magnitude * y-offset) to x/y offset + PathEl::MoveTo((714.97, -360.0).into()), + ], + ); + } + + #[test] + fn draw_no_scaled_component_offset_harfbuzz() { + let font = FontRef::new(font_test_data::GLYF_COMPONENTS).unwrap(); + assert_glyph_path_start_with( + &font, + GLYF_COMPONENT_GID_NO_SCALED_COMPONENT_OFFSET, + Location::default(), + PathStyle::HarfBuzz, + &[PathEl::MoveTo((704.97, -340.0).into())], + ); + } + + #[cfg(feature = "spec_next")] + const CUBIC_GLYPH: GlyphId = GlyphId::new(2); + + #[test] + #[cfg(feature = "spec_next")] + fn draw_cubic() { + let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); + assert_glyph_path_start_with( + &font, + CUBIC_GLYPH, + Location::default(), + PathStyle::FreeType, + &[ + PathEl::MoveTo((278.0, -710.0).into()), + PathEl::LineTo((278.0, -470.0).into()), + PathEl::CurveTo( + (300.0, -500.0).into(), + (800.0, -500.0).into(), + (998.0, -470.0).into(), + ), + PathEl::LineTo((998.0, -710.0).into()), + ], + ); + } + + /// Case where a font subset caused hinting to fail because execution + /// budget was derived from glyph count. + /// + #[test] + fn tthint_with_subset() { + let font = FontRef::new(font_test_data::TTHINT_SUBSET).unwrap(); + let glyphs = font.outline_glyphs(); + let hinting = HintingInstance::new( + &glyphs, + Size::new(16.0), + LocationRef::default(), + HintingOptions::default(), + ) + .unwrap(); + let glyph = glyphs.get(GlyphId::new(1)).unwrap(); + // Shouldn't fail in pedantic mode + glyph + .draw(DrawSettings::hinted(&hinting, true), &mut BezPen::default()) + .unwrap(); + } + + #[test] + fn empty_glyph_advance_unhinted() { + let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); + let outlines = font.outline_glyphs(); + let coords = [NormalizedCoord::from_f32(0.5)]; + let gid = font.charmap().map(' ').unwrap(); + let outline = outlines.get(gid).unwrap(); + let advance = outline + .draw( + (Size::new(24.0), LocationRef::new(&coords)), + &mut super::pen::NullPen, + ) + .unwrap() + .advance_width + .unwrap(); + assert_eq!(advance, 10.796875); + } + + #[test] + fn empty_glyph_advance_hinted() { + let font = FontRef::new(font_test_data::HVAR_WITH_TRUNCATED_ADVANCE_INDEX_MAP).unwrap(); + let outlines = font.outline_glyphs(); + let coords = [NormalizedCoord::from_f32(0.5)]; + let hinter = HintingInstance::new( + &outlines, + Size::new(24.0), + LocationRef::new(&coords), + HintingOptions::default(), + ) + .unwrap(); + let gid = font.charmap().map(' ').unwrap(); + let outline = outlines.get(gid).unwrap(); + let advance = outline + .draw(&hinter, &mut super::pen::NullPen) + .unwrap() + .advance_width + .unwrap(); + assert_eq!(advance, 11.0); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,390 @@ +//! TrueType style outline to path conversion. + +use super::pen::{OutlinePen, PathStyle}; +use core::fmt; +use raw::{ + tables::glyf::{PointCoord, PointFlags}, + types::Point, +}; + +/// Errors that can occur when converting an outline to a path. +#[derive(Clone, Debug)] +pub enum ToPathError { + /// Contour end point at this index was less than its preceding end point. + ContourOrder(usize), + /// Expected a quadratic off-curve point at this index. + ExpectedQuad(usize), + /// Expected a quadratic off-curve or on-curve point at this index. + ExpectedQuadOrOnCurve(usize), + /// Expected a cubic off-curve point at this index. + ExpectedCubic(usize), + /// Expected number of points to == number of flags + PointFlagMismatch { num_points: usize, num_flags: usize }, +} + +impl fmt::Display for ToPathError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::ContourOrder(ix) => write!( + f, + "Contour end point at index {ix} was less than preceding end point" + ), + Self::ExpectedQuad(ix) => write!(f, "Expected quadatic off-curve point at index {ix}"), + Self::ExpectedQuadOrOnCurve(ix) => write!( + f, + "Expected quadatic off-curve or on-curve point at index {ix}" + ), + Self::ExpectedCubic(ix) => write!(f, "Expected cubic off-curve point at index {ix}"), + Self::PointFlagMismatch { + num_points, + num_flags, + } => write!( + f, + "Number of points ({num_points}) and flags ({num_flags}) must match" + ), + } + } +} + +/// Converts a `glyf` outline described by points, flags and contour end points +/// to a sequence of path elements and invokes the appropriate callback on the +/// given pen for each. +/// +/// The input points can have any coordinate type that implements +/// [`PointCoord`]. Output points are always generated in `f32`. +/// +/// This is roughly equivalent to [`FT_Outline_Decompose`](https://freetype.org/freetype2/docs/reference/ft2-outline_processing.html#ft_outline_decompose). +/// +/// See [`contour_to_path`] for a more general function that takes an iterator +/// if your outline data is in a different format. +pub(crate) fn to_path( + points: &[Point], + flags: &[PointFlags], + contours: &[u16], + path_style: PathStyle, + pen: &mut impl OutlinePen, +) -> Result<(), ToPathError> { + for contour_ix in 0..contours.len() { + let start_ix = (contour_ix > 0) + .then(|| contours[contour_ix - 1] as usize + 1) + .unwrap_or_default(); + let end_ix = contours[contour_ix] as usize; + if end_ix < start_ix || end_ix >= points.len() { + return Err(ToPathError::ContourOrder(contour_ix)); + } + let points = &points[start_ix..=end_ix]; + if points.is_empty() { + continue; + } + let flags = flags + .get(start_ix..=end_ix) + .ok_or(ToPathError::PointFlagMismatch { + num_points: points.len(), + num_flags: flags.len(), + })?; + let last_point = points.last().unwrap(); + let last_flags = flags.last().unwrap(); + let last_point = ContourPoint { + x: last_point.x, + y: last_point.y, + flags: *last_flags, + }; + contour_to_path( + points.iter().zip(flags).map(|(point, flags)| ContourPoint { + x: point.x, + y: point.y, + flags: *flags, + }), + last_point, + path_style, + pen, + ) + .map_err(|e| match &e { + ToPathError::ExpectedCubic(ix) => ToPathError::ExpectedCubic(ix + start_ix), + ToPathError::ExpectedQuad(ix) => ToPathError::ExpectedQuad(ix + start_ix), + ToPathError::ExpectedQuadOrOnCurve(ix) => { + ToPathError::ExpectedQuadOrOnCurve(ix + start_ix) + } + _ => e, + })? + } + Ok(()) +} + +/// Combination of point coordinates and flags. +#[derive(Copy, Clone, Default, Debug)] +pub(crate) struct ContourPoint { + pub x: T, + pub y: T, + pub flags: PointFlags, +} + +impl ContourPoint +where + T: PointCoord, +{ + fn point_f32(&self) -> Point { + Point::new(self.x.to_f32(), self.y.to_f32()) + } + + fn midpoint(&self, other: Self) -> ContourPoint { + let (x, y) = (self.x.midpoint(other.x), self.y.midpoint(other.y)); + Self { + x, + y, + flags: other.flags, + } + } +} + +/// Generates a path from an iterator of contour points. +/// +/// Note that this requires the last point of the contour to be passed +/// separately to support FreeType style path conversion when the contour +/// begins with an off curve point. The points iterator should still +/// yield the last point as well. +/// +/// This is more general than [`to_path`] and exists to support cases (such as +/// autohinting) where the source outline data is in a different format. +pub(crate) fn contour_to_path( + points: impl Iterator>, + last_point: ContourPoint, + style: PathStyle, + pen: &mut impl OutlinePen, +) -> Result<(), ToPathError> { + let mut points = points.enumerate().peekable(); + let Some((_, first_point)) = points.peek().copied() else { + // This is an empty contour + return Ok(()); + }; + // We don't accept an off curve cubic as the first point + if first_point.flags.is_off_curve_cubic() { + return Err(ToPathError::ExpectedQuadOrOnCurve(0)); + } + // For FreeType style, we may need to omit the last point if we find the + // first on curve there + let mut omit_last = false; + // For HarfBuzz style, may skip up to two points in finding the start, so + // process these at the end + let mut trailing_points = [None; 2]; + // Find our starting point + let start_point = if first_point.flags.is_off_curve_quad() { + // We're starting with an off curve, so select our first move based on + // the path style + match style { + PathStyle::FreeType => { + if last_point.flags.is_on_curve() { + // The last point is an on curve, so let's start there + omit_last = true; + last_point + } else { + // It's also an off curve, so take implicit midpoint + last_point.midpoint(first_point) + } + } + PathStyle::HarfBuzz => { + // Always consume the first point + points.next(); + // Then check the next point + let Some((_, next_point)) = points.peek().copied() else { + // This is a single point contour + return Ok(()); + }; + if next_point.flags.is_on_curve() { + points.next(); + trailing_points = [Some((0, first_point)), Some((1, next_point))]; + // Next is on curve, so let's start there + next_point + } else { + // It's also an off curve, so take the implicit midpoint + trailing_points = [Some((0, first_point)), None]; + first_point.midpoint(next_point) + } + } + } + } else { + // We're starting with an on curve, so consume the point + points.next(); + first_point + }; + let point = start_point.point_f32(); + pen.move_to(point.x, point.y); + let mut state = PendingState::default(); + if omit_last { + while let Some((ix, point)) = points.next() { + if points.peek().is_none() { + break; + } + state.emit(ix, point, pen)?; + } + } else { + for (ix, point) in points { + state.emit(ix, point, pen)?; + } + } + for (ix, point) in trailing_points.iter().filter_map(|x| *x) { + state.emit(ix, point, pen)?; + } + state.finish(0, start_point, pen)?; + Ok(()) +} + +#[derive(Copy, Clone, Default)] +enum PendingState { + /// No pending points. + #[default] + Empty, + /// Pending off-curve quad point. + PendingQuad(ContourPoint), + /// Single pending off-curve cubic point. + PendingCubic(ContourPoint), + /// Two pending off-curve cubic points. + TwoPendingCubics(ContourPoint, ContourPoint), +} + +impl PendingState +where + C: PointCoord, +{ + #[inline(always)] + fn emit( + &mut self, + ix: usize, + point: ContourPoint, + pen: &mut impl OutlinePen, + ) -> Result<(), ToPathError> { + let flags = point.flags; + match *self { + Self::Empty => { + if flags.is_off_curve_quad() { + *self = Self::PendingQuad(point); + } else if flags.is_off_curve_cubic() { + *self = Self::PendingCubic(point); + } else { + let p = point.point_f32(); + pen.line_to(p.x, p.y); + } + } + Self::PendingQuad(quad) => { + if flags.is_off_curve_quad() { + let c0 = quad.point_f32(); + let p = quad.midpoint(point).point_f32(); + pen.quad_to(c0.x, c0.y, p.x, p.y); + *self = Self::PendingQuad(point); + } else if flags.is_off_curve_cubic() { + return Err(ToPathError::ExpectedQuadOrOnCurve(ix)); + } else { + let c0 = quad.point_f32(); + let p = point.point_f32(); + pen.quad_to(c0.x, c0.y, p.x, p.y); + *self = Self::Empty; + } + } + Self::PendingCubic(cubic) => { + if flags.is_off_curve_cubic() { + *self = Self::TwoPendingCubics(cubic, point); + } else { + return Err(ToPathError::ExpectedCubic(ix)); + } + } + Self::TwoPendingCubics(cubic0, cubic1) => { + if flags.is_off_curve_quad() { + return Err(ToPathError::ExpectedCubic(ix)); + } else if flags.is_off_curve_cubic() { + let c0 = cubic0.point_f32(); + let c1 = cubic1.point_f32(); + let p = cubic1.midpoint(point).point_f32(); + pen.curve_to(c0.x, c0.y, c1.x, c1.y, p.x, p.y); + *self = Self::PendingCubic(point); + } else { + let c0 = cubic0.point_f32(); + let c1 = cubic1.point_f32(); + let p = point.point_f32(); + pen.curve_to(c0.x, c0.y, c1.x, c1.y, p.x, p.y); + *self = Self::Empty; + } + } + } + Ok(()) + } + + fn finish( + mut self, + start_ix: usize, + mut start_point: ContourPoint, + pen: &mut impl OutlinePen, + ) -> Result<(), ToPathError> { + match self { + Self::Empty => {} + _ => { + // We always want to end with an explicit on-curve + start_point.flags = PointFlags::on_curve(); + self.emit(start_ix, start_point, pen)?; + } + } + pen.close(); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::{super::pen::SvgPen, *}; + use raw::types::F26Dot6; + + fn assert_off_curve_path_to_svg(expected: &str, path_style: PathStyle, all_off_curve: bool) { + fn pt(x: i32, y: i32) -> Point { + Point::new(x, y).map(F26Dot6::from_bits) + } + let mut flags = [PointFlags::off_curve_quad(); 4]; + if !all_off_curve { + flags[1] = PointFlags::on_curve(); + } + let contours = [3]; + // This test is meant to prevent a bug where the first move-to was computed improperly + // for a contour consisting of all off curve points. + // In this case, the start of the path should be the midpoint between the first and last points. + // For this test case (in 26.6 fixed point): [(640, 128) + (128, 128)] / 2 = (384, 128) + // which becomes (6.0, 2.0) when converted to floating point. + let points = [pt(640, 128), pt(256, 64), pt(640, 64), pt(128, 128)]; + let mut pen = SvgPen::with_precision(1); + to_path(&points, &flags, &contours, path_style, &mut pen).unwrap(); + assert_eq!(pen.as_ref(), expected); + } + + #[test] + fn all_off_curve_to_path_scan_backward() { + assert_off_curve_path_to_svg( + "M6.0,2.0 Q10.0,2.0 7.0,1.5 Q4.0,1.0 7.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Z", + PathStyle::FreeType, + true, + ); + } + + #[test] + fn all_off_curve_to_path_scan_forward() { + assert_off_curve_path_to_svg( + "M7.0,1.5 Q4.0,1.0 7.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Q10.0,2.0 7.0,1.5 Z", + PathStyle::HarfBuzz, + true, + ); + } + + #[test] + fn start_off_curve_to_path_scan_backward() { + assert_off_curve_path_to_svg( + "M6.0,2.0 Q10.0,2.0 4.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Z", + PathStyle::FreeType, + false, + ); + } + + #[test] + fn start_off_curve_to_path_scan_forward() { + assert_off_curve_path_to_svg( + "M4.0,1.0 Q10.0,1.0 6.0,1.5 Q2.0,2.0 6.0,2.0 Q10.0,2.0 4.0,1.0 Z", + PathStyle::HarfBuzz, + false, + ); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,247 @@ +//! Types for collecting the output when drawing a glyph outline. + +use alloc::{string::String, vec::Vec}; +use core::fmt::{self, Write}; + +/// Interface for accepting a sequence of path commands. +pub trait OutlinePen { + /// Emit a command to begin a new subpath at (x, y). + fn move_to(&mut self, x: f32, y: f32); + + /// Emit a line segment from the current point to (x, y). + fn line_to(&mut self, x: f32, y: f32); + + /// Emit a quadratic bezier segment from the current point with a control + /// point at (cx0, cy0) and ending at (x, y). + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32); + + /// Emit a cubic bezier segment from the current point with control + /// points at (cx0, cy0) and (cx1, cy1) and ending at (x, y). + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32); + + /// Emit a command to close the current subpath. + fn close(&mut self); +} + +/// Single element of a path. +#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)] +pub enum PathElement { + /// Begin a new subpath at (x, y). + MoveTo { x: f32, y: f32 }, + /// Draw a line from the current point to (x, y). + LineTo { x: f32, y: f32 }, + /// Draw a quadratic bezier from the current point with a control point at + /// (cx0, cy0) and ending at (x, y). + QuadTo { cx0: f32, cy0: f32, x: f32, y: f32 }, + /// Draw a cubic bezier from the current point with control points at + /// (cx0, cy0) and (cx1, cy1) and ending at (x, y). + CurveTo { + cx0: f32, + cy0: f32, + cx1: f32, + cy1: f32, + x: f32, + y: f32, + }, + /// Close the current subpath. + Close, +} + +/// Style for path conversion. +/// +/// The order to process points in a glyf point stream is ambiguous when the +/// first point is off-curve. Major implementations differ. Which one would +/// you like to match? +/// +/// **If you add a new one make sure to update the fuzzer.** +#[derive(Debug, Default, Copy, Clone)] +pub enum PathStyle { + /// If the first point is off-curve, check if the last is on-curve + /// If it is, start there. If it isn't, start at the implied midpoint + /// between first and last. + #[default] + FreeType, + /// If the first point is off-curve, check if the second is on-curve. + /// If it is, start there. If it isn't, start at the implied midpoint + /// between first and second. + /// + /// Matches hb-draw's interpretation of a point stream. + HarfBuzz, +} + +impl OutlinePen for Vec { + fn move_to(&mut self, x: f32, y: f32) { + self.push(PathElement::MoveTo { x, y }) + } + + fn line_to(&mut self, x: f32, y: f32) { + self.push(PathElement::LineTo { x, y }) + } + + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { + self.push(PathElement::QuadTo { cx0, cy0, x, y }) + } + + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { + self.push(PathElement::CurveTo { + cx0, + cy0, + cx1, + cy1, + x, + y, + }) + } + + fn close(&mut self) { + self.push(PathElement::Close) + } +} + +/// Pen that drops all drawing output into the ether. +pub struct NullPen; + +impl OutlinePen for NullPen { + fn move_to(&mut self, _x: f32, _y: f32) {} + fn line_to(&mut self, _x: f32, _y: f32) {} + fn quad_to(&mut self, _cx0: f32, _cy0: f32, _x: f32, _y: f32) {} + fn curve_to(&mut self, _cx0: f32, _cy0: f32, _cx1: f32, _cy1: f32, _x: f32, _y: f32) {} + fn close(&mut self) {} +} + +/// Pen that generates SVG style path data. +#[derive(Clone, Default, Debug)] +pub struct SvgPen(String, Option); + +impl SvgPen { + /// Creates a new SVG pen that formats floating point values with the + /// standard behavior. + pub fn new() -> Self { + Self::default() + } + + /// Creates a new SVG pen with the given precision (the number of digits + /// that will be printed after the decimal). + pub fn with_precision(precision: usize) -> Self { + Self(String::default(), Some(precision)) + } + + /// Clears the content of the internal string. + pub fn clear(&mut self) { + self.0.clear(); + } + + fn maybe_push_space(&mut self) { + if !self.0.is_empty() { + self.0.push(' '); + } + } +} + +impl core::ops::Deref for SvgPen { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.0.as_str() + } +} + +impl OutlinePen for SvgPen { + fn move_to(&mut self, x: f32, y: f32) { + self.maybe_push_space(); + let _ = if let Some(prec) = self.1 { + write!(self.0, "M{x:.0$},{y:.0$}", prec) + } else { + write!(self.0, "M{x},{y}") + }; + } + + fn line_to(&mut self, x: f32, y: f32) { + self.maybe_push_space(); + let _ = if let Some(prec) = self.1 { + write!(self.0, "L{x:.0$},{y:.0$}", prec) + } else { + write!(self.0, "L{x},{y}") + }; + } + + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { + self.maybe_push_space(); + let _ = if let Some(prec) = self.1 { + write!(self.0, "Q{cx0:.0$},{cy0:.0$} {x:.0$},{y:.0$}", prec) + } else { + write!(self.0, "Q{cx0},{cy0} {x},{y}") + }; + } + + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { + self.maybe_push_space(); + let _ = if let Some(prec) = self.1 { + write!( + self.0, + "C{cx0:.0$},{cy0:.0$} {cx1:.0$},{cy1:.0$} {x:.0$},{y:.0$}", + prec + ) + } else { + write!(self.0, "C{cx0},{cy0} {cx1},{cy1} {x},{y}") + }; + } + + fn close(&mut self) { + self.maybe_push_space(); + self.0.push('Z'); + } +} + +impl AsRef for SvgPen { + fn as_ref(&self) -> &str { + self.0.as_ref() + } +} + +impl From for SvgPen { + fn from(value: String) -> Self { + Self(value, None) + } +} + +impl From for String { + fn from(value: SvgPen) -> Self { + value.0 + } +} + +impl fmt::Display for SvgPen { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn svg_pen_precision() { + let svg_data = [None, Some(1), Some(4)].map(|prec| { + let mut pen = match prec { + None => SvgPen::new(), + Some(prec) => SvgPen::with_precision(prec), + }; + pen.move_to(1.0, 2.45556); + pen.line_to(1.2, 4.0); + pen.quad_to(2.0345, 3.56789, -0.157, -425.07); + pen.curve_to(-37.0010, 4.5, 2.0, 1.0, -0.5, -0.25); + pen.close(); + pen.to_string() + }); + let expected = [ + "M1,2.45556 L1.2,4 Q2.0345,3.56789 -0.157,-425.07 C-37.001,4.5 2,1 -0.5,-0.25 Z", + "M1.0,2.5 L1.2,4.0 Q2.0,3.6 -0.2,-425.1 C-37.0,4.5 2.0,1.0 -0.5,-0.2 Z", + "M1.0000,2.4556 L1.2000,4.0000 Q2.0345,3.5679 -0.1570,-425.0700 C-37.0010,4.5000 2.0000,1.0000 -0.5000,-0.2500 Z" + ]; + for (result, expected) in svg_data.iter().zip(&expected) { + assert_eq!(result, expected); + } + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,173 @@ +//! Helpers for unit testing + +use super::OutlinePen; +use core::str::FromStr; +use raw::{ + tables::glyf::PointFlags, + types::{F26Dot6, F2Dot14, GlyphId, Point}, +}; + +#[derive(Copy, Clone, PartialEq, Debug)] +// clippy doesn't like the common To suffix +#[allow(clippy::enum_variant_names)] +pub enum PathElement { + MoveTo([f32; 2]), + LineTo([f32; 2]), + QuadTo([f32; 4]), + CurveTo([f32; 6]), +} + +#[derive(Default)] +pub struct Path { + pub elements: Vec, + last_end: Option<[f32; 2]>, +} + +impl OutlinePen for Path { + fn move_to(&mut self, x: f32, y: f32) { + self.elements.push(PathElement::MoveTo([x, y])); + self.last_end = Some([x, y]); + } + + fn line_to(&mut self, x: f32, y: f32) { + self.elements.push(PathElement::LineTo([x, y])); + self.last_end = Some([x, y]); + } + + fn quad_to(&mut self, x0: f32, y0: f32, x1: f32, y1: f32) { + self.elements.push(PathElement::QuadTo([x0, y0, x1, y1])); + self.last_end = Some([x1, y1]); + } + + fn curve_to(&mut self, x0: f32, y0: f32, x1: f32, y1: f32, x2: f32, y2: f32) { + self.elements + .push(PathElement::CurveTo([x0, y0, x1, y1, x2, y2])); + self.last_end = Some([x2, y2]); + } + + fn close(&mut self) { + // FT_Outline_Decompose does not generate close commands, so for + // testing purposes, we insert a line to same point as the most + // recent move_to (if the last command didn't end at the same point) + // which copies FreeType's behavior. + let last_move = self + .elements + .iter() + .rev() + .find(|element| matches!(*element, PathElement::MoveTo(_))) + .copied(); + if let Some(PathElement::MoveTo(point)) = last_move { + if Some(point) != self.last_end { + self.elements.push(PathElement::LineTo(point)); + } + } + } +} + +#[derive(Clone, Default, Debug)] +pub struct GlyphOutline { + pub glyph_id: GlyphId, + pub size: f32, + pub coords: Vec, + pub points: Vec>, + pub contours: Vec, + pub flags: Vec, + pub path: Vec, +} + +pub fn parse_glyph_outlines(source: &str) -> Vec { + let mut outlines = vec![]; + let mut cur_outline = GlyphOutline::default(); + for line in source.lines() { + let line = line.trim(); + if line == "-" { + outlines.push(cur_outline.clone()); + } else if line.starts_with("glyph") { + cur_outline = GlyphOutline::default(); + let parts = line.split(' ').collect::>(); + cur_outline.glyph_id = GlyphId::new(parts[1].parse().unwrap()); + cur_outline.size = parts[2].parse().unwrap(); + } else if line.starts_with("coords") { + for coord in line.split(' ').skip(1) { + cur_outline + .coords + .push(F2Dot14::from_f32(coord.parse().unwrap())); + } + } else if line.starts_with("contours") { + for contour in line.split(' ').skip(1) { + cur_outline.contours.push(contour.parse().unwrap()); + } + } else if line.starts_with("points") { + let is_scaled = cur_outline.size != 0.0; + for mut point in parse_points(line.strip_prefix("points").unwrap().trim()) { + if !is_scaled { + point[0] <<= 6; + point[1] <<= 6; + } + cur_outline.points.push(Point { + x: F26Dot6::from_bits(point[0]), + y: F26Dot6::from_bits(point[1]), + }); + } + } else if line.starts_with("tags") { + for tag in line.split(' ').skip(1) { + cur_outline + .flags + .push(PointFlags::from_bits(tag.parse().unwrap())); + } + } else { + match line.as_bytes()[0] { + b'm' => { + let points = parse_points(line.strip_prefix("m ").unwrap().trim()); + cur_outline.path.push(PathElement::MoveTo(points[0])); + } + b'l' => { + let points = parse_points(line.strip_prefix("l ").unwrap().trim()); + cur_outline.path.push(PathElement::LineTo(points[0])); + } + b'q' => { + let points = parse_points(line.strip_prefix("q ").unwrap().trim()); + cur_outline.path.push(PathElement::QuadTo([ + points[0][0], + points[0][1], + points[1][0], + points[1][1], + ])); + } + b'c' => { + let points = parse_points(line.strip_prefix("c ").unwrap().trim()); + cur_outline.path.push(PathElement::CurveTo([ + points[0][0], + points[0][1], + points[1][0], + points[1][1], + points[2][0], + points[2][1], + ])); + } + _ => panic!("unexpected path element"), + } + } + } + outlines +} + +fn parse_points(source: &str) -> Vec<[F; 2]> +where + F: FromStr + Copy + Default, + ::Err: core::fmt::Debug, +{ + let mut points = vec![]; + for point in source.split(' ') { + let point = point.trim(); + if point.is_empty() { + continue; + } + let mut components = [F::default(); 2]; + for (i, component) in point.trim().split(',').take(2).enumerate() { + components[i] = F::from_str(component).unwrap(); + } + points.push(components); + } + points +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,367 @@ +//! Compact representation of an unscaled, unhinted outline. + +#![allow(dead_code)] + +use super::DrawError; +use crate::collections::SmallVec; +use core::ops::Range; +use raw::{ + tables::glyf::PointFlags, + types::{F26Dot6, Point}, +}; + +#[derive(Copy, Clone, Default, Debug)] +pub(super) struct UnscaledPoint { + pub x: i16, + pub y: i16, + pub flags: PointFlags, + pub is_contour_start: bool, +} + +impl UnscaledPoint { + pub fn from_glyf_point( + point: Point, + flags: PointFlags, + is_contour_start: bool, + ) -> Self { + let point = point.map(|x| (x.to_bits() >> 6) as i16); + Self { + x: point.x, + y: point.y, + flags: flags.without_markers(), + is_contour_start, + } + } + + pub fn is_on_curve(self) -> bool { + self.flags.is_on_curve() + } +} + +pub(super) trait UnscaledOutlineSink { + fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError>; + fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError>; + fn extend(&mut self, points: impl IntoIterator) -> Result<(), DrawError> { + for point in points.into_iter() { + self.push(point)?; + } + Ok(()) + } +} + +// please can I have smallvec? +pub(super) struct UnscaledOutlineBuf(SmallVec); + +impl UnscaledOutlineBuf { + pub fn new() -> Self { + Self(SmallVec::new()) + } + + pub fn clear(&mut self) { + self.0.clear(); + } + + pub fn as_ref(&self) -> UnscaledOutlineRef { + UnscaledOutlineRef { + points: self.0.as_slice(), + } + } +} + +impl UnscaledOutlineSink for UnscaledOutlineBuf { + fn try_reserve(&mut self, additional: usize) -> Result<(), DrawError> { + if !self.0.try_reserve(additional) { + Err(DrawError::InsufficientMemory) + } else { + Ok(()) + } + } + + fn push(&mut self, point: UnscaledPoint) -> Result<(), DrawError> { + self.0.push(point); + Ok(()) + } +} + +#[derive(Copy, Clone, Debug)] +pub(super) struct UnscaledOutlineRef<'a> { + pub points: &'a [UnscaledPoint], +} + +impl UnscaledOutlineRef<'_> { + /// Returns the range of contour points and the index of the point within + /// that contour for the last point where `f` returns true. + /// + /// This is common code used for finding extrema when materializing blue + /// zones. + /// + /// For example: + pub fn find_last_contour( + &self, + mut f: impl FnMut(&UnscaledPoint) -> bool, + ) -> Option<(Range, usize)> { + if self.points.is_empty() { + return None; + } + let mut best_contour = 0..0; + // Index of the best point relative to the start of the best contour + let mut best_point = 0; + let mut cur_contour = 0..0; + let mut found_best_in_cur_contour = false; + for (point_ix, point) in self.points.iter().enumerate() { + if point.is_contour_start { + if found_best_in_cur_contour { + best_contour = cur_contour; + } + cur_contour = point_ix..point_ix; + found_best_in_cur_contour = false; + // Ignore single point contours + match self.points.get(point_ix + 1) { + Some(next_point) if next_point.is_contour_start => continue, + None => continue, + _ => {} + } + } + cur_contour.end += 1; + if f(point) { + best_point = point_ix - cur_contour.start; + found_best_in_cur_contour = true; + } + } + if found_best_in_cur_contour { + best_contour = cur_contour; + } + if !best_contour.is_empty() { + Some((best_contour, best_point)) + } else { + None + } + } +} + +/// Adapts an UnscaledOutlineSink to be fed from a pen while tracking +/// memory allocation errors. +pub(super) struct UnscaledPenAdapter<'a, T> { + sink: &'a mut T, + failed: bool, +} + +impl<'a, T> UnscaledPenAdapter<'a, T> { + pub fn new(sink: &'a mut T) -> Self { + Self { + sink, + failed: false, + } + } + + pub fn finish(self) -> Result<(), DrawError> { + if self.failed { + Err(DrawError::InsufficientMemory) + } else { + Ok(()) + } + } +} + +impl UnscaledPenAdapter<'_, T> +where + T: UnscaledOutlineSink, +{ + fn push(&mut self, x: f32, y: f32, flags: PointFlags, is_contour_start: bool) { + if self + .sink + .push(UnscaledPoint { + x: x as i16, + y: y as i16, + flags, + is_contour_start, + }) + .is_err() + { + self.failed = true; + } + } +} + +impl super::OutlinePen for UnscaledPenAdapter<'_, T> { + fn move_to(&mut self, x: f32, y: f32) { + self.push(x, y, PointFlags::on_curve(), true); + } + + fn line_to(&mut self, x: f32, y: f32) { + self.push(x, y, PointFlags::on_curve(), false); + } + + fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) { + self.push(cx0, cy0, PointFlags::off_curve_quad(), false); + self.push(x, y, PointFlags::on_curve(), false); + } + + fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) { + self.push(cx0, cy0, PointFlags::off_curve_cubic(), false); + self.push(cx1, cy1, PointFlags::off_curve_cubic(), false); + self.push(x, y, PointFlags::on_curve(), false); + } + + fn close(&mut self) {} +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{prelude::LocationRef, MetadataProvider}; + use raw::{types::GlyphId, FontRef}; + + #[test] + fn read_glyf_outline() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + let glyph = font.outline_glyphs().get(GlyphId::new(5)).unwrap(); + let mut outline = UnscaledOutlineBuf::<32>::new(); + glyph + .draw_unscaled(LocationRef::default(), None, &mut outline) + .unwrap(); + let outline = outline.as_ref(); + let expected = [ + // contour 0 + (400, 80, 1), + (400, 360, 1), + (320, 360, 1), + (320, 600, 1), + (320, 633, 0), + (367, 680, 0), + (400, 680, 1), + (560, 680, 1), + (593, 680, 0), + (640, 633, 0), + (640, 600, 1), + (640, 360, 1), + (560, 360, 1), + (560, 80, 1), + // contour 1 + (480, 720, 1), + (447, 720, 0), + (400, 767, 0), + (400, 800, 1), + (400, 833, 0), + (447, 880, 0), + (480, 880, 1), + (513, 880, 0), + (560, 833, 0), + (560, 800, 1), + (560, 767, 0), + (513, 720, 0), + ]; + let points = outline + .points + .iter() + .map(|point| (point.x, point.y, point.flags.to_bits())) + .collect::>(); + assert_eq!(points, expected); + } + + #[test] + #[cfg(feature = "spec_next")] + fn read_cubic_glyf_outline() { + let font = FontRef::new(font_test_data::CUBIC_GLYF).unwrap(); + let glyph = font.outline_glyphs().get(GlyphId::new(2)).unwrap(); + let mut outline = UnscaledOutlineBuf::<32>::new(); + glyph + .draw_unscaled(LocationRef::default(), None, &mut outline) + .unwrap(); + let outline = outline.as_ref(); + let expected = [ + // contour 0 + (278, 710, 1), + (278, 470, 1), + (300, 500, 128), + (800, 500, 128), + (998, 470, 1), + (998, 710, 1), + ]; + let points = outline + .points + .iter() + .map(|point| (point.x, point.y, point.flags.to_bits())) + .collect::>(); + assert_eq!(points, expected); + } + + #[test] + fn read_cff_outline() { + let font = FontRef::new(font_test_data::CANTARELL_VF_TRIMMED).unwrap(); + let glyph = font.outline_glyphs().get(GlyphId::new(2)).unwrap(); + let mut outline = UnscaledOutlineBuf::<32>::new(); + glyph + .draw_unscaled(LocationRef::default(), None, &mut outline) + .unwrap(); + let outline = outline.as_ref(); + let expected = [ + // contour 0 + (83, 0, 1), + (163, 0, 1), + (163, 482, 1), + (83, 482, 1), + // contour 1 + (124, 595, 1), + (160, 595, 128), + (181, 616, 128), + (181, 652, 1), + (181, 688, 128), + (160, 709, 128), + (124, 709, 1), + (88, 709, 128), + (67, 688, 128), + (67, 652, 1), + (67, 616, 128), + (88, 595, 128), + (124, 595, 1), + ]; + let points = outline + .points + .iter() + .map(|point| (point.x, point.y, point.flags.to_bits())) + .collect::>(); + assert_eq!(points, expected); + } + + #[test] + fn find_vertical_extrema() { + let font = FontRef::new(font_test_data::MATERIAL_SYMBOLS_SUBSET).unwrap(); + let glyph = font.outline_glyphs().get(GlyphId::new(5)).unwrap(); + let mut outline = UnscaledOutlineBuf::<32>::new(); + glyph + .draw_unscaled(LocationRef::default(), None, &mut outline) + .unwrap(); + let outline = outline.as_ref(); + // Find the maximum Y value and its containing contour + let mut top_y = None; + let (top_contour, top_point_ix) = outline + .find_last_contour(|point| { + if top_y.is_none() || Some(point.y) > top_y { + top_y = Some(point.y); + true + } else { + false + } + }) + .unwrap(); + assert_eq!(top_contour, 14..26); + assert_eq!(top_point_ix, 5); + assert_eq!(top_y, Some(880)); + // Find the minimum Y value and its containing contour + let mut bottom_y = None; + let (bottom_contour, bottom_point_ix) = outline + .find_last_contour(|point| { + if bottom_y.is_none() || Some(point.y) < bottom_y { + bottom_y = Some(point.y); + true + } else { + false + } + }) + .unwrap(); + assert_eq!(bottom_contour, 0..14); + assert_eq!(bottom_point_ix, 0); + assert_eq!(bottom_y, Some(80)); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,104 @@ +use super::{ + attribute::Attributes, + charmap::Charmap, + color::ColorGlyphCollection, + instance::{LocationRef, Size}, + metrics::{GlyphMetrics, Metrics}, + outline::OutlineGlyphCollection, + string::{LocalizedStrings, StringId}, + variation::{AxisCollection, NamedInstanceCollection}, + FontRef, +}; + +/// Interface for types that can provide font metadata. +pub trait MetadataProvider<'a>: Sized { + /// Returns the primary attributes for font classification-- stretch, + /// style and weight. + fn attributes(&self) -> Attributes; + + /// Returns the collection of variation axes. + fn axes(&self) -> AxisCollection<'a>; + + /// Returns the collection of named variation instances. + fn named_instances(&self) -> NamedInstanceCollection<'a>; + + /// Returns an iterator over the collection of localized strings for the + /// given informational string identifier. + fn localized_strings(&self, id: StringId) -> LocalizedStrings<'a>; + + /// Returns the global font metrics for the specified size and location in + /// normalized variation space. + fn metrics(&self, size: Size, location: impl Into>) -> Metrics; + + /// Returns the glyph specific metrics for the specified size and location + /// in normalized variation space. + fn glyph_metrics(&self, size: Size, location: impl Into>) -> GlyphMetrics<'a>; + + /// Returns the character to nominal glyph identifier mapping. + fn charmap(&self) -> Charmap<'a>; + + /// Returns the collection of scalable glyph outlines. + /// + /// If the font contains multiple outline sources, this method prioritizes + /// `glyf`, `CFF2` and `CFF` in that order. To select a specific outline + /// source, use the [`OutlineGlyphCollection::with_format`] method. + fn outline_glyphs(&self) -> OutlineGlyphCollection<'a>; + + // Returns a collection of paintable color glyphs. + fn color_glyphs(&self) -> ColorGlyphCollection<'a>; +} + +impl<'a> MetadataProvider<'a> for FontRef<'a> { + /// Returns the primary attributes for font classification-- stretch, + /// style and weight. + fn attributes(&self) -> Attributes { + Attributes::new(self) + } + + /// Returns the collection of variation axes. + fn axes(&self) -> AxisCollection<'a> { + AxisCollection::new(self) + } + + /// Returns the collection of named variation instances. + fn named_instances(&self) -> NamedInstanceCollection<'a> { + NamedInstanceCollection::new(self) + } + + /// Returns an iterator over the collection of localized strings for the + /// given informational string identifier. + fn localized_strings(&self, id: StringId) -> LocalizedStrings<'a> { + LocalizedStrings::new(self, id) + } + + /// Returns the global font metrics for the specified size and location in + /// normalized variation space. + fn metrics(&self, size: Size, location: impl Into>) -> Metrics { + Metrics::new(self, size, location) + } + + /// Returns the glyph specific metrics for the specified size and location + /// in normalized variation space. + fn glyph_metrics(&self, size: Size, location: impl Into>) -> GlyphMetrics<'a> { + GlyphMetrics::new(self, size, location) + } + + /// Returns the character to nominal glyph identifier mapping. + fn charmap(&self) -> Charmap<'a> { + Charmap::new(self) + } + + /// Returns the collection of scalable glyph outlines. + /// + /// If the font contains multiple outline sources, this method prioritizes + /// `glyf`, `CFF2` and `CFF` in that order. To select a specific outline + /// source, use the [`OutlineGlyphCollection::with_format`] method. + fn outline_glyphs(&self) -> OutlineGlyphCollection<'a> { + OutlineGlyphCollection::new(self) + } + + // Returns a collection of paintable color glyphs. + fn color_glyphs(&self) -> ColorGlyphCollection<'a> { + ColorGlyphCollection::new(self) + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,97 @@ +//! Definitions for specifying variations and typographic features. + +use super::Tag; +use core::str::FromStr; + +/// Setting defined by a selector tag and an associated value. +/// +/// This type is a generic container for properties that can be activated +/// or defined by a `(Tag, T)` pair where the tag selects the target +/// setting and the generic value of type `T` specifies the value for that +/// setting. +/// +/// ## Usage +/// Current usage is for specifying variation axis settings (similar to the +/// CSS property [font-variation-settings](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variation-settings)). +/// See [`VariationSetting`]. +/// +/// In the future, this will likely also be used for specifying feature settings +/// (analogous to the CSS property [font-feature-settings](https://developer.mozilla.org/en-US/docs/Web/CSS/font-feature-settings)) +/// for selecting OpenType [features](https://learn.microsoft.com/en-us/typography/opentype/spec/featuretags). +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct Setting { + /// Tag that specifies the target setting. + pub selector: Tag, + /// The desired value for the setting. + pub value: T, +} + +impl Setting { + /// Creates a new setting from the given selector tag and its associated + /// value. + pub fn new(selector: Tag, value: T) -> Self { + Self { selector, value } + } +} + +// This is provided so that &[VariationSetting] can be passed to the +// variation_settings() method of ScalerBuilder. +impl From<&'_ Setting> for Setting { + fn from(value: &'_ Setting) -> Self { + *value + } +} + +impl From<(Tag, T)> for Setting { + fn from(s: (Tag, T)) -> Self { + Self { + selector: s.0, + value: s.1, + } + } +} + +impl From<&(Tag, T)> for Setting { + fn from(s: &(Tag, T)) -> Self { + Self { + selector: s.0, + value: s.1, + } + } +} + +impl From<(&str, T)> for Setting { + fn from(s: (&str, T)) -> Self { + Self { + selector: Tag::from_str(s.0).unwrap_or_default(), + value: s.1, + } + } +} + +impl From<&(&str, T)> for Setting { + fn from(s: &(&str, T)) -> Self { + Self { + selector: Tag::from_str(s.0).unwrap_or_default(), + value: s.1, + } + } +} + +/// Type for specifying a variation axis setting in user coordinates. +/// +/// The `selector` field should contain a tag that corresponds to a +/// variation axis while the `value` field specifies the desired position +/// on the axis in user coordinates (i.e. within the range defined by +/// the minimum and maximum values of the axis). +/// +/// # Example +/// ``` +/// use skrifa::{Tag, setting::VariationSetting}; +/// +/// // For convenience, a conversion from (&str, f32) is provided. +/// let slightly_bolder: VariationSetting = ("wght", 720.0).into(); +/// +/// assert_eq!(slightly_bolder, VariationSetting::new(Tag::new(b"wght"), 720.0)); +/// ``` +pub type VariationSetting = Setting; diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,649 @@ +//! Localized strings describing font names and other metadata. +//! +//! This provides higher level interfaces for accessing the data in the +//! OpenType [name](https://learn.microsoft.com/en-us/typography/opentype/spec/name) +//! table. +//! +//! # Example +//! The following function will print all localized strings from the set +//! of predefined identifiers in a font: +//! ``` +//! use skrifa::{string::StringId, MetadataProvider}; +//! +//! fn print_well_known_strings<'a>(font: &impl MetadataProvider<'a>) { +//! for id in StringId::predefined() { +//! let strings = font.localized_strings(id); +//! if strings.clone().next().is_some() { +//! println!("[{:?}]", id); +//! for string in font.localized_strings(id) { +//! println!("{:?} {}", string.language(), string.to_string()); +//! } +//! } +//! } +//! } +//! ``` + +use read_fonts::{ + tables::name::{CharIter, Name, NameRecord, NameString}, + TableProvider, +}; + +use core::fmt; + +#[doc(inline)] +pub use read_fonts::types::NameId as StringId; + +/// Iterator over the characters of a string. +#[derive(Clone)] +pub struct Chars<'a> { + inner: Option>, +} + +impl Iterator for Chars<'_> { + type Item = char; + + fn next(&mut self) -> Option { + self.inner.as_mut()?.next() + } +} + +/// Iterator over a collection of localized strings for a specific identifier. +#[derive(Clone)] +pub struct LocalizedStrings<'a> { + name: Option>, + records: core::slice::Iter<'a, NameRecord>, + id: StringId, +} + +impl<'a> LocalizedStrings<'a> { + /// Creates a new localized string iterator from the given font and string identifier. + pub fn new(font: &impl TableProvider<'a>, id: StringId) -> Self { + let name = font.name().ok(); + let records = name + .as_ref() + .map(|name| name.name_record().iter()) + .unwrap_or([].iter()); + Self { name, records, id } + } + + /// Returns the informational string identifier for this iterator. + pub fn id(&self) -> StringId { + self.id + } + + /// Returns the best available English string or the first string in the sequence. + /// + /// This prefers the following languages, in order: "en-US", "en", + /// "" (empty, for bare Unicode platform strings which don't have an associated + /// language). + /// + /// If none of these are found, returns the first string, or `None` if the sequence + /// is empty. + pub fn english_or_first(self) -> Option> { + let mut best_rank = -1; + let mut best_string = None; + for (i, string) in self.enumerate() { + let rank = match (i, string.language()) { + (_, Some("en-US")) => return Some(string), + (_, Some("en")) => 2, + (_, None) => 1, + (0, _) => 0, + _ => continue, + }; + if rank > best_rank { + best_rank = rank; + best_string = Some(string); + } + } + best_string + } +} + +impl<'a> Iterator for LocalizedStrings<'a> { + type Item = LocalizedString<'a>; + + fn next(&mut self) -> Option { + let name = self.name.as_ref()?; + loop { + let record = self.records.next()?; + if record.name_id() == self.id { + return Some(LocalizedString::new(name, record)); + } + } + } +} + +impl Default for LocalizedStrings<'_> { + fn default() -> Self { + Self { + name: None, + records: [].iter(), + id: StringId::default(), + } + } +} + +/// String containing a name or other font metadata in a specific language. +#[derive(Clone, Debug)] +pub struct LocalizedString<'a> { + language: Option, + value: Option>, +} + +impl<'a> LocalizedString<'a> { + fn new(name: &Name<'a>, record: &NameRecord) -> Self { + let language = Language::new(name, record); + let value = record.string(name.string_data()).ok(); + Self { language, value } + } + + /// Returns the BCP-47 language identifier for the localized string. + pub fn language(&self) -> Option<&str> { + self.language.as_ref().map(|language| language.as_str()) + } + + /// Returns an iterator over the characters of the localized string. + pub fn chars(&self) -> Chars<'a> { + Chars { + inner: self.value.map(|value| value.chars()), + } + } +} + +impl fmt::Display for LocalizedString<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for ch in self.chars() { + ch.fmt(f)?; + } + Ok(()) + } +} + +/// This value is chosen arbitrarily to accommodate common language tags that +/// are almost always <= 11 bytes (LLL-SSSS-RR where L is primary language, S +/// is script and R is region) and to keep the Language enum at a reasonable +/// 32 bytes in size. +const MAX_INLINE_LANGUAGE_LEN: usize = 30; + +#[derive(Copy, Clone, Debug)] +#[repr(u8)] +enum Language { + Inline { + buf: [u8; MAX_INLINE_LANGUAGE_LEN], + len: u8, + }, + Static(&'static str), +} + +impl Language { + fn new(name: &Name, record: &NameRecord) -> Option { + let language_id = record.language_id(); + // For version 1 name tables, prefer language tags: + // https://learn.microsoft.com/en-us/typography/opentype/spec/name#naming-table-version-1 + const BASE_LANGUAGE_TAG_ID: u16 = 0x8000; + if name.version() == 1 && language_id >= BASE_LANGUAGE_TAG_ID { + let index = (language_id - BASE_LANGUAGE_TAG_ID) as usize; + let language_string = name + .lang_tag_record()? + .get(index)? + .lang_tag(name.string_data()) + .ok()?; + Self::from_name_string(&language_string) + } else { + match record.platform_id() { + // We only match Macintosh and Windows language ids. + 1 | 3 => Self::from_language_id(language_id), + _ => None, + } + } + } + + /// Decodes a language tag string into an inline ASCII byte sequence. + fn from_name_string(s: &NameString) -> Option { + let mut buf = [0u8; MAX_INLINE_LANGUAGE_LEN]; + let mut len = 0; + for ch in s.chars() { + // From "Tags for Identifying Languages" : + // "Although [RFC5234] refers to octets, the language tags described in + // this document are sequences of characters from the US-ASCII [ISO646] + // repertoire" + // Therefore we assume that non-ASCII characters signal an invalid language tag. + if !ch.is_ascii() || len == MAX_INLINE_LANGUAGE_LEN { + return None; + } + buf[len] = ch as u8; + len += 1; + } + Some(Self::Inline { + buf, + len: len as u8, + }) + } + + fn from_language_id(language_id: u16) -> Option { + Some(Self::Static(language_id_to_bcp47(language_id)?)) + } + + fn as_str(&self) -> &str { + match self { + Self::Inline { buf: data, len } => { + let data = &data[..*len as usize]; + core::str::from_utf8(data).unwrap_or_default() + } + Self::Static(str) => str, + } + } +} + +/// Converts an OpenType language identifier to a BCP-47 language tag. +fn language_id_to_bcp47(language_id: u16) -> Option<&'static str> { + match LANGUAGE_ID_TO_BCP47.binary_search_by(|entry| entry.0.cmp(&language_id)) { + Ok(ix) => LANGUAGE_ID_TO_BCP47.get(ix).map(|entry| entry.1), + _ => None, + } +} + +/// Mapping of OpenType name table language identifier to BCP-47 language tag. +/// Borrowed from Skia: +const LANGUAGE_ID_TO_BCP47: &[(u16, &str)] = &[ + /* A mapping from Mac Language Designators to BCP 47 codes. + * The following list was constructed more or less manually. + * Apple now uses BCP 47 (post OSX10.4), so there will be no new entries. + */ + (0, "en"), //English + (1, "fr"), //French + (2, "de"), //German + (3, "it"), //Italian + (4, "nl"), //Dutch + (5, "sv"), //Swedish + (6, "es"), //Spanish + (7, "da"), //Danish + (8, "pt"), //Portuguese + (9, "nb"), //Norwegian + (10, "he"), //Hebrew + (11, "ja"), //Japanese + (12, "ar"), //Arabic + (13, "fi"), //Finnish + (14, "el"), //Greek + (15, "is"), //Icelandic + (16, "mt"), //Maltese + (17, "tr"), //Turkish + (18, "hr"), //Croatian + (19, "zh-Hant"), //Chinese (Traditional) + (20, "ur"), //Urdu + (21, "hi"), //Hindi + (22, "th"), //Thai + (23, "ko"), //Korean + (24, "lt"), //Lithuanian + (25, "pl"), //Polish + (26, "hu"), //Hungarian + (27, "et"), //Estonian + (28, "lv"), //Latvian + (29, "se"), //Sami + (30, "fo"), //Faroese + (31, "fa"), //Farsi (Persian) + (32, "ru"), //Russian + (33, "zh-Hans"), //Chinese (Simplified) + (34, "nl"), //Dutch + (35, "ga"), //Irish(Gaelic) + (36, "sq"), //Albanian + (37, "ro"), //Romanian + (38, "cs"), //Czech + (39, "sk"), //Slovak + (40, "sl"), //Slovenian + (41, "yi"), //Yiddish + (42, "sr"), //Serbian + (43, "mk"), //Macedonian + (44, "bg"), //Bulgarian + (45, "uk"), //Ukrainian + (46, "be"), //Byelorussian + (47, "uz"), //Uzbek + (48, "kk"), //Kazakh + (49, "az-Cyrl"), //Azerbaijani (Cyrillic) + (50, "az-Arab"), //Azerbaijani (Arabic) + (51, "hy"), //Armenian + (52, "ka"), //Georgian + (53, "mo"), //Moldavian + (54, "ky"), //Kirghiz + (55, "tg"), //Tajiki + (56, "tk"), //Turkmen + (57, "mn-Mong"), //Mongolian (Traditional) + (58, "mn-Cyrl"), //Mongolian (Cyrillic) + (59, "ps"), //Pashto + (60, "ku"), //Kurdish + (61, "ks"), //Kashmiri + (62, "sd"), //Sindhi + (63, "bo"), //Tibetan + (64, "ne"), //Nepali + (65, "sa"), //Sanskrit + (66, "mr"), //Marathi + (67, "bn"), //Bengali + (68, "as"), //Assamese + (69, "gu"), //Gujarati + (70, "pa"), //Punjabi + (71, "or"), //Oriya + (72, "ml"), //Malayalam + (73, "kn"), //Kannada + (74, "ta"), //Tamil + (75, "te"), //Telugu + (76, "si"), //Sinhalese + (77, "my"), //Burmese + (78, "km"), //Khmer + (79, "lo"), //Lao + (80, "vi"), //Vietnamese + (81, "id"), //Indonesian + (82, "tl"), //Tagalog + (83, "ms-Latn"), //Malay (Roman) + (84, "ms-Arab"), //Malay (Arabic) + (85, "am"), //Amharic + (86, "ti"), //Tigrinya + (87, "om"), //Oromo + (88, "so"), //Somali + (89, "sw"), //Swahili + (90, "rw"), //Kinyarwanda/Ruanda + (91, "rn"), //Rundi + (92, "ny"), //Nyanja/Chewa + (93, "mg"), //Malagasy + (94, "eo"), //Esperanto + (128, "cy"), //Welsh + (129, "eu"), //Basque + (130, "ca"), //Catalan + (131, "la"), //Latin + (132, "qu"), //Quechua + (133, "gn"), //Guarani + (134, "ay"), //Aymara + (135, "tt"), //Tatar + (136, "ug"), //Uighur + (137, "dz"), //Dzongkha + (138, "jv-Latn"), //Javanese (Roman) + (139, "su-Latn"), //Sundanese (Roman) + (140, "gl"), //Galician + (141, "af"), //Afrikaans + (142, "br"), //Breton + (143, "iu"), //Inuktitut + (144, "gd"), //Scottish (Gaelic) + (145, "gv"), //Manx (Gaelic) + (146, "ga"), //Irish (Gaelic with Lenition) + (147, "to"), //Tongan + (148, "el"), //Greek (Polytonic) Note: ISO 15924 does not have an equivalent script name. + (149, "kl"), //Greenlandic + (150, "az-Latn"), //Azerbaijani (Roman) + (151, "nn"), //Nynorsk + /* A mapping from Windows LCID to BCP 47 codes. + * This list is the sorted, curated output of tools/win_lcid.cpp. + * Note that these are sorted by value for quick binary lookup, and not logically by lsb. + * The 'bare' language ids (e.g. 0x0001 for Arabic) are omitted + * as they do not appear as valid language ids in the OpenType specification. + */ + (0x0401, "ar-SA"), //Arabic + (0x0402, "bg-BG"), //Bulgarian + (0x0403, "ca-ES"), //Catalan + (0x0404, "zh-TW"), //Chinese (Traditional) + (0x0405, "cs-CZ"), //Czech + (0x0406, "da-DK"), //Danish + (0x0407, "de-DE"), //German + (0x0408, "el-GR"), //Greek + (0x0409, "en-US"), //English + (0x040a, "es-ES_tradnl"), //Spanish + (0x040b, "fi-FI"), //Finnish + (0x040c, "fr-FR"), //French + (0x040d, "he-IL"), //Hebrew + (0x040d, "he"), //Hebrew + (0x040e, "hu-HU"), //Hungarian + (0x040e, "hu"), //Hungarian + (0x040f, "is-IS"), //Icelandic + (0x0410, "it-IT"), //Italian + (0x0411, "ja-JP"), //Japanese + (0x0412, "ko-KR"), //Korean + (0x0413, "nl-NL"), //Dutch + (0x0414, "nb-NO"), //Norwegian (Bokmål) + (0x0415, "pl-PL"), //Polish + (0x0416, "pt-BR"), //Portuguese + (0x0417, "rm-CH"), //Romansh + (0x0418, "ro-RO"), //Romanian + (0x0419, "ru-RU"), //Russian + (0x041a, "hr-HR"), //Croatian + (0x041b, "sk-SK"), //Slovak + (0x041c, "sq-AL"), //Albanian + (0x041d, "sv-SE"), //Swedish + (0x041e, "th-TH"), //Thai + (0x041f, "tr-TR"), //Turkish + (0x0420, "ur-PK"), //Urdu + (0x0421, "id-ID"), //Indonesian + (0x0422, "uk-UA"), //Ukrainian + (0x0423, "be-BY"), //Belarusian + (0x0424, "sl-SI"), //Slovenian + (0x0425, "et-EE"), //Estonian + (0x0426, "lv-LV"), //Latvian + (0x0427, "lt-LT"), //Lithuanian + (0x0428, "tg-Cyrl-TJ"), //Tajik (Cyrillic) + (0x0429, "fa-IR"), //Persian + (0x042a, "vi-VN"), //Vietnamese + (0x042b, "hy-AM"), //Armenian + (0x042c, "az-Latn-AZ"), //Azeri (Latin) + (0x042d, "eu-ES"), //Basque + (0x042e, "hsb-DE"), //Upper Sorbian + (0x042f, "mk-MK"), //Macedonian (FYROM) + (0x0432, "tn-ZA"), //Setswana + (0x0434, "xh-ZA"), //isiXhosa + (0x0435, "zu-ZA"), //isiZulu + (0x0436, "af-ZA"), //Afrikaans + (0x0437, "ka-GE"), //Georgian + (0x0438, "fo-FO"), //Faroese + (0x0439, "hi-IN"), //Hindi + (0x043a, "mt-MT"), //Maltese + (0x043b, "se-NO"), //Sami (Northern) + (0x043e, "ms-MY"), //Malay + (0x043f, "kk-KZ"), //Kazakh + (0x0440, "ky-KG"), //Kyrgyz + (0x0441, "sw-KE"), //Kiswahili + (0x0442, "tk-TM"), //Turkmen + (0x0443, "uz-Latn-UZ"), //Uzbek (Latin) + (0x0443, "uz"), //Uzbek + (0x0444, "tt-RU"), //Tatar + (0x0445, "bn-IN"), //Bengali + (0x0446, "pa-IN"), //Punjabi + (0x0447, "gu-IN"), //Gujarati + (0x0448, "or-IN"), //Oriya + (0x0449, "ta-IN"), //Tamil + (0x044a, "te-IN"), //Telugu + (0x044b, "kn-IN"), //Kannada + (0x044c, "ml-IN"), //Malayalam + (0x044d, "as-IN"), //Assamese + (0x044e, "mr-IN"), //Marathi + (0x044f, "sa-IN"), //Sanskrit + (0x0450, "mn-Cyrl"), //Mongolian (Cyrillic) + (0x0451, "bo-CN"), //Tibetan + (0x0452, "cy-GB"), //Welsh + (0x0453, "km-KH"), //Khmer + (0x0454, "lo-LA"), //Lao + (0x0456, "gl-ES"), //Galician + (0x0457, "kok-IN"), //Konkani + (0x045a, "syr-SY"), //Syriac + (0x045b, "si-LK"), //Sinhala + (0x045d, "iu-Cans-CA"), //Inuktitut (Syllabics) + (0x045e, "am-ET"), //Amharic + (0x0461, "ne-NP"), //Nepali + (0x0462, "fy-NL"), //Frisian + (0x0463, "ps-AF"), //Pashto + (0x0464, "fil-PH"), //Filipino + (0x0465, "dv-MV"), //Divehi + (0x0468, "ha-Latn-NG"), //Hausa (Latin) + (0x046a, "yo-NG"), //Yoruba + (0x046b, "quz-BO"), //Quechua + (0x046c, "nso-ZA"), //Sesotho sa Leboa + (0x046d, "ba-RU"), //Bashkir + (0x046e, "lb-LU"), //Luxembourgish + (0x046f, "kl-GL"), //Greenlandic + (0x0470, "ig-NG"), //Igbo + (0x0478, "ii-CN"), //Yi + (0x047a, "arn-CL"), //Mapudungun + (0x047c, "moh-CA"), //Mohawk + (0x047e, "br-FR"), //Breton + (0x0480, "ug-CN"), //Uyghur + (0x0481, "mi-NZ"), //Maori + (0x0482, "oc-FR"), //Occitan + (0x0483, "co-FR"), //Corsican + (0x0484, "gsw-FR"), //Alsatian + (0x0485, "sah-RU"), //Yakut + (0x0486, "qut-GT"), //K'iche + (0x0487, "rw-RW"), //Kinyarwanda + (0x0488, "wo-SN"), //Wolof + (0x048c, "prs-AF"), //Dari + (0x0491, "gd-GB"), //Scottish Gaelic + (0x0801, "ar-IQ"), //Arabic + (0x0804, "zh-Hans"), //Chinese (Simplified) + (0x0807, "de-CH"), //German + (0x0809, "en-GB"), //English + (0x080a, "es-MX"), //Spanish + (0x080c, "fr-BE"), //French + (0x0810, "it-CH"), //Italian + (0x0813, "nl-BE"), //Dutch + (0x0814, "nn-NO"), //Norwegian (Nynorsk) + (0x0816, "pt-PT"), //Portuguese + (0x081a, "sr-Latn-CS"), //Serbian (Latin) + (0x081d, "sv-FI"), //Swedish + (0x082c, "az-Cyrl-AZ"), //Azeri (Cyrillic) + (0x082e, "dsb-DE"), //Lower Sorbian + (0x082e, "dsb"), //Lower Sorbian + (0x083b, "se-SE"), //Sami (Northern) + (0x083c, "ga-IE"), //Irish + (0x083e, "ms-BN"), //Malay + (0x0843, "uz-Cyrl-UZ"), //Uzbek (Cyrillic) + (0x0845, "bn-BD"), //Bengali + (0x0850, "mn-Mong-CN"), //Mongolian (Traditional Mongolian) + (0x085d, "iu-Latn-CA"), //Inuktitut (Latin) + (0x085f, "tzm-Latn-DZ"), //Tamazight (Latin) + (0x086b, "quz-EC"), //Quechua + (0x0c01, "ar-EG"), //Arabic + (0x0c04, "zh-Hant"), //Chinese (Traditional) + (0x0c07, "de-AT"), //German + (0x0c09, "en-AU"), //English + (0x0c0a, "es-ES"), //Spanish + (0x0c0c, "fr-CA"), //French + (0x0c1a, "sr-Cyrl-CS"), //Serbian (Cyrillic) + (0x0c3b, "se-FI"), //Sami (Northern) + (0x0c6b, "quz-PE"), //Quechua + (0x1001, "ar-LY"), //Arabic + (0x1004, "zh-SG"), //Chinese (Simplified) + (0x1007, "de-LU"), //German + (0x1009, "en-CA"), //English + (0x100a, "es-GT"), //Spanish + (0x100c, "fr-CH"), //French + (0x101a, "hr-BA"), //Croatian (Latin) + (0x103b, "smj-NO"), //Sami (Lule) + (0x1401, "ar-DZ"), //Arabic + (0x1404, "zh-MO"), //Chinese (Traditional) + (0x1407, "de-LI"), //German + (0x1409, "en-NZ"), //English + (0x140a, "es-CR"), //Spanish + (0x140c, "fr-LU"), //French + (0x141a, "bs-Latn-BA"), //Bosnian (Latin) + (0x141a, "bs"), //Bosnian + (0x143b, "smj-SE"), //Sami (Lule) + (0x143b, "smj"), //Sami (Lule) + (0x1801, "ar-MA"), //Arabic + (0x1809, "en-IE"), //English + (0x180a, "es-PA"), //Spanish + (0x180c, "fr-MC"), //French + (0x181a, "sr-Latn-BA"), //Serbian (Latin) + (0x183b, "sma-NO"), //Sami (Southern) + (0x1c01, "ar-TN"), //Arabic + (0x1c09, "en-ZA"), //English + (0x1c0a, "es-DO"), //Spanish + (0x1c1a, "sr-Cyrl-BA"), //Serbian (Cyrillic) + (0x1c3b, "sma-SE"), //Sami (Southern) + (0x1c3b, "sma"), //Sami (Southern) + (0x2001, "ar-OM"), //Arabic + (0x2009, "en-JM"), //English + (0x200a, "es-VE"), //Spanish + (0x201a, "bs-Cyrl-BA"), //Bosnian (Cyrillic) + (0x201a, "bs-Cyrl"), //Bosnian (Cyrillic) + (0x203b, "sms-FI"), //Sami (Skolt) + (0x203b, "sms"), //Sami (Skolt) + (0x2401, "ar-YE"), //Arabic + (0x2409, "en-029"), //English + (0x240a, "es-CO"), //Spanish + (0x241a, "sr-Latn-RS"), //Serbian (Latin) + (0x243b, "smn-FI"), //Sami (Inari) + (0x2801, "ar-SY"), //Arabic + (0x2809, "en-BZ"), //English + (0x280a, "es-PE"), //Spanish + (0x281a, "sr-Cyrl-RS"), //Serbian (Cyrillic) + (0x2c01, "ar-JO"), //Arabic + (0x2c09, "en-TT"), //English + (0x2c0a, "es-AR"), //Spanish + (0x2c1a, "sr-Latn-ME"), //Serbian (Latin) + (0x3001, "ar-LB"), //Arabic + (0x3009, "en-ZW"), //English + (0x300a, "es-EC"), //Spanish + (0x301a, "sr-Cyrl-ME"), //Serbian (Cyrillic) + (0x3401, "ar-KW"), //Arabic + (0x3409, "en-PH"), //English + (0x340a, "es-CL"), //Spanish + (0x3801, "ar-AE"), //Arabic + (0x380a, "es-UY"), //Spanish + (0x3c01, "ar-BH"), //Arabic + (0x3c0a, "es-PY"), //Spanish + (0x4001, "ar-QA"), //Arabic + (0x4009, "en-IN"), //English + (0x400a, "es-BO"), //Spanish + (0x4409, "en-MY"), //English + (0x440a, "es-SV"), //Spanish + (0x4809, "en-SG"), //English + (0x480a, "es-HN"), //Spanish + (0x4c0a, "es-NI"), //Spanish + (0x500a, "es-PR"), //Spanish + (0x540a, "es-US"), //Spanish +]; + +#[cfg(test)] +mod tests { + use crate::MetadataProvider; + + use super::*; + use read_fonts::FontRef; + + #[test] + fn localized() { + let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); + let mut subfamily_names = font + .localized_strings(StringId::SUBFAMILY_NAME) + .map(|s| (s.language().unwrap().to_string(), s.to_string())) + .collect::>(); + subfamily_names.sort_by(|a, b| a.0.cmp(&b.0)); + let expected = [ + (String::from("ar-SA"), String::from("عادي")), + (String::from("el-GR"), String::from("Κανονικά")), + (String::from("en"), String::from("Regular")), + (String::from("eu-ES"), String::from("Arrunta")), + (String::from("pl-PL"), String::from("Normalny")), + (String::from("zh-Hans"), String::from("正常")), + ]; + assert_eq!(subfamily_names.as_slice(), expected); + } + + #[test] + fn find_by_language() { + let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); + assert_eq!( + font.localized_strings(StringId::SUBFAMILY_NAME) + .find(|s| s.language() == Some("pl-PL")) + .unwrap() + .to_string(), + "Normalny" + ); + } + + #[test] + fn english_or_first() { + let font = FontRef::new(font_test_data::NAMES_ONLY).unwrap(); + assert_eq!( + font.localized_strings(StringId::SUBFAMILY_NAME) + .english_or_first() + .unwrap() + .to_string(), + "Regular" + ); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs --- chromium-134.0.6998.35/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs 1970-01-01 00:00:00.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs 2025-03-07 21:29:53.000000000 +0000 @@ -0,0 +1,519 @@ +//! Axes of variation in a variable font. + +use read_fonts::{ + tables::avar::Avar, + tables::fvar::{self, Fvar}, + types::{Fixed, Tag}, + TableProvider, +}; + +use crate::{ + collections::SmallVec, + instance::{Location, NormalizedCoord}, + setting::VariationSetting, + string::StringId, +}; + +/// Axis of variation in a variable font. +/// +/// In variable fonts, an axis usually refers to a single aspect of a +/// typeface's design that can be altered by the user. +/// +/// See +#[derive(Clone)] +pub struct Axis { + index: usize, + record: fvar::VariationAxisRecord, +} + +impl Axis { + /// Returns the tag that identifies the axis. + pub fn tag(&self) -> Tag { + self.record.axis_tag() + } + + /// Returns the index of the axis in its owning collection. + pub fn index(&self) -> usize { + self.index + } + + /// Returns the localized string identifier for the name of the axis. + pub fn name_id(&self) -> StringId { + self.record.axis_name_id() + } + + /// Returns true if the axis should be hidden in user interfaces. + pub fn is_hidden(&self) -> bool { + const AXIS_HIDDEN_FLAG: u16 = 0x1; + self.record.flags() & AXIS_HIDDEN_FLAG != 0 + } + + /// Returns the minimum value of the axis. + pub fn min_value(&self) -> f32 { + self.record.min_value().to_f64() as _ + } + + /// Returns the default value of the axis. + pub fn default_value(&self) -> f32 { + self.record.default_value().to_f64() as _ + } + + /// Returns the maximum value of the axis. + pub fn max_value(&self) -> f32 { + self.record.max_value().to_f64() as _ + } + + /// Returns a normalized coordinate for the given user coordinate. + /// + /// The value will be clamped to the range specified by the minimum + /// and maximum values. + /// + /// This does not apply any axis variation remapping. + pub fn normalize(&self, coord: f32) -> NormalizedCoord { + self.record + .normalize(Fixed::from_f64(coord as _)) + .to_f2dot14() + } +} + +/// Collection of axes in a variable font. +/// +/// Converts user ([fvar](https://learn.microsoft.com/en-us/typography/opentype/spec/fvar)) +/// locations to normalized locations. See [`Self::location`]. +/// +/// See the [`Axis`] type for more detail. +#[derive(Clone)] +pub struct AxisCollection<'a> { + fvar: Option>, + avar: Option>, +} + +impl<'a> AxisCollection<'a> { + /// Creates a new axis collection from the given font. + pub fn new(font: &impl TableProvider<'a>) -> Self { + let fvar = font.fvar().ok(); + let avar = font.avar().ok(); + Self { fvar, avar } + } + + /// Returns the number of variation axes in the font. + pub fn len(&self) -> usize { + self.fvar + .as_ref() + .map(|fvar| fvar.axis_count() as usize) + .unwrap_or(0) + } + + /// Returns true if the collection is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the axis at the given index. + pub fn get(&self, index: usize) -> Option { + let record = *self.fvar.as_ref()?.axes().ok()?.get(index)?; + Some(Axis { index, record }) + } + + /// Returns the axis with the given tag. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// let opsz = Tag::new(b"opsz"); + /// assert_eq!(font.axes().get_by_tag(opsz).unwrap().tag(), opsz); + /// # } + /// ``` + pub fn get_by_tag(&self, tag: Tag) -> Option { + self.iter().find(|axis| axis.tag() == tag) + } + + /// Given an iterator of variation settings in user space, computes an + /// ordered sequence of normalized coordinates. + /// + /// * Setting selectors that don't match an axis are ignored. + /// * Setting values are clamped to the range of their associated axis + /// before normalization. + /// * If more than one setting for an axis is provided, the last one is + /// used. + /// * Omitted settings are set to 0.0, representing the default position + /// in variation space. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// let location = font.axes().location([("wght", 250.0), ("wdth", 75.0)]); + /// # } + /// ``` + pub fn location(&self, settings: I) -> Location + where + I: IntoIterator, + I::Item: Into, + { + let mut location = Location::new(self.len()); + self.location_to_slice(settings, location.coords_mut()); + location + } + + /// Given an iterator of variation settings in user space, computes an + /// ordered sequence of normalized coordinates and stores them in the + /// target slice. + /// + /// * Setting selectors that don't match an axis are ignored. + /// * Setting values are clamped to the range of their associated axis + /// before normalization. + /// * If more than one setting for an axis is provided, the last one is + /// used. + /// * If no setting for an axis is provided, the associated coordinate is + /// set to the normalized value 0.0, representing the default position + /// in variation space. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// let axes = font.axes(); + /// let mut location = vec![NormalizedCoord::default(); axes.len()]; + /// axes.location_to_slice([("wght", 250.0), ("wdth", 75.0)], &mut location); + /// # } + /// ``` + pub fn location_to_slice(&self, settings: I, location: &mut [NormalizedCoord]) + where + I: IntoIterator, + I::Item: Into, + { + if let Some(fvar) = self.fvar.as_ref() { + fvar.user_to_normalized( + self.avar.as_ref(), + settings + .into_iter() + .map(|setting| setting.into()) + .map(|setting| (setting.selector, Fixed::from_f64(setting.value as f64))), + location, + ); + } else { + location.fill(NormalizedCoord::default()); + } + } + + /// Given an iterator of variation settings in user space, returns a + /// new iterator yielding those settings that are valid for this axis + /// collection. + /// + /// * Setting selectors that don't match an axis are dropped. + /// * If more than one setting for an axis is provided, the last one is + /// retained. + /// * Setting values are clamped to the range of their associated axis. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// // Assuming a font contains a single "wght" (weight) axis with range + /// // 100-900: + /// let axes = font.axes(); + /// let filtered: Vec<_> = axes + /// .filter([("wght", 400.0), ("opsz", 100.0), ("wght", 1200.0)]) + /// .collect(); + /// // The first "wght" and "opsz" settings are dropped and the final + /// // "wght" axis is clamped to the maximum value of 900. + /// assert_eq!(&filtered, &[("wght", 900.0).into()]); + /// # } + /// ``` + pub fn filter(&self, settings: I) -> impl Iterator + Clone + where + I: IntoIterator, + I::Item: Into, + { + #[derive(Copy, Clone, Default)] + struct Entry { + tag: Tag, + min: f32, + max: f32, + value: f32, + present: bool, + } + let mut results = SmallVec::<_, 8>::with_len(self.len(), Entry::default()); + for (axis, result) in self.iter().zip(results.as_mut_slice()) { + result.tag = axis.tag(); + result.min = axis.min_value(); + result.max = axis.max_value(); + result.value = axis.default_value(); + } + for setting in settings { + let setting = setting.into(); + for entry in results.as_mut_slice() { + if entry.tag == setting.selector { + entry.value = setting.value.max(entry.min).min(entry.max); + entry.present = true; + } + } + } + results + .into_iter() + .filter(|entry| entry.present) + .map(|entry| VariationSetting::new(entry.tag, entry.value)) + } + + /// Returns an iterator over the axes in the collection. + pub fn iter(&self) -> impl Iterator + 'a + Clone { + let copy = self.clone(); + (0..self.len()).filter_map(move |i| copy.get(i)) + } +} + +/// Named instance of a variation. +/// +/// A set of fixed axis positions selected by the type designer and assigned a +/// name. +/// +/// See +#[derive(Clone)] +pub struct NamedInstance<'a> { + axes: AxisCollection<'a>, + record: fvar::InstanceRecord<'a>, +} + +impl<'a> NamedInstance<'a> { + /// Returns the string identifier for the subfamily name of the instance. + pub fn subfamily_name_id(&self) -> StringId { + self.record.subfamily_name_id + } + + /// Returns the string identifier for the PostScript name of the instance. + pub fn postscript_name_id(&self) -> Option { + self.record.post_script_name_id + } + + /// Returns an iterator over the ordered sequence of user space coordinates + /// that define the instance, one coordinate per axis. + pub fn user_coords(&self) -> impl Iterator + 'a + Clone { + self.record + .coordinates + .iter() + .map(|coord| coord.get().to_f64() as _) + } + + /// Computes a location in normalized variation space for this instance. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// let location = font.named_instances().get(0).unwrap().location(); + /// # } + /// ``` + pub fn location(&self) -> Location { + let mut location = Location::new(self.axes.len()); + self.location_to_slice(location.coords_mut()); + location + } + + /// Computes a location in normalized variation space for this instance and + /// stores the result in the given slice. + /// + /// # Examples + /// + /// ```rust + /// # use skrifa::prelude::*; + /// # fn wrapper(font: &FontRef) { + /// let instance = font.named_instances().get(0).unwrap(); + /// let mut location = vec![NormalizedCoord::default(); instance.user_coords().count()]; + /// instance.location_to_slice(&mut location); + /// # } + /// ``` + pub fn location_to_slice(&self, location: &mut [NormalizedCoord]) { + let settings = self + .axes + .iter() + .map(|axis| axis.tag()) + .zip(self.user_coords()); + self.axes.location_to_slice(settings, location); + } +} + +/// Collection of named instances in a variable font. +/// +/// See the [`NamedInstance`] type for more detail. +#[derive(Clone)] +pub struct NamedInstanceCollection<'a> { + axes: AxisCollection<'a>, +} + +impl<'a> NamedInstanceCollection<'a> { + /// Creates a new instance collection from the given font. + pub fn new(font: &impl TableProvider<'a>) -> Self { + Self { + axes: AxisCollection::new(font), + } + } + + /// Returns the number of instances in the collection. + pub fn len(&self) -> usize { + self.axes + .fvar + .as_ref() + .map(|fvar| fvar.instance_count() as usize) + .unwrap_or(0) + } + + /// Returns true if the collection is empty. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Returns the instance at the given index. + pub fn get(&self, index: usize) -> Option> { + let record = self.axes.fvar.as_ref()?.instances().ok()?.get(index).ok()?; + Some(NamedInstance { + axes: self.axes.clone(), + record, + }) + } + + /// Returns an iterator over the instances in the collection. + pub fn iter(&self) -> impl Iterator> + 'a + Clone { + let copy = self.clone(); + (0..self.len()).filter_map(move |i| copy.get(i)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::MetadataProvider as _; + use font_test_data::VAZIRMATN_VAR; + use read_fonts::FontRef; + use std::str::FromStr; + + #[test] + fn axis() { + let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); + let axis = font.axes().get(0).unwrap(); + assert_eq!(axis.index(), 0); + assert_eq!(axis.tag(), Tag::new(b"wght")); + assert_eq!(axis.min_value(), 100.0); + assert_eq!(axis.default_value(), 400.0); + assert_eq!(axis.max_value(), 900.0); + assert_eq!(axis.name_id(), StringId::new(257)); + assert_eq!( + font.localized_strings(axis.name_id()) + .english_or_first() + .unwrap() + .to_string(), + "Weight" + ); + } + + #[test] + fn named_instances() { + let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); + let named_instances = font.named_instances(); + let thin = named_instances.get(0).unwrap(); + assert_eq!(thin.subfamily_name_id(), StringId::new(258)); + assert_eq!( + font.localized_strings(thin.subfamily_name_id()) + .english_or_first() + .unwrap() + .to_string(), + "Thin" + ); + assert_eq!(thin.location().coords(), &[NormalizedCoord::from_f32(-1.0)]); + let regular = named_instances.get(3).unwrap(); + assert_eq!(regular.subfamily_name_id(), StringId::new(261)); + assert_eq!( + font.localized_strings(regular.subfamily_name_id()) + .english_or_first() + .unwrap() + .to_string(), + "Regular" + ); + assert_eq!( + regular.location().coords(), + &[NormalizedCoord::from_f32(0.0)] + ); + let bold = named_instances.get(6).unwrap(); + assert_eq!(bold.subfamily_name_id(), StringId::new(264)); + assert_eq!( + font.localized_strings(bold.subfamily_name_id()) + .english_or_first() + .unwrap() + .to_string(), + "Bold" + ); + assert_eq!( + bold.location().coords(), + &[NormalizedCoord::from_f32(0.6776123)] + ); + } + + #[test] + fn location() { + let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); + let axes = font.axes(); + let axis = axes.get_by_tag(Tag::from_str("wght").unwrap()).unwrap(); + assert_eq!( + axes.location([("wght", -1000.0)]).coords(), + &[NormalizedCoord::from_f32(-1.0)] + ); + assert_eq!( + axes.location([("wght", 100.0)]).coords(), + &[NormalizedCoord::from_f32(-1.0)] + ); + assert_eq!( + axes.location([("wght", 200.0)]).coords(), + &[NormalizedCoord::from_f32(-0.5)] + ); + assert_eq!( + axes.location([("wght", 400.0)]).coords(), + &[NormalizedCoord::from_f32(0.0)] + ); + // avar table maps 0.8 to 0.83875 + assert_eq!( + axes.location(&[( + "wght", + axis.default_value() + (axis.max_value() - axis.default_value()) * 0.8, + )]) + .coords(), + &[NormalizedCoord::from_f32(0.83875)] + ); + assert_eq!( + axes.location([("wght", 900.0)]).coords(), + &[NormalizedCoord::from_f32(1.0)] + ); + assert_eq!( + axes.location([("wght", 1251.5)]).coords(), + &[NormalizedCoord::from_f32(1.0)] + ); + } + + #[test] + fn filter() { + let font = FontRef::from_index(VAZIRMATN_VAR, 0).unwrap(); + // This font contains one wght axis with the range 100-900 and default + // value of 400. + let axes = font.axes(); + // Drop axes that are not present in the font + let drop_missing: Vec<_> = axes.filter(&[("slnt", 25.0), ("wdth", 50.0)]).collect(); + assert_eq!(&drop_missing, &[]); + // Clamp an out of range value + let clamp: Vec<_> = axes.filter(&[("wght", 50.0)]).collect(); + assert_eq!(&clamp, &[("wght", 100.0).into()]); + // Combination of the above two: drop the missing axis and clamp out of range value + let drop_missing_and_clamp: Vec<_> = + axes.filter(&[("slnt", 25.0), ("wght", 1000.0)]).collect(); + assert_eq!(&drop_missing_and_clamp, &[("wght", 900.0).into()]); + // Ensure we take the later value in the case of duplicates + let drop_duplicate_and_missing: Vec<_> = axes + .filter(&[("wght", 400.0), ("opsz", 100.0), ("wght", 120.5)]) + .collect(); + assert_eq!(&drop_duplicate_and_missing, &[("wght", 120.5).into()]); + } +} diff -Nru chromium-134.0.6998.35/third_party/rust/skrifa/v0_26/BUILD.gn chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/BUILD.gn --- chromium-134.0.6998.35/third_party/rust/skrifa/v0_26/BUILD.gn 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/BUILD.gn 2025-03-07 21:29:53.000000000 +0000 @@ -13,91 +13,92 @@ epoch = "0.26" crate_type = "rlib" crate_root = - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs" + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs" sources = [ - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/attribute.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/charmap.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/collections.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/instance.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/transform.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/color/traversal_tests/test_glyph_defs.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/font.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/instance.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/lib.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/metrics.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/edges.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/hint/outline.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/instance.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/blues.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/scale.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/metrics/widths.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/outline.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/shape.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/style.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/edges.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/autohint/topo/segments.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/hint.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/cff/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/error.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/deltas.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/call_stack.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cow_slice.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/cvt.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/definition.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/arith.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/control_flow.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/cvt.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/data.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/definition.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/delta.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/dispatch.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/graphics.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/logical.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/misc.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/outline.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/round.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/stack.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/engine/storage.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/error.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/graphics.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/instance.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/math.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/program.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/projection.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/round.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/storage.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/value_stack.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/hint/zone.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/memory.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/glyf/outline.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/hint_reliant.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/metrics.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/mod.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/path.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/pen.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/testing.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/outline/unscaled.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/provider.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/setting.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/string.rs", - "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/variation.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/attribute.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/charmap.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/collections.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/instance.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/transform.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/color/traversal_tests/test_glyph_defs.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/font.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/instance.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/lib.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/metrics.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/edges.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/hint/outline.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/instance.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/blues.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/scale.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/metrics/widths.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/outline.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/shape.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/style.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/edges.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/autohint/topo/segments.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/hint.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/cff/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/error.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/deltas.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/call_stack.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cow_slice.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/cvt.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/definition.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/arith.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/control_flow.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/cvt.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/data.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/definition.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/delta.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/dispatch.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/graphics.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/logical.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/misc.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/outline.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/round.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/stack.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/engine/storage.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/error.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/graphics.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/instance.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/math.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/program.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/projection.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/round.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/storage.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/value_stack.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/hint/zone.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/memory.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/glyf/outline.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/hint_reliant.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/memory.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/metrics.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/mod.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/path.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/pen.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/testing.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/outline/unscaled.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/provider.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/setting.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/string.rs", + "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/variation.rs", ] - inputs = [ "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/src/../generated/generated_autohint_styles.rs" ] + inputs = [ "//third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/src/../generated/generated_autohint_styles.rs" ] build_native_rust_unit_tests = false edition = "2021" - cargo_pkg_version = "0.26.5" + cargo_pkg_version = "0.26.6" cargo_pkg_name = "skrifa" cargo_pkg_description = "Metadata reader and glyph scaler for OpenType fonts." library_configs -= [ "//build/config/compiler:chromium_code" ] diff -Nru chromium-134.0.6998.35/third_party/rust/skrifa/v0_26/README.chromium chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/README.chromium --- chromium-134.0.6998.35/third_party/rust/skrifa/v0_26/README.chromium 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/third_party/rust/skrifa/v0_26/README.chromium 2025-03-07 21:29:53.000000000 +0000 @@ -1,9 +1,9 @@ Name: skrifa URL: https://crates.io/crates/skrifa -Version: 0.26.5 -Revision: 57715f398fdc5c4444cd19eb07105fc0df56316c +Version: 0.26.6 +Revision: 0ecc7ac2105be5a44e7d973291f767b35581670e License: Apache-2.0 -License File: //third_party/rust/chromium_crates_io/vendor/skrifa-0.26.5/LICENSE-APACHE +License File: //third_party/rust/chromium_crates_io/vendor/skrifa-0.26.6/LICENSE-APACHE Shipped: yes Security Critical: yes diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/enums.xml chromium-134.0.6998.88/tools/metrics/histograms/enums.xml --- chromium-134.0.6998.35/tools/metrics/histograms/enums.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/enums.xml 2025-03-07 21:29:53.000000000 +0000 @@ -15617,6 +15617,7 @@ + @@ -17504,6 +17505,7 @@ label="OmniboxHistoryQuickProviderAllowMidwordContinuations:enabled"/> + diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml chromium-134.0.6998.88/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml --- chromium-134.0.6998.35/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/metadata/chromeos_settings/histograms.xml 2025-03-07 21:29:53.000000000 +0000 @@ -78,7 +78,7 @@ + enum="BooleanToggled" expires_after="2025-09-23"> diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/metadata/extensions/enums.xml chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/enums.xml --- chromium-134.0.6998.35/tools/metrics/histograms/metadata/extensions/enums.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/enums.xml 2025-03-07 21:29:53.000000000 +0000 @@ -3523,6 +3523,17 @@ + + + + + + + + + + + diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/metadata/extensions/histograms.xml chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/histograms.xml --- chromium-134.0.6998.35/tools/metrics/histograms/metadata/extensions/histograms.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/metadata/extensions/histograms.xml 2025-03-07 21:29:53.000000000 +0000 @@ -5270,6 +5270,18 @@ + + toyoshim@chromium.org + chrome-loading@google.com +

    + Records the reason of kWillProxyForExtension in the ProxyDecision2. This is + recorded if and only if the reason is kWillProxyForExtension when a + URLLoaderFactory is created for renderers. + + + diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/metadata/new_tab_page/enums.xml chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/enums.xml --- chromium-134.0.6998.35/tools/metrics/histograms/metadata/new_tab_page/enums.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/enums.xml 2025-03-07 21:29:53.000000000 +0000 @@ -375,6 +375,11 @@ + + + + + Hash values for the IDs of NTP modules. Each of these values is computed by diff -Nru chromium-134.0.6998.35/tools/metrics/histograms/metadata/new_tab_page/histograms.xml chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/histograms.xml --- chromium-134.0.6998.35/tools/metrics/histograms/metadata/new_tab_page/histograms.xml 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/tools/metrics/histograms/metadata/new_tab_page/histograms.xml 2025-03-07 21:29:53.000000000 +0000 @@ -621,6 +621,20 @@ + + rtatum@google.com + pauladedeji@google.com + chrome-desktop-ntp@google.com + + Records the type of Microsoft Auth (Silent or Popup) whenever Microsoft + authentication is initiated by the NTP. This is only logged on the 1P NTP + when the Microsoft Authentication module and another Microsoft module are + enabled. It can be logged because of an initial login or because an access + token expires. + + + jennserrano@google.com diff -Nru chromium-134.0.6998.35/ui/strings/translations/ax_strings_vi.xtb chromium-134.0.6998.88/ui/strings/translations/ax_strings_vi.xtb --- chromium-134.0.6998.35/ui/strings/translations/ax_strings_vi.xtb 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ui/strings/translations/ax_strings_vi.xtb 2025-03-07 21:29:53.000000000 +0000 @@ -129,7 +129,7 @@ giới thiệu hiện trình đơn tốc độ phát đã mở rộng, có các tùy chọn tự động hoàn thành. -Tắt +Đang tắt hộp tìm kiếm Đang bật Tuần diff -Nru chromium-134.0.6998.35/ui/views/controls/label.cc chromium-134.0.6998.88/ui/views/controls/label.cc --- chromium-134.0.6998.35/ui/views/controls/label.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/ui/views/controls/label.cc 2025-03-07 21:29:53.000000000 +0000 @@ -1428,6 +1428,11 @@ const int width = w.is_bounded() ? w.value() : 0; // SetDisplayRect() has side-effect. The text height will change to respect // width. + // TODO(crbug.com/400028865): full_text_'s eliding behavior should align + // with the label. Currently, it always returns non-elided width, + // effectively preventing the label to shrink. It should be as small as the + // width of "...". This issue currently causes overflow in a horizontal + // layout that has multiple single-line labels. full_text_->SetDisplayRect(gfx::Rect(0, 0, width, 0)); size = full_text_->GetStringSize(); diff -Nru chromium-134.0.6998.35/v8/include/v8-version.h chromium-134.0.6998.88/v8/include/v8-version.h --- chromium-134.0.6998.35/v8/include/v8-version.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/include/v8-version.h 2025-03-07 21:29:53.000000000 +0000 @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 13 #define V8_MINOR_VERSION 4 #define V8_BUILD_NUMBER 114 -#define V8_PATCH_LEVEL 14 +#define V8_PATCH_LEVEL 19 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff -Nru chromium-134.0.6998.35/v8/src/builtins/builtins-json.cc chromium-134.0.6998.88/v8/src/builtins/builtins-json.cc --- chromium-134.0.6998.35/v8/src/builtins/builtins-json.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/builtins-json.cc 2025-03-07 21:29:53.000000000 +0000 @@ -23,7 +23,7 @@ Object::ToString(isolate, source)); string = String::Flatten(isolate, string); RETURN_RESULT_OR_FAILURE( - isolate, string->IsOneByteRepresentation() + isolate, String::IsOneByteRepresentationUnderneath(*string) ? JsonParser::Parse(isolate, string, reviver) : JsonParser::Parse(isolate, string, reviver)); } diff -Nru chromium-134.0.6998.35/v8/src/builtins/builtins-string.cc chromium-134.0.6998.88/v8/src/builtins/builtins-string.cc --- chromium-134.0.6998.35/v8/src/builtins/builtins-string.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/builtins-string.cc 2025-03-07 21:29:53.000000000 +0000 @@ -345,7 +345,7 @@ // character is also ASCII. This is currently the case, but it // might break in the future if we implement more context and locale // dependent upper/lower conversions. - if (s->IsOneByteRepresentation()) { + if (String::IsOneByteRepresentationUnderneath(*s)) { // Same length as input. DirectHandle result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); diff -Nru chromium-134.0.6998.35/v8/src/builtins/ia32/builtins-ia32.cc chromium-134.0.6998.88/v8/src/builtins/ia32/builtins-ia32.cc --- chromium-134.0.6998.35/v8/src/builtins/ia32/builtins-ia32.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/ia32/builtins-ia32.cc 2025-03-07 21:29:53.000000000 +0000 @@ -3485,6 +3485,10 @@ // the parent frame. __ mov(original_fp, ebp); LoadTargetJumpBuffer(masm, target_continuation, wasm::JumpBuffer::Suspended); + // Return address slot. The builtin itself returns by switching to the parent + // jump buffer and does not actually use this slot, but it is read by the + // profiler. + __ Push(Immediate(0)); // Push the loaded ebp. We know it is null, because there is no frame yet, // so we could also push 0 directly. In any case we need to push it, because // this marks the base of the stack segment for the stack frame iterator. diff -Nru chromium-134.0.6998.35/v8/src/builtins/string-iswellformed.tq chromium-134.0.6998.88/v8/src/builtins/string-iswellformed.tq --- chromium-134.0.6998.35/v8/src/builtins/string-iswellformed.tq 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/string-iswellformed.tq 2025-03-07 21:29:53.000000000 +0000 @@ -35,7 +35,7 @@ // InstanceType. See // https://docs.google.com/document/d/15f-1c_Ysw3lvjy_Gx0SmmD9qeO8UuXuAbWIpWCnTDO8/ const flat = Flatten(s); - if (flat.IsOneByteRepresentation()) return True; + if (flat.IsOneByteRepresentationUnderneath()) return True; try { const illFormed = HasUnpairedSurrogate(flat) otherwise Indirect; return illFormed ? False : True; diff -Nru chromium-134.0.6998.35/v8/src/builtins/string-towellformed.tq chromium-134.0.6998.88/v8/src/builtins/string-towellformed.tq --- chromium-134.0.6998.35/v8/src/builtins/string-towellformed.tq 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/string-towellformed.tq 2025-03-07 21:29:53.000000000 +0000 @@ -33,7 +33,7 @@ // 4. Let k be 0. // 5. Let result be the empty String. const flat = Flatten(s); - if (flat.IsOneByteRepresentation()) return flat; + if (flat.IsOneByteRepresentationUnderneath()) return flat; let result = flat; // 6. Repeat, while k < strLen, diff -Nru chromium-134.0.6998.35/v8/src/builtins/x64/builtins-x64.cc chromium-134.0.6998.88/v8/src/builtins/x64/builtins-x64.cc --- chromium-134.0.6998.35/v8/src/builtins/x64/builtins-x64.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/builtins/x64/builtins-x64.cc 2025-03-07 21:29:53.000000000 +0000 @@ -3616,6 +3616,10 @@ // the parent frame. __ movq(original_fp, rbp); LoadTargetJumpBuffer(masm, target_continuation, wasm::JumpBuffer::Suspended); + // Return address slot. The builtin itself returns by switching to the parent + // jump buffer and does not actually use this slot, but it is read by the + // profiler. + __ Push(Immediate(kNullAddress)); // Push the loaded rbp. We know it is null, because there is no frame yet, // so we could also push 0 directly. In any case we need to push it, because // this marks the base of the stack segment for the stack frame iterator. diff -Nru chromium-134.0.6998.35/v8/src/compiler/node-properties.cc chromium-134.0.6998.88/v8/src/compiler/node-properties.cc --- chromium-134.0.6998.35/v8/src/compiler/node-properties.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/compiler/node-properties.cc 2025-03-07 21:29:53.000000000 +0000 @@ -451,6 +451,9 @@ ElementsTransitionWithMultipleSourcesOf(effect->op()).target()}; return result; } + // `receiver` and `object` might alias, so + // TransitionElementsKindOrCheckMaps might change receiver's map. + result = kUnreliableMaps; break; } case IrOpcode::kJSCreate: { diff -Nru chromium-134.0.6998.35/v8/src/execution/frames.h chromium-134.0.6998.88/v8/src/execution/frames.h --- chromium-134.0.6998.35/v8/src/execution/frames.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/execution/frames.h 2025-03-07 21:29:53.000000000 +0000 @@ -1850,11 +1850,6 @@ void AdvanceOneFrame(); bool IsValidStackAddress(Address addr) const { -#if V8_ENABLE_WEBASSEMBLY - for (const std::unique_ptr& stack : wasm_stacks_) { - if (stack->Contains(addr)) return true; - } -#endif return low_bound_ <= addr && addr <= high_bound_; } bool IsValidState(const StackFrame::State& frame) const; diff -Nru chromium-134.0.6998.35/v8/src/json/json-stringifier.cc chromium-134.0.6998.88/v8/src/json/json-stringifier.cc --- chromium-134.0.6998.35/v8/src/json/json-stringifier.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/json/json-stringifier.cc 2025-03-07 21:29:53.000000000 +0000 @@ -155,25 +155,29 @@ const DisallowGarbageCollection& no_gc) { DCHECK_EQ(length, string->length()); DCHECK(encoding_ == String::TWO_BYTE_ENCODING || - (string->IsFlat() && string->IsOneByteRepresentation())); + (string->IsFlat() && + String::IsOneByteRepresentationUnderneath(string))); DCHECK(CurrentPartCanFit(length + 1)); - String::FlatContent flat = string->GetFlatContent(no_gc); if (encoding_ == String::ONE_BYTE_ENCODING) { - if (flat.IsOneByte()) { - CopyChars(one_byte_ptr_ + current_index_, - flat.ToOneByteVector().begin(), length); + if (String::IsOneByteRepresentationUnderneath(string)) { + CopyChars( + one_byte_ptr_ + current_index_, + string->GetCharVector(no_gc).begin(), length); } else { ChangeEncoding(); - CopyChars(two_byte_ptr_ + current_index_, - flat.ToUC16Vector().begin(), length); + CopyChars( + two_byte_ptr_ + current_index_, + string->GetCharVector(no_gc).begin(), length); } } else { - if (flat.IsOneByte()) { - CopyChars(two_byte_ptr_ + current_index_, - flat.ToOneByteVector().begin(), length); + if (String::IsOneByteRepresentationUnderneath(string)) { + CopyChars( + two_byte_ptr_ + current_index_, + string->GetCharVector(no_gc).begin(), length); } else { - CopyChars(two_byte_ptr_ + current_index_, - flat.ToUC16Vector().begin(), length); + CopyChars( + two_byte_ptr_ + current_index_, + string->GetCharVector(no_gc).begin(), length); } } current_index_ += length; @@ -186,7 +190,8 @@ Tagged string = *string_handle; const bool representation_ok = encoding_ == String::TWO_BYTE_ENCODING || - (string->IsFlat() && string->IsOneByteRepresentation()); + (string->IsFlat() && + String::IsOneByteRepresentationUnderneath(string)); if (representation_ok) { size_t length = string->length(); while (!CurrentPartCanFit(length + 1)) { @@ -1528,7 +1533,8 @@ vector, &no_extend); } else { DCHECK(encoding_ == String::TWO_BYTE_ENCODING || - (string->IsFlat() && string->IsOneByteRepresentation())); + (string->IsFlat() && + String::IsOneByteRepresentationUnderneath(string))); int prev_escaped_offset = -1; for (int i = 0; i < vector.length(); i++) { SrcChar c = vector.at(i); @@ -1689,14 +1695,14 @@ DisallowGarbageCollection no_gc; auto string = *object; if (encoding_ == String::ONE_BYTE_ENCODING) { - if (string->IsOneByteRepresentation()) { + if (String::IsOneByteRepresentationUnderneath(string)) { return SerializeString_(string, no_gc); } else { ChangeEncoding(); } } DCHECK_EQ(encoding_, String::TWO_BYTE_ENCODING); - if (string->IsOneByteRepresentation()) { + if (String::IsOneByteRepresentationUnderneath(string)) { return SerializeString_(string, no_gc); } else { return SerializeString_(string, no_gc); diff -Nru chromium-134.0.6998.35/v8/src/maglev/maglev-graph-builder.cc chromium-134.0.6998.88/v8/src/maglev/maglev-graph-builder.cc --- chromium-134.0.6998.35/v8/src/maglev/maglev-graph-builder.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/maglev/maglev-graph-builder.cc 2025-03-07 21:29:53.000000000 +0000 @@ -12487,7 +12487,13 @@ CreateHeapNumber(node->Cast()->value()), allocation_type); } else { - node = GetTaggedValue(node); + ValueNode* new_node = GetTaggedValue(node); + if (new_node != node && new_node->properties().can_allocate()) { + // TODO(olivf): Remove this and instead always clear when we + // emit an allocating instruction. + ClearCurrentAllocationBlock(); + } + node = new_node; } values[i] = node; } diff -Nru chromium-134.0.6998.35/v8/src/numbers/conversions.cc chromium-134.0.6998.88/v8/src/numbers/conversions.cc --- chromium-134.0.6998.35/v8/src/numbers/conversions.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/numbers/conversions.cc 2025-03-07 21:29:53.000000000 +0000 @@ -343,7 +343,7 @@ bool IsOneByte() const { if (raw_two_byte_subject_ != nullptr) return false; return raw_one_byte_subject_ != nullptr || - subject_->IsOneByteRepresentation(); + String::IsOneByteRepresentationUnderneath(*subject_); } base::Vector GetOneByteVector( @@ -1364,7 +1364,7 @@ return std::nullopt; } - if (object->IsOneByteRepresentation()) { + if (String::IsOneByteRepresentationUnderneath(*object)) { uint8_t buffer[kMaxLengthForConversion]; SharedStringAccessGuardIfNeeded access_guard(isolate); String::WriteToFlat(*object, buffer, 0, length, access_guard); diff -Nru chromium-134.0.6998.35/v8/src/objects/js-raw-json.cc chromium-134.0.6998.88/v8/src/objects/js-raw-json.cc --- chromium-134.0.6998.35/v8/src/objects/js-raw-json.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/js-raw-json.cc 2025-03-07 21:29:53.000000000 +0000 @@ -20,7 +20,7 @@ ASSIGN_RETURN_ON_EXCEPTION(isolate, json_string, Object::ToString(isolate, text)); Handle flat = String::Flatten(isolate, json_string); - if (flat->IsOneByteRepresentation()) { + if (String::IsOneByteRepresentationUnderneath(*flat)) { if (!JsonParser::CheckRawJson(isolate, flat)) { DCHECK(isolate->has_exception()); return MaybeDirectHandle(); diff -Nru chromium-134.0.6998.35/v8/src/objects/js-regexp.cc chromium-134.0.6998.88/v8/src/objects/js-regexp.cc --- chromium-134.0.6998.35/v8/src/objects/js-regexp.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/js-regexp.cc 2025-03-07 21:29:53.000000000 +0000 @@ -300,7 +300,7 @@ DirectHandle source) { DCHECK(source->IsFlat()); if (source->length() == 0) return isolate->factory()->query_colon_string(); - bool one_byte = source->IsOneByteRepresentation(); + bool one_byte = String::IsOneByteRepresentationUnderneath(*source); bool needs_escapes = false; int additional_escape_chars = one_byte ? CountAdditionalEscapeChars(source, &needs_escapes) diff -Nru chromium-134.0.6998.35/v8/src/objects/map.h chromium-134.0.6998.88/v8/src/objects/map.h --- chromium-134.0.6998.35/v8/src/objects/map.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/map.h 2025-03-07 21:29:53.000000000 +0000 @@ -1109,9 +1109,6 @@ inline bool IsSpecialReceiverMap(Tagged map); inline bool IsCustomElementsReceiverMap(Tagged map); -// Define the instance type accessors in the `.h` instead of `-inl.h` to avoid -// a circular dependency with the instance-type-inl.h header. - InstanceType Map::instance_type() const { // TODO(solanes, v8:7790, v8:11353, v8:11945): Make this and the setter // non-atomic when TSAN sees the map's store synchronization. diff -Nru chromium-134.0.6998.35/v8/src/objects/string-inl.h chromium-134.0.6998.88/v8/src/objects/string-inl.h --- chromium-134.0.6998.35/v8/src/objects/string-inl.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/string-inl.h 2025-03-07 21:29:53.000000000 +0000 @@ -365,6 +365,24 @@ return InstanceTypeChecker::IsTwoByteString(map()); } +// static +bool String::IsOneByteRepresentationUnderneath(Tagged string) { + while (true) { + uint32_t type = string->map()->instance_type(); + static_assert(kIsIndirectStringTag != 0); + static_assert((kIsIndirectStringMask & kStringEncodingMask) == 0); + DCHECK(string->IsFlat()); + switch (type & (kIsIndirectStringMask | kStringEncodingMask)) { + case kOneByteStringTag: + return true; + case kTwoByteStringTag: + return false; + default: // Cons, sliced, thin, strings need to go deeper. + string = string->GetUnderlying(); + } + } +} + base::uc32 FlatStringReader::Get(uint32_t index) const { if (is_one_byte_) { return Get(index); @@ -1099,7 +1117,7 @@ // InstanceType. See // https://docs.google.com/document/d/15f-1c_Ysw3lvjy_Gx0SmmD9qeO8UuXuAbWIpWCnTDO8/ string = Flatten(isolate, string); - if (string->IsOneByteRepresentation()) return true; + if (String::IsOneByteRepresentationUnderneath(*string)) return true; DisallowGarbageCollection no_gc; String::FlatContent flat = string->GetFlatContent(no_gc); DCHECK(flat.IsFlat()); diff -Nru chromium-134.0.6998.35/v8/src/objects/string.h chromium-134.0.6998.88/v8/src/objects/string.h --- chromium-134.0.6998.35/v8/src/objects/string.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/string.h 2025-03-07 21:29:53.000000000 +0000 @@ -232,10 +232,19 @@ inline void set_length(uint32_t hash); inline void set_length(uint32_t hash, ReleaseStoreTag); - // Returns whether this string is stored with one-byte chars. + // Returns whether this string has only one-byte chars, i.e. all of them can + // be one-byte encoded. This might be the case even if the string is + // two-byte. Such strings may appear when the embedder prefers + // two-byte external representations even for one-byte data. inline bool IsOneByteRepresentation() const; inline bool IsTwoByteRepresentation() const; + // Cons and slices have an encoding flag that may not represent the actual + // encoding of the underlying string. This is taken into account here. + // This function is static because that helps it get inlined. + // Requires: string.IsFlat() + static inline bool IsOneByteRepresentationUnderneath(Tagged string); + // Get and set individual two byte chars in the string. inline void Set(uint32_t index, uint16_t value); // Get individual two byte char in the string. Repeated calls diff -Nru chromium-134.0.6998.35/v8/src/objects/string.tq chromium-134.0.6998.88/v8/src/objects/string.tq --- chromium-134.0.6998.35/v8/src/objects/string.tq 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/string.tq 2025-03-07 21:29:53.000000000 +0000 @@ -21,6 +21,33 @@ return IsOneByteStringMap(this.map); } + // Keep this in sync with the C++ String::IsOneByteRepresentationUnderneath. + macro IsOneByteRepresentationUnderneath(): bool { + let string = this; + while (true) { + typeswitch (string) { + case (cons: ConsString): { + dcheck(cons.IsFlat()); + string = cons.first; + } + case (thin: ThinString): { + // Internalized strings can't change representation. + dcheck( + thin.IsOneByteRepresentation() == + thin.actual.IsOneByteRepresentation()); + return thin.IsOneByteRepresentation(); + } + case (slice: SlicedString): { + string = slice.parent; + } + case (str: String): { + return str.IsOneByteRepresentation(); + } + } + } + VerifiedUnreachable(); + } + const length: int32; } diff -Nru chromium-134.0.6998.35/v8/src/objects/templates-inl.h chromium-134.0.6998.88/v8/src/objects/templates-inl.h --- chromium-134.0.6998.35/v8/src/objects/templates-inl.h 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/objects/templates-inl.h 2025-03-07 21:29:53.000000000 +0000 @@ -6,6 +6,7 @@ #define V8_OBJECTS_TEMPLATES_INL_H_ #include "src/heap/heap-write-barrier-inl.h" +#include "src/objects/dictionary.h" #include "src/objects/objects-inl.h" #include "src/objects/oddball.h" #include "src/objects/shared-function-info.h" diff -Nru chromium-134.0.6998.35/v8/src/profiler/tick-sample.cc chromium-134.0.6998.88/v8/src/profiler/tick-sample.cc --- chromium-134.0.6998.35/v8/src/profiler/tick-sample.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/profiler/tick-sample.cc 2025-03-07 21:29:53.000000000 +0000 @@ -257,6 +257,19 @@ i::Address js_entry_sp = isolate->js_entry_sp(); if (js_entry_sp == 0) return true; // Not executing JS now. +#if V8_ENABLE_WEBASSEMBLY + // With stack-switching, the js_entry_sp and current sp may be in different + // stacks. Use the active stack base instead as the upper bound to correctly + // validate addresses in the stack frame iterator. + Tagged cont_obj = isolate->root(RootIndex::kActiveContinuation); + if (!IsUndefined(cont_obj)) { + auto cont = Cast(cont_obj); + if (!IsUndefined(cont->parent())) { + auto* stack = reinterpret_cast(cont->stack()); + js_entry_sp = stack->base(); + } + } +#endif #if defined(USE_SIMULATOR) if (use_simulator_reg_state) { diff -Nru chromium-134.0.6998.35/v8/src/regexp/experimental/experimental-interpreter.cc chromium-134.0.6998.88/v8/src/regexp/experimental/experimental-interpreter.cc --- chromium-134.0.6998.35/v8/src/regexp/experimental/experimental-interpreter.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/regexp/experimental/experimental-interpreter.cc 2025-03-07 21:29:53.000000000 +0000 @@ -760,7 +760,12 @@ isolate_->StackOverflow(); return RegExp::kInternalRegExpException; } else if (check.InterruptRequested()) { - const bool was_one_byte = input_object_->IsOneByteRepresentation(); + // TODO(mbid): Is this really equivalent to whether the string is + // one-byte or two-byte? A comment at the declaration of + // IsOneByteRepresentationUnderneath says that this might fail for + // external strings. + const bool was_one_byte = + String::IsOneByteRepresentationUnderneath(input_object_); Tagged result; { @@ -774,7 +779,8 @@ // If we changed between a LATIN1 and a UC16 string, we need to restart // regexp matching with the appropriate template instantiation of // RawMatch. - if (input_handle->IsOneByteRepresentation() != was_one_byte) { + if (String::IsOneByteRepresentationUnderneath(*input_handle) != + was_one_byte) { return RegExp::kInternalRegExpRetry; } diff -Nru chromium-134.0.6998.35/v8/src/regexp/regexp-interpreter.cc chromium-134.0.6998.88/v8/src/regexp/regexp-interpreter.cc --- chromium-134.0.6998.35/v8/src/regexp/regexp-interpreter.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/regexp/regexp-interpreter.cc 2025-03-07 21:29:53.000000000 +0000 @@ -294,7 +294,7 @@ return ThrowStackOverflow(isolate, call_origin); } else if (check.InterruptRequested()) { const bool was_one_byte = - (*subject_string_out)->IsOneByteRepresentation(); + String::IsOneByteRepresentationUnderneath(*subject_string_out); Tagged result; { AllowGarbageCollection yes_gc; @@ -307,7 +307,8 @@ // If we changed between a LATIN1 and a UC16 string, we need to // restart regexp matching with the appropriate template instantiation of // RawMatch. - if (subject_handle->IsOneByteRepresentation() != was_one_byte) { + if (String::IsOneByteRepresentationUnderneath(*subject_handle) != + was_one_byte) { return IrregexpInterpreter::RETRY; } @@ -1074,7 +1075,7 @@ bool is_any_unicode = IsEitherUnicode(JSRegExp::AsRegExpFlags(regexp_data->flags())); - bool is_one_byte = subject_string->IsOneByteRepresentation(); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(subject_string); Tagged code_array = regexp_data->bytecode(is_one_byte); int total_register_count = regexp_data->max_register_count(); diff -Nru chromium-134.0.6998.35/v8/src/regexp/regexp-macro-assembler.cc chromium-134.0.6998.88/v8/src/regexp/regexp-macro-assembler.cc --- chromium-134.0.6998.35/v8/src/regexp/regexp-macro-assembler.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/regexp/regexp-macro-assembler.cc 2025-03-07 21:29:53.000000000 +0000 @@ -319,7 +319,7 @@ DirectHandle code_handle(re_code, isolate); DirectHandle subject_handle(Cast(Tagged(*subject)), isolate); - bool is_one_byte = subject_handle->IsOneByteRepresentation(); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject_handle); int return_value = 0; { @@ -349,7 +349,8 @@ // If we continue, we need to update the subject string addresses. if (return_value == 0) { // String encoding might have changed. - if (subject_handle->IsOneByteRepresentation() != is_one_byte) { + if (String::IsOneByteRepresentationUnderneath(*subject_handle) != + is_one_byte) { // If we changed between an LATIN1 and an UC16 string, the specialized // code cannot be used, and we need to restart regexp matching from // scratch (including, potentially, compiling a new version of the code). @@ -430,7 +431,7 @@ int start_offset, const uint8_t* input_start, const uint8_t* input_end, int* output, int output_size, Isolate* isolate, Tagged regexp_data) { - bool is_one_byte = input->IsOneByteRepresentation(); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(input); Tagged code = regexp_data->code(isolate, is_one_byte); RegExp::CallOrigin call_origin = RegExp::CallOrigin::kFromRuntime; diff -Nru chromium-134.0.6998.35/v8/src/regexp/regexp.cc chromium-134.0.6998.88/v8/src/regexp/regexp.cc --- chromium-134.0.6998.35/v8/src/regexp/regexp.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/regexp/regexp.cc 2025-03-07 21:29:53.000000000 +0000 @@ -699,7 +699,7 @@ DCHECK(subject->IsFlat()); // Check representation of the underlying storage. - bool is_one_byte = subject->IsOneByteRepresentation(); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject); if (!RegExpImpl::EnsureCompiledIrregexp(isolate, re_data, subject, is_one_byte)) { return -1; @@ -720,7 +720,7 @@ DCHECK_GE(output_size, JSRegExp::RegistersForCaptureCount(regexp_data->capture_count())); - bool is_one_byte = subject->IsOneByteRepresentation(); + bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject); if (!regexp_data->ShouldProduceBytecode()) { do { @@ -748,7 +748,7 @@ // the, potentially, different subject (the string can switch between // being internal and external, and even between being Latin1 and // UC16, but the characters are always the same). - is_one_byte = subject->IsOneByteRepresentation(); + is_one_byte = String::IsOneByteRepresentationUnderneath(*subject); } while (true); UNREACHABLE(); } else { @@ -773,7 +773,7 @@ // The string has changed representation, and we must restart the // match. We need to reset the tier up to start over with compilation. if (v8_flags.regexp_tier_up) regexp_data->ResetLastTierUpTick(); - is_one_byte = subject->IsOneByteRepresentation(); + is_one_byte = String::IsOneByteRepresentationUnderneath(*subject); EnsureCompiledIrregexp(isolate, regexp_data, subject, is_one_byte); } else { DCHECK(result == IrregexpInterpreter::EXCEPTION || diff -Nru chromium-134.0.6998.35/v8/src/runtime/runtime-strings.cc chromium-134.0.6998.88/v8/src/runtime/runtime-strings.cc --- chromium-134.0.6998.35/v8/src/runtime/runtime-strings.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/runtime/runtime-strings.cc 2025-03-07 21:29:53.000000000 +0000 @@ -480,7 +480,7 @@ DirectHandle source = args.at(0); if (String::IsWellFormedUnicode(isolate, source)) return *source; // String::IsWellFormedUnicode would have returned true above otherwise. - DCHECK(!source->IsOneByteRepresentation()); + DCHECK(!String::IsOneByteRepresentationUnderneath(*source)); const int length = source->length(); DirectHandle dest = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); diff -Nru chromium-134.0.6998.35/v8/src/strings/string-builder.cc chromium-134.0.6998.88/v8/src/strings/string-builder.cc --- chromium-134.0.6998.35/v8/src/strings/string-builder.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/strings/string-builder.cc 2025-03-07 21:29:53.000000000 +0000 @@ -315,7 +315,7 @@ bool IncrementalStringBuilder::CanAppendByCopy(DirectHandle string) { const bool representation_ok = encoding_ == String::TWO_BYTE_ENCODING || - (string->IsFlat() && string->IsOneByteRepresentation()); + (string->IsFlat() && String::IsOneByteRepresentationUnderneath(*string)); return representation_ok && CurrentPartCanFit(string->length()); } diff -Nru chromium-134.0.6998.35/v8/src/strings/uri.cc chromium-134.0.6998.88/v8/src/strings/uri.cc --- chromium-134.0.6998.35/v8/src/strings/uri.cc 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/src/strings/uri.cc 2025-03-07 21:29:53.000000000 +0000 @@ -506,7 +506,7 @@ MaybeDirectHandle Uri::Escape(Isolate* isolate, Handle string) { string = String::Flatten(isolate, string); - return string->IsOneByteRepresentation() + return String::IsOneByteRepresentationUnderneath(*string) ? EscapePrivate(isolate, string) : EscapePrivate(isolate, string); } @@ -514,7 +514,7 @@ MaybeDirectHandle Uri::Unescape(Isolate* isolate, Handle string) { string = String::Flatten(isolate, string); - return string->IsOneByteRepresentation() + return String::IsOneByteRepresentationUnderneath(*string) ? UnescapePrivate(isolate, string) : UnescapePrivate(isolate, string); } diff -Nru chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/meta.json chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/meta.json --- chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/meta.json 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/meta.json 2025-03-07 21:29:53.000000000 +0000 @@ -1 +1 @@ -{"build_link": "https://cr-buildbucket.appspot.com/build/8722032866966730625", "profile": ["x86", "x64", "x86-rl", "x64-rl"], "revision": "debba63b78f8791411bff379835982cb2e8cabfa", "version": "13.4.114.14"} \ No newline at end of file +{"build_link": "https://cr-buildbucket.appspot.com/build/8721057780958920321", "profile": ["x86", "x64", "x86-rl", "x64-rl"], "revision": "a57459aad9ec3ed5f78d9ded700d52e31029efd2", "version": "13.4.114.19"} \ No newline at end of file diff -Nru chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x64-rl.profile chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64-rl.profile --- chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x64-rl.profile 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64-rl.profile 2025-03-07 21:29:53.000000000 +0000 @@ -13,7 +13,6 @@ block_hint,RecordWriteSaveFP,61,51,0 block_hint,RecordWriteSaveFP,53,52,1 block_hint,RecordWriteSaveFP,55,56,1 -block_hint,RecordWriteIgnoreFP,14,1,0 block_hint,RecordWriteIgnoreFP,2,3,0 block_hint,RecordWriteIgnoreFP,5,4,1 block_hint,RecordWriteIgnoreFP,11,6,0 @@ -532,6 +531,7 @@ block_hint,StoreIC_NoFeedback,160,159,1 block_hint,StoreIC_NoFeedback,166,165,1 block_hint,StoreIC_NoFeedback,171,170,0 +block_hint,StoreIC_NoFeedback,192,189,1 block_hint,StoreIC_NoFeedback,191,190,0 block_hint,StoreIC_NoFeedback,287,194,0 block_hint,StoreIC_NoFeedback,197,200,0 @@ -671,6 +671,7 @@ block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,27,26,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,32,31,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,34,33,1 +block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,40,39,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,45,44,0 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,62,52,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,96,70,1 @@ -691,6 +692,8 @@ block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,455,454,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,457,456,0 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,461,460,0 +block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,473,472,1 +block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,491,490,0 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,508,498,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,506,507,1 block_hint,StoreFastElementIC_NoTransitionGrowAndHandleCOW,541,517,1 @@ -960,7 +963,6 @@ block_hint,ArrayIndexOf,12,38,1 block_hint,ArrayIndexOf,37,13,0 block_hint,ArrayIndexOf,23,14,1 -block_hint,ArrayIndexOf,36,25,0 block_hint,ArrayIndexOf,35,26,0 block_hint,ArrayIndexOf,34,27,1 block_hint,ArrayIndexOf,44,43,1 @@ -977,6 +979,7 @@ block_hint,ArrayPrototypePop,31,16,0 block_hint,ArrayPrototypePop,30,17,0 block_hint,ArrayPrototypePop,25,18,0 +block_hint,ArrayPrototypePop,24,19,1 block_hint,ArrayPrototypePop,29,28,1 block_hint,ArrayPrototypePush,2,1,1 block_hint,ArrayPrototypePush,4,180,1 @@ -1073,9 +1076,7 @@ block_hint,ExtractFastJSArray,16,15,0 block_hint,ExtractFastJSArray,26,27,1 block_hint,ExtractFastJSArray,29,28,1 -block_hint,ExtractFastJSArray,31,30,0 block_hint,ExtractFastJSArray,33,34,1 -block_hint,ExtractFastJSArray,37,36,1 block_hint,ExtractFastJSArray,60,41,0 block_hint,ExtractFastJSArray,43,42,1 block_hint,ExtractFastJSArray,45,44,1 @@ -1329,12 +1330,14 @@ block_hint,LoadIC_Noninlined,6,5,0 block_hint,LoadIC_Noninlined,19,18,0 block_hint,LoadIC_Noninlined,22,23,1 +block_hint,LoadIC_Noninlined,27,28,1 block_hint,LoadIC_Noninlined,121,32,0 block_hint,LoadIC_Noninlined,120,33,0 block_hint,LoadIC_Noninlined,37,34,0 block_hint,LoadIC_Noninlined,36,35,1 block_hint,LoadIC_Noninlined,113,119,1 block_hint,LoadIC_Noninlined,116,115,0 +block_hint,LoadIC_Noninlined,200,129,0 block_hint,LoadIC_Noninlined,273,259,0 block_hint,LoadIC_Noninlined,264,263,0 block_hint,LoadIC_Noninlined,312,311,0 @@ -1377,9 +1380,7 @@ block_hint,KeyedLoadIC,147,60,1 block_hint,KeyedLoadIC,153,429,1 block_hint,KeyedLoadIC,371,370,0 -block_hint,KeyedLoadIC,378,385,1 block_hint,KeyedLoadIC,398,390,0 -block_hint,KeyedLoadIC,405,404,0 block_hint,KeyedLoadIC,408,407,0 block_hint,KeyedLoadIC,413,414,1 block_hint,KeyedLoadIC,421,416,1 @@ -1975,6 +1976,8 @@ block_hint,SubtractSmi_Baseline,19,18,0 block_hint,Multiply_Baseline,3,4,1 block_hint,Multiply_Baseline,18,6,0 +block_hint,Multiply_Baseline,9,8,0 +block_hint,Multiply_Baseline,21,20,1 block_hint,Multiply_Baseline,24,25,1 block_hint,Multiply_Baseline,31,36,1 block_hint,Multiply_Baseline,33,34,1 @@ -2098,7 +2101,6 @@ block_hint,Equal_Baseline,136,137,0 block_hint,Equal_Baseline,174,152,0 block_hint,Equal_Baseline,157,156,0 -block_hint,Equal_Baseline,168,167,1 block_hint,Equal_Baseline,171,172,0 block_hint,Equal_Baseline,176,175,1 block_hint,Equal_Baseline,182,181,1 @@ -2112,7 +2114,6 @@ block_hint,StrictEqual_Baseline,22,21,1 block_hint,StrictEqual_Baseline,57,56,1 block_hint,StrictEqual_Baseline,61,62,0 -block_hint,StrictEqual_Baseline,70,69,0 block_hint,StrictEqual_Baseline,77,82,0 block_hint,StrictEqual_Baseline,108,86,0 block_hint,StrictEqual_Baseline,91,90,0 @@ -3507,7 +3508,6 @@ block_hint,StringPrototypeCharCodeAt,44,14,0 block_hint,StringPrototypeCharCodeAt,43,15,0 block_hint,StringPrototypeCharCodeAt,26,18,0 -block_hint,StringPrototypeCharCodeAt,22,19,1 block_hint,StringPrototypeCharCodeAt,23,24,1 block_hint,StringPrototypeCharCodeAt,41,42,1 block_hint,StringPrototypeCodePointAt,2,1,1 @@ -3937,8 +3937,6 @@ block_hint,Equal,54,8,0 block_hint,Equal,16,9,0 block_hint,Equal,12,11,0 -block_hint,Equal,55,58,0 -block_hint,Equal,60,59,0 block_hint,Equal,69,64,0 block_hint,Equal,68,65,0 block_hint,Equal,66,67,1 @@ -4890,6 +4888,7 @@ block_hint,StoreScriptContextSlotBaseline,179,14,0 block_hint,StoreScriptContextSlotBaseline,178,15,0 block_hint,StoreScriptContextSlotBaseline,32,31,1 +block_hint,StoreScriptContextSlotBaseline,34,33,0 block_hint,StoreScriptContextSlotBaseline,129,38,0 block_hint,StoreScriptContextSlotBaseline,174,173,0 block_hint,StringSlowFlatten,1,2,1 @@ -4960,8 +4959,6 @@ block_hint,MergeAt,71,76,1 block_hint,MergeAt,72,75,1 block_hint,MergeAt,74,73,0 -block_hint,MergeAt,85,82,0 -block_hint,MergeAt,83,84,0 block_hint,MergeAt,89,88,1 block_hint,MergeAt,91,118,1 block_hint,MergeAt,97,117,1 @@ -5222,7 +5219,6 @@ block_hint,LdaCurrentScriptContextSlotHandler,36,10,0 block_hint,LdaCurrentScriptContextSlotHandler,12,11,1 block_hint,LdaCurrentScriptContextSlotHandler,13,14,0 -block_hint,LdaCurrentScriptContextSlotHandler,15,18,0 block_hint,LdaCurrentScriptContextSlotHandler,23,28,0 block_hint,LdaCurrentScriptContextSlotHandler,33,32,0 block_hint,LdaImmutableCurrentContextSlotHandler,2,1,1 @@ -5374,6 +5370,7 @@ block_hint,ShiftLeftSmiHandler,24,3,1 block_hint,ShiftLeftSmiHandler,38,37,0 block_hint,ShiftLeftSmiHandler,51,48,0 +block_hint,ShiftRightSmiHandler,1,36,0 block_hint,ShiftRightSmiHandler,24,3,1 block_hint,ShiftRightSmiHandler,27,26,0 block_hint,ShiftRightSmiHandler,41,38,1 @@ -5400,6 +5397,12 @@ block_hint,FindNonDefaultConstructorOrConstructHandler,6,13,1 block_hint,FindNonDefaultConstructorOrConstructHandler,12,7,0 block_hint,CallAnyReceiverHandler,66,2,1 +block_hint,CallPropertyHandler,46,45,1 +block_hint,CallPropertyHandler,48,47,0 +block_hint,CallPropertyHandler,55,63,1 +block_hint,CallPropertyHandler,57,58,0 +block_hint,CallPropertyHandler,62,59,0 +block_hint,CallPropertyHandler,60,61,1 block_hint,CallProperty0Handler,46,45,1 block_hint,CallProperty0Handler,48,47,0 block_hint,CallProperty0Handler,55,63,1 @@ -5503,6 +5506,7 @@ block_hint,TestLessThanHandler,118,129,0 block_hint,TestLessThanHandler,147,146,1 block_hint,TestGreaterThanHandler,95,4,1 +block_hint,TestGreaterThanHandler,105,96,1 block_hint,TestGreaterThanHandler,116,107,1 block_hint,TestGreaterThanHandler,118,129,0 block_hint,TestGreaterThanHandler,147,146,1 @@ -5644,14 +5648,12 @@ block_hint,AddWideHandler,102,20,0 block_hint,AddWideHandler,21,101,1 block_hint,AddWideHandler,82,79,1 -block_hint,AddWideHandler,116,113,1 block_hint,AddWideHandler,126,125,0 block_hint,MulWideHandler,30,27,1 block_hint,MulWideHandler,33,38,1 block_hint,MulWideHandler,123,122,1 block_hint,AddSmiWideHandler,9,1,0 block_hint,AddSmiWideHandler,8,2,0 -block_hint,AddSmiWideHandler,5,4,1 block_hint,MulSmiWideHandler,14,2,0 block_hint,MulSmiWideHandler,5,4,0 block_hint,MulSmiWideHandler,17,16,1 @@ -5702,7 +5704,6 @@ block_hint,CreateClosureWideHandler,2,1,1 block_hint,CreateFunctionContextWideHandler,14,15,1 block_hint,JumpLoopWideHandler,3,4,0 -block_hint,JumpLoopWideHandler,35,6,1 block_hint,JumpLoopWideHandler,36,40,1 block_hint,JumpLoopWideHandler,37,38,0 block_hint,JumpLoopWideHandler,42,56,1 @@ -5724,20 +5725,21 @@ block_hint,BitwiseAndSmiExtraWideHandler,27,26,0 block_hint,BitwiseAndSmiExtraWideHandler,41,38,1 block_hint,CallUndefinedReceiver1ExtraWideHandler,1,67,0 -builtin_count,RecordWriteSaveFP,1755 +builtin_count,RecordWriteSaveFP,1807 builtin_count,RecordWriteIgnoreFP,14 builtin_count,EphemeronKeyBarrierSaveFP,0 +builtin_count,IndirectPointerBarrierIgnoreFP,0 builtin_count,AdaptorWithBuiltinExitFrame0,118 builtin_count,AdaptorWithBuiltinExitFrame1,4 builtin_count,AdaptorWithBuiltinExitFrame2,0 builtin_count,AdaptorWithBuiltinExitFrame3,8 -builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,138 -builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,518 +builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,135 +builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,513 builtin_count,Call_ReceiverIsAny_Baseline_Compact,2 builtin_count,CallProxy,0 builtin_count,CallWithSpread,26 builtin_count,CallWithSpread_Baseline,1 -builtin_count,CallWithArrayLike,32 +builtin_count,CallWithArrayLike,33 builtin_count,CallFunctionTemplate_Generic,0 builtin_count,ConstructWithSpread,0 builtin_count,ConstructWithSpread_Baseline,0 @@ -5746,8 +5748,8 @@ builtin_count,ConstructForwardAllArgs_WithFeedback,2 builtin_count,Construct_Baseline,44 builtin_count,Construct_WithFeedback,44 -builtin_count,FastNewObject,269 -builtin_count,FastNewClosure,186 +builtin_count,FastNewObject,270 +builtin_count,FastNewClosure,187 builtin_count,StringEqual,749 builtin_count,StringGreaterThan,0 builtin_count,StringGreaterThanOrEqual,4 @@ -5771,7 +5773,7 @@ builtin_count,GrowFastSmiOrObjectElements,350 builtin_count,ToNumber,0 builtin_count,ToNumber_Baseline,0 -builtin_count,ToNumeric_Baseline,29 +builtin_count,ToNumeric_Baseline,28 builtin_count,ToNumberConvertBigInt,2 builtin_count,Typeof,31 builtin_count,Typeof_Baseline,0 @@ -5780,13 +5782,13 @@ builtin_count,DefineKeyedOwnIC_Megamorphic,2 builtin_count,LoadGlobalIC_NoFeedback,16 builtin_count,LoadIC_FunctionPrototype,204 -builtin_count,LoadIC_StringLength,42 +builtin_count,LoadIC_StringLength,41 builtin_count,LoadIC_StringWrapperLength,0 builtin_count,LoadIC_NoFeedback,45 builtin_count,StoreIC_NoFeedback,6 builtin_count,DefineNamedOwnIC_NoFeedback,4 builtin_count,KeyedLoadIC_SloppyArguments,2 -builtin_count,StoreFastElementIC_InBounds,205 +builtin_count,StoreFastElementIC_InBounds,202 builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,18 builtin_count,StoreFastElementIC_NoTransitionHandleCOW,0 builtin_count,ElementsTransitionAndStore_InBounds,0 @@ -5798,9 +5800,9 @@ builtin_count,HasProperty,11 builtin_count,DeleteProperty,3 builtin_count,SetDataProperties,2 -builtin_count,ReturnReceiver,8 +builtin_count,ReturnReceiver,9 builtin_count,ArrayConstructor,2 -builtin_count,ArrayConstructorImpl,247 +builtin_count,ArrayConstructorImpl,230 builtin_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,0 builtin_count,ArrayNoArgumentConstructor_HoleySmi_DontOverride,0 builtin_count,ArrayNoArgumentConstructor_PackedSmi_DisableAllocationSites,0 @@ -5818,7 +5820,7 @@ builtin_count,ArrayIndexOfSmiOrObject,141 builtin_count,ArrayIndexOf,32 builtin_count,ArrayPrototypePop,5 -builtin_count,ArrayPrototypePush,205 +builtin_count,ArrayPrototypePush,202 builtin_count,CloneFastJSArray,193 builtin_count,CloneFastJSArrayFillingHoles,41 builtin_count,ExtractFastJSArray,203 @@ -5855,42 +5857,42 @@ builtin_count,GlobalIsNaN,0 builtin_count,LoadIC,2458 builtin_count,LoadIC_Megamorphic,10000 -builtin_count,LoadIC_Noninlined,2 +builtin_count,LoadIC_Noninlined,3 builtin_count,LoadICTrampoline,307 -builtin_count,LoadICBaseline,1819 -builtin_count,LoadICTrampoline_Megamorphic,5825 +builtin_count,LoadICBaseline,1818 +builtin_count,LoadICTrampoline_Megamorphic,5822 builtin_count,LoadSuperIC,2 builtin_count,LoadSuperICBaseline,2 -builtin_count,KeyedLoadIC,335 +builtin_count,KeyedLoadIC,336 builtin_count,EnumeratedKeyedLoadIC,4 builtin_count,KeyedLoadIC_Megamorphic,2387 builtin_count,KeyedLoadICTrampoline,1 builtin_count,KeyedLoadICBaseline,313 builtin_count,EnumeratedKeyedLoadICBaseline,3 -builtin_count,KeyedLoadICTrampoline_Megamorphic,1085 -builtin_count,StoreGlobalIC,565 +builtin_count,KeyedLoadICTrampoline_Megamorphic,1086 +builtin_count,StoreGlobalIC,567 builtin_count,StoreGlobalICTrampoline,187 builtin_count,StoreGlobalICBaseline,1 -builtin_count,StoreIC,269 -builtin_count,StoreIC_Megamorphic,1373 +builtin_count,StoreIC,271 +builtin_count,StoreIC_Megamorphic,1376 builtin_count,StoreICTrampoline,27 -builtin_count,StoreICTrampoline_Megamorphic,638 -builtin_count,StoreICBaseline,207 +builtin_count,StoreICTrampoline_Megamorphic,637 +builtin_count,StoreICBaseline,208 builtin_count,DefineNamedOwnIC,39 builtin_count,DefineNamedOwnICBaseline,34 -builtin_count,KeyedStoreIC,223 +builtin_count,KeyedStoreIC,220 builtin_count,KeyedStoreICTrampoline,1 builtin_count,KeyedStoreICTrampoline_Megamorphic,260 -builtin_count,KeyedStoreICBaseline,208 +builtin_count,KeyedStoreICBaseline,205 builtin_count,DefineKeyedOwnIC,2 builtin_count,StoreInArrayLiteralIC,17 builtin_count,StoreInArrayLiteralICBaseline,15 -builtin_count,LoadGlobalIC,1196 +builtin_count,LoadGlobalIC,1392 builtin_count,LoadGlobalICInsideTypeof,0 -builtin_count,LoadGlobalICTrampoline,731 +builtin_count,LoadGlobalICTrampoline,937 builtin_count,LoadGlobalICBaseline,400 builtin_count,LoadGlobalICInsideTypeofBaseline,0 -builtin_count,LookupGlobalICBaseline,1 +builtin_count,LookupGlobalICBaseline,0 builtin_count,LookupGlobalICInsideTypeofBaseline,0 builtin_count,KeyedHasIC,722 builtin_count,KeyedHasICBaseline,2 @@ -5899,11 +5901,11 @@ builtin_count,IterableToListWithSymbolLookup,0 builtin_count,IterableToListMayPreserveHoles,0 builtin_count,IterableToListConvertHoles,40 -builtin_count,FindOrderedHashMapEntry,391 +builtin_count,FindOrderedHashMapEntry,394 builtin_count,MapConstructor,76 builtin_count,MapPrototypeSet,66 builtin_count,MapPrototypeDelete,0 -builtin_count,MapPrototypeGet,21 +builtin_count,MapPrototypeGet,25 builtin_count,MapPrototypeHas,3 builtin_count,MapPrototypeEntries,0 builtin_count,MapPrototypeGetSize,0 @@ -5912,27 +5914,27 @@ builtin_count,MapPrototypeValues,1 builtin_count,MapIteratorPrototypeNext,12 builtin_count,MapIteratorToList,0 -builtin_count,Add_Baseline,200 -builtin_count,AddSmi_Baseline,245 +builtin_count,Add_Baseline,192 +builtin_count,AddSmi_Baseline,242 builtin_count,Subtract_Baseline,47 builtin_count,SubtractSmi_Baseline,20 -builtin_count,Multiply_Baseline,58 +builtin_count,Multiply_Baseline,47 builtin_count,MultiplySmi_Baseline,5 -builtin_count,Divide_Baseline,3 +builtin_count,Divide_Baseline,4 builtin_count,DivideSmi_Baseline,1 builtin_count,Modulus_Baseline,0 builtin_count,ModulusSmi_Baseline,0 builtin_count,Exponentiate_Baseline,0 builtin_count,BitwiseAnd_Baseline,8 -builtin_count,BitwiseAndSmi_Baseline,34 +builtin_count,BitwiseAndSmi_Baseline,31 builtin_count,BitwiseOr_Baseline,19 builtin_count,BitwiseOrSmi_Baseline,182 builtin_count,BitwiseXor_Baseline,9 builtin_count,BitwiseXorSmi_Baseline,0 builtin_count,ShiftLeft_Baseline,1 -builtin_count,ShiftLeftSmi_Baseline,31 -builtin_count,ShiftRight_Baseline,1 -builtin_count,ShiftRightSmi_Baseline,117 +builtin_count,ShiftLeftSmi_Baseline,30 +builtin_count,ShiftRight_Baseline,2 +builtin_count,ShiftRightSmi_Baseline,115 builtin_count,ShiftRightLogical_Baseline,0 builtin_count,ShiftRightLogicalSmi_Baseline,4 builtin_count,Add_WithFeedback,44 @@ -5940,20 +5942,20 @@ builtin_count,Divide_WithFeedback,0 builtin_count,Modulus_WithFeedback,0 builtin_count,BitwiseOr_WithFeedback,0 -builtin_count,Equal_Baseline,153 -builtin_count,StrictEqual_Baseline,198 -builtin_count,LessThan_Baseline,152 -builtin_count,GreaterThan_Baseline,44 -builtin_count,LessThanOrEqual_Baseline,19 +builtin_count,Equal_Baseline,154 +builtin_count,StrictEqual_Baseline,191 +builtin_count,LessThan_Baseline,147 +builtin_count,GreaterThan_Baseline,45 +builtin_count,LessThanOrEqual_Baseline,20 builtin_count,GreaterThanOrEqual_Baseline,39 -builtin_count,Equal_WithFeedback,11 +builtin_count,Equal_WithFeedback,10 builtin_count,StrictEqual_WithFeedback,120 builtin_count,LessThan_WithFeedback,2 builtin_count,GreaterThan_WithFeedback,2 builtin_count,GreaterThanOrEqual_WithFeedback,0 builtin_count,BitwiseNot_Baseline,1 builtin_count,Decrement_Baseline,16 -builtin_count,Increment_Baseline,109 +builtin_count,Increment_Baseline,103 builtin_count,Negate_Baseline,3 builtin_count,ObjectAssign,2 builtin_count,ObjectCreate,7 @@ -5988,7 +5990,7 @@ builtin_count,StringPrototypeSplit,53 builtin_count,TypedArrayConstructor,3 builtin_count,TypedArrayPrototypeByteLength,0 -builtin_count,TypedArrayPrototypeLength,38 +builtin_count,TypedArrayPrototypeLength,36 builtin_count,TypedArrayPrototypeToStringTag,0 builtin_count,WasmToJsWrapperCSA,0 builtin_count,WeakMapConstructor,0 @@ -6007,7 +6009,7 @@ builtin_count,AsyncGeneratorAwait,7 builtin_count,AsyncGeneratorAwaitResolveClosure,7 builtin_count,AsyncGeneratorYieldWithAwaitResolveClosure,8 -builtin_count,StringAdd_CheckNone,8563 +builtin_count,StringAdd_CheckNone,8562 builtin_count,SubString,1649 builtin_count,GetProperty,712 builtin_count,GetPropertyWithReceiver,17 @@ -6055,16 +6057,16 @@ builtin_count,ToString,73 builtin_count,StringPrototypeToString,18 builtin_count,StringPrototypeCharAt,127 -builtin_count,StringPrototypeCharCodeAt,69 +builtin_count,StringPrototypeCharCodeAt,68 builtin_count,StringPrototypeCodePointAt,0 builtin_count,StringPrototypeConcat,0 builtin_count,StringConstructor,32 builtin_count,StringAddConvertLeft,18 builtin_count,StringAddConvertRight,202 builtin_count,StringCharAt,9 -builtin_count,FastNewClosureBaseline,32 +builtin_count,FastNewClosureBaseline,31 builtin_count,FastNewFunctionContextFunction,61 -builtin_count,CreateRegExpLiteral,13 +builtin_count,CreateRegExpLiteral,12 builtin_count,CreateShallowArrayLiteral,9 builtin_count,CreateEmptyArrayLiteral,13 builtin_count,CreateShallowObjectLiteral,16 @@ -6077,7 +6079,7 @@ builtin_count,ToNumeric,16 builtin_count,NumberToString,1498 builtin_count,ToBoolean,34 -builtin_count,ToBooleanForBaselineJump,411 +builtin_count,ToBooleanForBaselineJump,405 builtin_count,ToLength,2 builtin_count,ToName,47 builtin_count,ToObject,243 @@ -6113,7 +6115,7 @@ builtin_count,MathLog,0 builtin_count,MathSin,0 builtin_count,MathSign,0 -builtin_count,MathSqrt,9 +builtin_count,MathSqrt,10 builtin_count,MathTan,0 builtin_count,MathTanh,0 builtin_count,MathRandom,315 @@ -6129,10 +6131,10 @@ builtin_count,Divide,0 builtin_count,Modulus,0 builtin_count,BitwiseOr,4 -builtin_count,LessThan,761 +builtin_count,LessThan,758 builtin_count,GreaterThan,659 builtin_count,GreaterThanOrEqual,3 -builtin_count,Equal,49 +builtin_count,Equal,50 builtin_count,StrictEqual,1416 builtin_count,CreateObjectWithoutProperties,7 builtin_count,ObjectIsExtensible,0 @@ -6169,7 +6171,7 @@ builtin_count,RegExpPrototypeSourceGetter,0 builtin_count,RegExpSplit,13 builtin_count,RegExpPrototypeTest,114 -builtin_count,RegExpPrototypeTestFast,427 +builtin_count,RegExpPrototypeTestFast,426 builtin_count,RegExpPrototypeGlobalGetter,0 builtin_count,RegExpPrototypeIgnoreCaseGetter,0 builtin_count,RegExpPrototypeMultilineGetter,0 @@ -6181,7 +6183,7 @@ builtin_count,RegExpPrototypeFlagsGetter,0 builtin_count,StringPrototypeEndsWith,0 builtin_count,StringPrototypeIncludes,0 -builtin_count,StringPrototypeIndexOf,13 +builtin_count,StringPrototypeIndexOf,12 builtin_count,StringPrototypeIterator,0 builtin_count,StringIteratorPrototypeNext,0 builtin_count,StringPrototypeMatch,1235 @@ -6235,11 +6237,11 @@ builtin_count,StringPrototypeToLowerCaseIntl,4 builtin_count,StringToLowerCaseIntl,146 builtin_count,WideHandler,62 -builtin_count,ExtraWideHandler,10 -builtin_count,LdarHandler,84 +builtin_count,ExtraWideHandler,11 +builtin_count,LdarHandler,86 builtin_count,LdaZeroHandler,11 builtin_count,LdaSmiHandler,12 -builtin_count,LdaUndefinedHandler,7 +builtin_count,LdaUndefinedHandler,8 builtin_count,LdaNullHandler,1 builtin_count,LdaTheHoleHandler,0 builtin_count,LdaTrueHandler,2 @@ -6251,8 +6253,8 @@ builtin_count,LdaCurrentContextSlotHandler,5 builtin_count,LdaCurrentScriptContextSlotHandler,0 builtin_count,LdaImmutableCurrentContextSlotHandler,20 -builtin_count,StarHandler,19 -builtin_count,MovHandler,18 +builtin_count,StarHandler,20 +builtin_count,MovHandler,19 builtin_count,PushContextHandler,2 builtin_count,PopContextHandler,0 builtin_count,TestReferenceEqualHandler,0 @@ -6260,7 +6262,7 @@ builtin_count,TestNullHandler,0 builtin_count,TestUndefinedHandler,0 builtin_count,TestTypeOfHandler,0 -builtin_count,LdaGlobalHandler,23 +builtin_count,LdaGlobalHandler,24 builtin_count,LdaGlobalInsideTypeofHandler,0 builtin_count,StaGlobalHandler,0 builtin_count,StaContextSlotHandler,0 @@ -6270,23 +6272,23 @@ builtin_count,LdaLookupGlobalSlotHandler,0 builtin_count,LdaLookupGlobalSlotInsideTypeofHandler,0 builtin_count,StaLookupSlotHandler,0 -builtin_count,GetNamedPropertyHandler,73 +builtin_count,GetNamedPropertyHandler,76 builtin_count,GetNamedPropertyFromSuperHandler,0 builtin_count,GetKeyedPropertyHandler,20 builtin_count,GetEnumeratedKeyedPropertyHandler,1 builtin_count,SetNamedPropertyHandler,10 builtin_count,DefineNamedOwnPropertyHandler,3 -builtin_count,SetKeyedPropertyHandler,11 +builtin_count,SetKeyedPropertyHandler,12 builtin_count,DefineKeyedOwnPropertyHandler,0 builtin_count,StaInArrayLiteralHandler,1 builtin_count,DefineKeyedOwnPropertyInLiteralHandler,0 builtin_count,AddHandler,11 builtin_count,SubHandler,1 -builtin_count,MulHandler,4 +builtin_count,MulHandler,5 builtin_count,DivHandler,0 builtin_count,ModHandler,0 builtin_count,ExpHandler,0 -builtin_count,BitwiseOrHandler,0 +builtin_count,BitwiseOrHandler,1 builtin_count,BitwiseXorHandler,0 builtin_count,BitwiseAndHandler,0 builtin_count,ShiftLeftHandler,0 @@ -6304,7 +6306,7 @@ builtin_count,ShiftRightSmiHandler,2 builtin_count,ShiftRightLogicalSmiHandler,0 builtin_count,IncHandler,11 -builtin_count,DecHandler,2 +builtin_count,DecHandler,3 builtin_count,NegateHandler,0 builtin_count,BitwiseNotHandler,0 builtin_count,ToBooleanLogicalNotHandler,0 @@ -6315,11 +6317,11 @@ builtin_count,FindNonDefaultConstructorOrConstructHandler,0 builtin_count,CallAnyReceiverHandler,0 builtin_count,CallPropertyHandler,2 -builtin_count,CallProperty0Handler,5 +builtin_count,CallProperty0Handler,6 builtin_count,CallProperty1Handler,12 -builtin_count,CallProperty2Handler,3 +builtin_count,CallProperty2Handler,4 builtin_count,CallUndefinedReceiverHandler,1 -builtin_count,CallUndefinedReceiver0Handler,1 +builtin_count,CallUndefinedReceiver0Handler,2 builtin_count,CallUndefinedReceiver1Handler,5 builtin_count,CallUndefinedReceiver2Handler,3 builtin_count,CallWithSpreadHandler,0 @@ -6329,7 +6331,7 @@ builtin_count,ConstructHandler,4 builtin_count,ConstructWithSpreadHandler,0 builtin_count,ConstructForwardAllArgsHandler,0 -builtin_count,TestEqualHandler,4 +builtin_count,TestEqualHandler,5 builtin_count,TestEqualStrictHandler,7 builtin_count,TestLessThanHandler,10 builtin_count,TestGreaterThanHandler,2 @@ -6339,7 +6341,7 @@ builtin_count,TestInHandler,0 builtin_count,ToNameHandler,0 builtin_count,ToNumberHandler,0 -builtin_count,ToNumericHandler,3 +builtin_count,ToNumericHandler,4 builtin_count,ToObjectHandler,0 builtin_count,ToStringHandler,0 builtin_count,ToBooleanHandler,0 @@ -6356,7 +6358,7 @@ builtin_count,CreateMappedArgumentsHandler,0 builtin_count,CreateUnmappedArgumentsHandler,0 builtin_count,CreateRestParameterHandler,0 -builtin_count,JumpLoopHandler,13 +builtin_count,JumpLoopHandler,14 builtin_count,JumpHandler,4 builtin_count,JumpConstantHandler,0 builtin_count,JumpIfUndefinedConstantHandler,0 @@ -6367,10 +6369,10 @@ builtin_count,JumpIfForInDoneConstantHandler,0 builtin_count,JumpIfToBooleanTrueConstantHandler,0 builtin_count,JumpIfToBooleanFalseConstantHandler,0 -builtin_count,JumpIfToBooleanTrueHandler,5 +builtin_count,JumpIfToBooleanTrueHandler,6 builtin_count,JumpIfToBooleanFalseHandler,12 builtin_count,JumpIfTrueHandler,6 -builtin_count,JumpIfFalseHandler,22 +builtin_count,JumpIfFalseHandler,23 builtin_count,JumpIfNullHandler,0 builtin_count,JumpIfNotNullHandler,0 builtin_count,JumpIfUndefinedHandler,1 @@ -6386,7 +6388,7 @@ builtin_count,SetPendingMessageHandler,0 builtin_count,ThrowHandler,2 builtin_count,ReThrowHandler,0 -builtin_count,ReturnHandler,20 +builtin_count,ReturnHandler,21 builtin_count,ThrowReferenceErrorIfHoleHandler,1 builtin_count,ThrowSuperNotCalledIfHoleHandler,0 builtin_count,ThrowSuperAlreadyCalledIfNotHoleHandler,0 @@ -6395,7 +6397,7 @@ builtin_count,SuspendGeneratorHandler,0 builtin_count,ResumeGeneratorHandler,0 builtin_count,GetIteratorHandler,0 -builtin_count,ShortStarHandler,53 +builtin_count,ShortStarHandler,55 builtin_count,LdarWideHandler,0 builtin_count,LdaSmiWideHandler,7 builtin_count,LdaConstantWideHandler,1 @@ -6493,24 +6495,24 @@ builtin_count,CallUndefinedReceiverExtraWideHandler,0 builtin_count,CallUndefinedReceiver1ExtraWideHandler,4 builtin_count,CallUndefinedReceiver2ExtraWideHandler,0 -block_count,RecordWriteSaveFP,0,1755 -block_count,RecordWriteSaveFP,1,1740 +block_count,RecordWriteSaveFP,0,1807 +block_count,RecordWriteSaveFP,1,1785 block_count,RecordWriteSaveFP,2,0 -block_count,RecordWriteSaveFP,3,1740 +block_count,RecordWriteSaveFP,3,1785 block_count,RecordWriteSaveFP,4,0 -block_count,RecordWriteSaveFP,5,1740 -block_count,RecordWriteSaveFP,6,1740 +block_count,RecordWriteSaveFP,5,1785 +block_count,RecordWriteSaveFP,6,1785 block_count,RecordWriteSaveFP,7,0 -block_count,RecordWriteSaveFP,8,1740 -block_count,RecordWriteSaveFP,9,1739 -block_count,RecordWriteSaveFP,10,0 +block_count,RecordWriteSaveFP,8,1785 +block_count,RecordWriteSaveFP,9,1783 +block_count,RecordWriteSaveFP,10,1 block_count,RecordWriteSaveFP,11,0 -block_count,RecordWriteSaveFP,12,0 -block_count,RecordWriteSaveFP,13,1740 -block_count,RecordWriteSaveFP,14,15 -block_count,RecordWriteSaveFP,15,4 -block_count,RecordWriteSaveFP,16,4 -block_count,RecordWriteSaveFP,17,4 +block_count,RecordWriteSaveFP,12,1 +block_count,RecordWriteSaveFP,13,1785 +block_count,RecordWriteSaveFP,14,22 +block_count,RecordWriteSaveFP,15,8 +block_count,RecordWriteSaveFP,16,8 +block_count,RecordWriteSaveFP,17,8 block_count,RecordWriteSaveFP,18,0 block_count,RecordWriteSaveFP,19,0 block_count,RecordWriteSaveFP,20,0 @@ -6522,9 +6524,9 @@ block_count,RecordWriteSaveFP,26,0 block_count,RecordWriteSaveFP,27,0 block_count,RecordWriteSaveFP,28,0 -block_count,RecordWriteSaveFP,29,10 -block_count,RecordWriteSaveFP,30,15 -block_count,RecordWriteSaveFP,31,15 +block_count,RecordWriteSaveFP,29,13 +block_count,RecordWriteSaveFP,30,22 +block_count,RecordWriteSaveFP,31,22 block_count,RecordWriteSaveFP,32,0 block_count,RecordWriteSaveFP,33,0 block_count,RecordWriteSaveFP,34,0 @@ -6543,12 +6545,12 @@ block_count,RecordWriteSaveFP,47,0 block_count,RecordWriteSaveFP,48,0 block_count,RecordWriteSaveFP,49,0 -block_count,RecordWriteSaveFP,50,15 -block_count,RecordWriteSaveFP,51,15 +block_count,RecordWriteSaveFP,50,22 +block_count,RecordWriteSaveFP,51,22 block_count,RecordWriteSaveFP,52,0 -block_count,RecordWriteSaveFP,53,15 -block_count,RecordWriteSaveFP,54,14 -block_count,RecordWriteSaveFP,55,14 +block_count,RecordWriteSaveFP,53,22 +block_count,RecordWriteSaveFP,54,21 +block_count,RecordWriteSaveFP,55,21 block_count,RecordWriteSaveFP,56,0 block_count,RecordWriteSaveFP,57,0 block_count,RecordWriteSaveFP,58,0 @@ -6561,21 +6563,21 @@ block_count,RecordWriteSaveFP,65,0 block_count,RecordWriteSaveFP,66,0 block_count,RecordWriteSaveFP,67,0 -block_count,RecordWriteSaveFP,68,15 +block_count,RecordWriteSaveFP,68,22 block_count,RecordWriteIgnoreFP,0,14 -block_count,RecordWriteIgnoreFP,1,13 +block_count,RecordWriteIgnoreFP,1,14 block_count,RecordWriteIgnoreFP,2,0 -block_count,RecordWriteIgnoreFP,3,13 +block_count,RecordWriteIgnoreFP,3,14 block_count,RecordWriteIgnoreFP,4,0 -block_count,RecordWriteIgnoreFP,5,13 -block_count,RecordWriteIgnoreFP,6,13 +block_count,RecordWriteIgnoreFP,5,14 +block_count,RecordWriteIgnoreFP,6,14 block_count,RecordWriteIgnoreFP,7,0 -block_count,RecordWriteIgnoreFP,8,13 -block_count,RecordWriteIgnoreFP,9,13 +block_count,RecordWriteIgnoreFP,8,14 +block_count,RecordWriteIgnoreFP,9,14 block_count,RecordWriteIgnoreFP,10,0 block_count,RecordWriteIgnoreFP,11,0 block_count,RecordWriteIgnoreFP,12,0 -block_count,RecordWriteIgnoreFP,13,13 +block_count,RecordWriteIgnoreFP,13,14 block_count,RecordWriteIgnoreFP,14,0 block_count,RecordWriteIgnoreFP,15,0 block_count,RecordWriteIgnoreFP,16,0 @@ -6632,6 +6634,7 @@ block_count,RecordWriteIgnoreFP,67,0 block_count,RecordWriteIgnoreFP,68,0 block_count,EphemeronKeyBarrierSaveFP,0,0 +block_count,IndirectPointerBarrierIgnoreFP,0,0 block_count,AdaptorWithBuiltinExitFrame0,0,118 block_count,AdaptorWithBuiltinExitFrame1,0,4 block_count,AdaptorWithBuiltinExitFrame1,1,0 @@ -6645,8 +6648,8 @@ block_count,AdaptorWithBuiltinExitFrame3,1,6 block_count,AdaptorWithBuiltinExitFrame3,2,1 block_count,AdaptorWithBuiltinExitFrame3,3,8 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,138 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,138 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,135 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,135 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,37 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,33 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,33 @@ -6680,7 +6683,7 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,32,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,33,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,34,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,33 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,32 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,36,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,37,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,38,0 @@ -6711,12 +6714,12 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,64,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,65,4 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,100 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,98 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,138 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,518 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,518 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,28 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,135 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,513 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,513 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,29 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,3,12 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,4,11 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,5,11 @@ -6779,10 +6782,10 @@ block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,62,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,64,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,15 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,489 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,16 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,484 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,518 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,513 block_count,Call_ReceiverIsAny_Baseline_Compact,0,2 block_count,Call_ReceiverIsAny_Baseline_Compact,1,2 block_count,Call_ReceiverIsAny_Baseline_Compact,2,0 @@ -7089,13 +7092,13 @@ block_count,CallWithSpread_Baseline,130,0 block_count,CallWithSpread_Baseline,131,0 block_count,CallWithSpread_Baseline,132,1 -block_count,CallWithArrayLike,0,32 -block_count,CallWithArrayLike,1,32 +block_count,CallWithArrayLike,0,33 +block_count,CallWithArrayLike,1,33 block_count,CallWithArrayLike,2,0 -block_count,CallWithArrayLike,3,32 -block_count,CallWithArrayLike,4,32 +block_count,CallWithArrayLike,3,33 +block_count,CallWithArrayLike,4,33 block_count,CallWithArrayLike,5,0 -block_count,CallWithArrayLike,6,32 +block_count,CallWithArrayLike,6,33 block_count,CallWithArrayLike,7,31 block_count,CallWithArrayLike,8,0 block_count,CallWithArrayLike,9,31 @@ -7104,7 +7107,7 @@ block_count,CallWithArrayLike,12,30 block_count,CallWithArrayLike,13,30 block_count,CallWithArrayLike,14,10 -block_count,CallWithArrayLike,15,10 +block_count,CallWithArrayLike,15,9 block_count,CallWithArrayLike,16,0 block_count,CallWithArrayLike,17,20 block_count,CallWithArrayLike,18,0 @@ -7118,18 +7121,18 @@ block_count,CallWithArrayLike,26,0 block_count,CallWithArrayLike,27,0 block_count,CallWithArrayLike,28,1 -block_count,CallWithArrayLike,29,1 +block_count,CallWithArrayLike,29,2 block_count,CallWithArrayLike,30,0 -block_count,CallWithArrayLike,31,1 +block_count,CallWithArrayLike,31,2 block_count,CallWithArrayLike,32,0 -block_count,CallWithArrayLike,33,0 +block_count,CallWithArrayLike,33,1 block_count,CallWithArrayLike,34,0 block_count,CallWithArrayLike,35,0 block_count,CallWithArrayLike,36,0 block_count,CallWithArrayLike,37,0 block_count,CallWithArrayLike,38,31 -block_count,CallWithArrayLike,39,1 -block_count,CallWithArrayLike,40,32 +block_count,CallWithArrayLike,39,2 +block_count,CallWithArrayLike,40,33 block_count,CallWithArrayLike,41,0 block_count,CallWithArrayLike,42,0 block_count,CallWithArrayLike,43,0 @@ -7162,7 +7165,7 @@ block_count,CallWithArrayLike,70,0 block_count,CallWithArrayLike,71,0 block_count,CallWithArrayLike,72,0 -block_count,CallWithArrayLike,73,32 +block_count,CallWithArrayLike,73,33 block_count,CallFunctionTemplate_Generic,0,0 block_count,CallFunctionTemplate_Generic,1,0 block_count,CallFunctionTemplate_Generic,2,0 @@ -7607,7 +7610,7 @@ block_count,Construct_Baseline,41,1 block_count,Construct_Baseline,42,1 block_count,Construct_Baseline,43,41 -block_count,Construct_Baseline,44,42 +block_count,Construct_Baseline,44,43 block_count,Construct_WithFeedback,0,44 block_count,Construct_WithFeedback,1,44 block_count,Construct_WithFeedback,2,10 @@ -7655,13 +7658,13 @@ block_count,Construct_WithFeedback,44,33 block_count,Construct_WithFeedback,45,0 block_count,Construct_WithFeedback,46,40 -block_count,FastNewObject,0,269 +block_count,FastNewObject,0,270 block_count,FastNewObject,1,0 -block_count,FastNewObject,2,269 -block_count,FastNewObject,3,269 -block_count,FastNewObject,4,266 -block_count,FastNewObject,5,266 -block_count,FastNewObject,6,266 +block_count,FastNewObject,2,270 +block_count,FastNewObject,3,270 +block_count,FastNewObject,4,267 +block_count,FastNewObject,5,267 +block_count,FastNewObject,6,267 block_count,FastNewObject,7,0 block_count,FastNewObject,8,0 block_count,FastNewObject,9,0 @@ -7687,25 +7690,25 @@ block_count,FastNewObject,29,0 block_count,FastNewObject,30,0 block_count,FastNewObject,31,0 -block_count,FastNewObject,32,266 -block_count,FastNewObject,33,266 +block_count,FastNewObject,32,267 +block_count,FastNewObject,33,267 block_count,FastNewObject,34,0 -block_count,FastNewObject,35,266 +block_count,FastNewObject,35,267 block_count,FastNewObject,36,0 block_count,FastNewObject,37,0 -block_count,FastNewObject,38,266 -block_count,FastNewObject,39,266 +block_count,FastNewObject,38,267 +block_count,FastNewObject,39,267 block_count,FastNewObject,40,1 block_count,FastNewObject,41,265 block_count,FastNewObject,42,47 -block_count,FastNewObject,43,217 -block_count,FastNewObject,44,390 -block_count,FastNewObject,45,173 -block_count,FastNewObject,46,217 +block_count,FastNewObject,43,218 +block_count,FastNewObject,44,397 +block_count,FastNewObject,45,178 +block_count,FastNewObject,46,218 block_count,FastNewObject,47,265 block_count,FastNewObject,48,184 -block_count,FastNewObject,49,80 -block_count,FastNewObject,50,266 +block_count,FastNewObject,49,81 +block_count,FastNewObject,50,267 block_count,FastNewObject,51,0 block_count,FastNewObject,52,0 block_count,FastNewObject,53,0 @@ -7735,33 +7738,33 @@ block_count,FastNewObject,77,2 block_count,FastNewObject,78,0 block_count,FastNewObject,79,2 -block_count,FastNewClosure,0,186 -block_count,FastNewClosure,1,181 -block_count,FastNewClosure,2,181 +block_count,FastNewClosure,0,187 +block_count,FastNewClosure,1,182 +block_count,FastNewClosure,2,182 block_count,FastNewClosure,3,0 block_count,FastNewClosure,4,4 -block_count,FastNewClosure,5,186 +block_count,FastNewClosure,5,187 block_count,FastNewClosure,6,0 -block_count,FastNewClosure,7,186 -block_count,FastNewClosure,8,186 +block_count,FastNewClosure,7,187 +block_count,FastNewClosure,8,187 block_count,FastNewClosure,9,0 -block_count,FastNewClosure,10,186 +block_count,FastNewClosure,10,187 block_count,FastNewClosure,11,0 block_count,FastNewClosure,12,0 -block_count,FastNewClosure,13,186 +block_count,FastNewClosure,13,187 block_count,FastNewClosure,14,67 -block_count,FastNewClosure,15,118 -block_count,FastNewClosure,16,118 +block_count,FastNewClosure,15,119 +block_count,FastNewClosure,16,119 block_count,FastNewClosure,17,0 block_count,FastNewClosure,18,0 block_count,FastNewClosure,19,0 block_count,FastNewClosure,20,0 -block_count,FastNewClosure,21,118 +block_count,FastNewClosure,21,119 block_count,FastNewClosure,22,0 -block_count,FastNewClosure,23,118 -block_count,FastNewClosure,24,186 +block_count,FastNewClosure,23,119 +block_count,FastNewClosure,24,187 block_count,FastNewClosure,25,67 -block_count,FastNewClosure,26,118 +block_count,FastNewClosure,26,119 block_count,StringEqual,0,749 block_count,StringEqual,1,762 block_count,StringEqual,2,304 @@ -7778,11 +7781,11 @@ block_count,StringEqual,13,0 block_count,StringEqual,14,4 block_count,StringEqual,15,4 -block_count,StringEqual,16,0 -block_count,StringEqual,17,4 -block_count,StringEqual,18,3 +block_count,StringEqual,16,1 +block_count,StringEqual,17,5 +block_count,StringEqual,18,2 block_count,StringEqual,19,9 -block_count,StringEqual,20,9 +block_count,StringEqual,20,8 block_count,StringEqual,21,3 block_count,StringEqual,22,0 block_count,StringEqual,23,3 @@ -8175,19 +8178,19 @@ block_count,StringCompare,53,0 block_count,StringCompare,54,0 block_count,StringSubstring,0,554 -block_count,StringSubstring,1,542 -block_count,StringSubstring,2,542 +block_count,StringSubstring,1,543 +block_count,StringSubstring,2,543 block_count,StringSubstring,3,439 -block_count,StringSubstring,4,628 -block_count,StringSubstring,5,188 -block_count,StringSubstring,6,188 +block_count,StringSubstring,4,629 +block_count,StringSubstring,5,189 +block_count,StringSubstring,6,189 block_count,StringSubstring,7,181 block_count,StringSubstring,8,6 block_count,StringSubstring,9,175 block_count,StringSubstring,10,7 block_count,StringSubstring,11,7 block_count,StringSubstring,12,0 -block_count,StringSubstring,13,188 +block_count,StringSubstring,13,189 block_count,StringSubstring,14,0 block_count,StringSubstring,15,439 block_count,StringSubstring,16,439 @@ -8365,17 +8368,17 @@ block_count,StringSubstring,188,0 block_count,StringSubstring,189,0 block_count,StringSubstring,190,0 -block_count,StringSubstring,191,102 -block_count,StringSubstring,192,107 -block_count,StringSubstring,193,4 -block_count,StringSubstring,194,4 +block_count,StringSubstring,191,103 +block_count,StringSubstring,192,108 +block_count,StringSubstring,193,5 +block_count,StringSubstring,194,5 block_count,StringSubstring,195,1 block_count,StringSubstring,196,0 block_count,StringSubstring,197,1 block_count,StringSubstring,198,3 block_count,StringSubstring,199,3 block_count,StringSubstring,200,0 -block_count,StringSubstring,201,4 +block_count,StringSubstring,201,5 block_count,StringSubstring,202,0 block_count,StringSubstring,203,0 block_count,StringSubstring,204,0 @@ -8388,17 +8391,17 @@ block_count,StringSubstring,211,0 block_count,StringSubstring,212,0 block_count,StringSubstring,213,0 -block_count,StringSubstring,214,102 -block_count,StringSubstring,215,102 +block_count,StringSubstring,214,103 +block_count,StringSubstring,215,103 block_count,StringSubstring,216,3 block_count,StringSubstring,217,99 -block_count,StringSubstring,218,102 +block_count,StringSubstring,218,103 block_count,StringSubstring,219,0 block_count,StringSubstring,220,0 block_count,StringSubstring,221,0 block_count,StringSubstring,222,0 -block_count,StringSubstring,223,102 -block_count,StringSubstring,224,102 +block_count,StringSubstring,223,103 +block_count,StringSubstring,224,103 block_count,StringSubstring,225,0 block_count,StringSubstring,226,11 block_count,StringSubstring,227,11 @@ -8568,8 +8571,8 @@ block_count,GrowFastSmiOrObjectElements,19,332 block_count,GrowFastSmiOrObjectElements,20,350 block_count,GrowFastSmiOrObjectElements,21,47 -block_count,GrowFastSmiOrObjectElements,22,7047 -block_count,GrowFastSmiOrObjectElements,23,6999 +block_count,GrowFastSmiOrObjectElements,22,7050 +block_count,GrowFastSmiOrObjectElements,23,7002 block_count,GrowFastSmiOrObjectElements,24,47 block_count,GrowFastSmiOrObjectElements,25,302 block_count,GrowFastSmiOrObjectElements,26,0 @@ -8622,7 +8625,7 @@ block_count,ToNumber_Baseline,22,0 block_count,ToNumber_Baseline,23,0 block_count,ToNumber_Baseline,24,0 -block_count,ToNumeric_Baseline,0,29 +block_count,ToNumeric_Baseline,0,28 block_count,ToNumeric_Baseline,1,0 block_count,ToNumeric_Baseline,2,0 block_count,ToNumeric_Baseline,3,0 @@ -8650,10 +8653,10 @@ block_count,ToNumeric_Baseline,25,0 block_count,ToNumeric_Baseline,26,0 block_count,ToNumeric_Baseline,27,0 -block_count,ToNumeric_Baseline,28,29 -block_count,ToNumeric_Baseline,29,29 +block_count,ToNumeric_Baseline,28,28 +block_count,ToNumeric_Baseline,29,28 block_count,ToNumeric_Baseline,30,0 -block_count,ToNumeric_Baseline,31,29 +block_count,ToNumeric_Baseline,31,28 block_count,ToNumberConvertBigInt,0,2 block_count,ToNumberConvertBigInt,1,2 block_count,ToNumberConvertBigInt,2,0 @@ -9228,14 +9231,14 @@ block_count,KeyedStoreIC_Megamorphic,178,11 block_count,KeyedStoreIC_Megamorphic,179,0 block_count,KeyedStoreIC_Megamorphic,180,11 -block_count,KeyedStoreIC_Megamorphic,181,96 -block_count,KeyedStoreIC_Megamorphic,182,96 +block_count,KeyedStoreIC_Megamorphic,181,97 +block_count,KeyedStoreIC_Megamorphic,182,97 block_count,KeyedStoreIC_Megamorphic,183,0 -block_count,KeyedStoreIC_Megamorphic,184,96 -block_count,KeyedStoreIC_Megamorphic,185,52 -block_count,KeyedStoreIC_Megamorphic,186,44 -block_count,KeyedStoreIC_Megamorphic,187,96 -block_count,KeyedStoreIC_Megamorphic,188,85 +block_count,KeyedStoreIC_Megamorphic,184,97 +block_count,KeyedStoreIC_Megamorphic,185,49 +block_count,KeyedStoreIC_Megamorphic,186,47 +block_count,KeyedStoreIC_Megamorphic,187,97 +block_count,KeyedStoreIC_Megamorphic,188,86 block_count,KeyedStoreIC_Megamorphic,189,11 block_count,KeyedStoreIC_Megamorphic,190,11 block_count,KeyedStoreIC_Megamorphic,191,11 @@ -9310,7 +9313,7 @@ block_count,KeyedStoreIC_Megamorphic,260,0 block_count,KeyedStoreIC_Megamorphic,261,9 block_count,KeyedStoreIC_Megamorphic,262,67 -block_count,KeyedStoreIC_Megamorphic,263,25 +block_count,KeyedStoreIC_Megamorphic,263,26 block_count,KeyedStoreIC_Megamorphic,264,0 block_count,KeyedStoreIC_Megamorphic,265,0 block_count,KeyedStoreIC_Megamorphic,266,0 @@ -9319,10 +9322,10 @@ block_count,KeyedStoreIC_Megamorphic,269,0 block_count,KeyedStoreIC_Megamorphic,270,0 block_count,KeyedStoreIC_Megamorphic,271,25 -block_count,KeyedStoreIC_Megamorphic,272,25 -block_count,KeyedStoreIC_Megamorphic,273,25 +block_count,KeyedStoreIC_Megamorphic,272,26 +block_count,KeyedStoreIC_Megamorphic,273,26 block_count,KeyedStoreIC_Megamorphic,274,0 -block_count,KeyedStoreIC_Megamorphic,275,25 +block_count,KeyedStoreIC_Megamorphic,275,26 block_count,KeyedStoreIC_Megamorphic,276,9 block_count,KeyedStoreIC_Megamorphic,277,9 block_count,KeyedStoreIC_Megamorphic,278,0 @@ -9353,7 +9356,7 @@ block_count,KeyedStoreIC_Megamorphic,303,3 block_count,KeyedStoreIC_Megamorphic,304,9 block_count,KeyedStoreIC_Megamorphic,305,16 -block_count,KeyedStoreIC_Megamorphic,306,25 +block_count,KeyedStoreIC_Megamorphic,306,26 block_count,KeyedStoreIC_Megamorphic,307,41 block_count,KeyedStoreIC_Megamorphic,308,41 block_count,KeyedStoreIC_Megamorphic,309,0 @@ -11648,7 +11651,7 @@ block_count,LoadIC_FunctionPrototype,2,1 block_count,LoadIC_FunctionPrototype,3,202 block_count,LoadIC_FunctionPrototype,4,0 -block_count,LoadIC_StringLength,0,42 +block_count,LoadIC_StringLength,0,41 block_count,LoadIC_StringWrapperLength,0,0 block_count,LoadIC_NoFeedback,0,45 block_count,LoadIC_NoFeedback,1,45 @@ -12773,7 +12776,7 @@ block_count,KeyedLoadIC_SloppyArguments,20,0 block_count,KeyedLoadIC_SloppyArguments,21,0 block_count,KeyedLoadIC_SloppyArguments,22,0 -block_count,StoreFastElementIC_InBounds,0,205 +block_count,StoreFastElementIC_InBounds,0,202 block_count,StoreFastElementIC_InBounds,1,0 block_count,StoreFastElementIC_InBounds,2,3 block_count,StoreFastElementIC_InBounds,3,3 @@ -12796,8 +12799,8 @@ block_count,StoreFastElementIC_InBounds,20,0 block_count,StoreFastElementIC_InBounds,21,3 block_count,StoreFastElementIC_InBounds,22,0 -block_count,StoreFastElementIC_InBounds,23,3 -block_count,StoreFastElementIC_InBounds,24,3 +block_count,StoreFastElementIC_InBounds,23,2 +block_count,StoreFastElementIC_InBounds,24,2 block_count,StoreFastElementIC_InBounds,25,0 block_count,StoreFastElementIC_InBounds,26,0 block_count,StoreFastElementIC_InBounds,27,0 @@ -12805,17 +12808,17 @@ block_count,StoreFastElementIC_InBounds,29,0 block_count,StoreFastElementIC_InBounds,30,0 block_count,StoreFastElementIC_InBounds,31,0 -block_count,StoreFastElementIC_InBounds,32,3 -block_count,StoreFastElementIC_InBounds,33,3 +block_count,StoreFastElementIC_InBounds,32,2 +block_count,StoreFastElementIC_InBounds,33,2 block_count,StoreFastElementIC_InBounds,34,0 -block_count,StoreFastElementIC_InBounds,35,3 +block_count,StoreFastElementIC_InBounds,35,2 block_count,StoreFastElementIC_InBounds,36,0 -block_count,StoreFastElementIC_InBounds,37,3 -block_count,StoreFastElementIC_InBounds,38,3 +block_count,StoreFastElementIC_InBounds,37,2 +block_count,StoreFastElementIC_InBounds,38,2 block_count,StoreFastElementIC_InBounds,39,0 -block_count,StoreFastElementIC_InBounds,40,3 +block_count,StoreFastElementIC_InBounds,40,2 block_count,StoreFastElementIC_InBounds,41,0 -block_count,StoreFastElementIC_InBounds,42,3 +block_count,StoreFastElementIC_InBounds,42,2 block_count,StoreFastElementIC_InBounds,43,0 block_count,StoreFastElementIC_InBounds,44,10 block_count,StoreFastElementIC_InBounds,45,10 @@ -13219,7 +13222,7 @@ block_count,StoreFastElementIC_InBounds,443,0 block_count,StoreFastElementIC_InBounds,444,0 block_count,StoreFastElementIC_InBounds,445,0 -block_count,StoreFastElementIC_InBounds,446,27 +block_count,StoreFastElementIC_InBounds,446,24 block_count,StoreFastElementIC_InBounds,447,0 block_count,StoreFastElementIC_InBounds,448,0 block_count,StoreFastElementIC_InBounds,449,0 @@ -13227,20 +13230,20 @@ block_count,StoreFastElementIC_InBounds,451,0 block_count,StoreFastElementIC_InBounds,452,0 block_count,StoreFastElementIC_InBounds,453,0 -block_count,StoreFastElementIC_InBounds,454,27 -block_count,StoreFastElementIC_InBounds,455,27 -block_count,StoreFastElementIC_InBounds,456,27 -block_count,StoreFastElementIC_InBounds,457,22 -block_count,StoreFastElementIC_InBounds,458,22 +block_count,StoreFastElementIC_InBounds,454,24 +block_count,StoreFastElementIC_InBounds,455,24 +block_count,StoreFastElementIC_InBounds,456,24 +block_count,StoreFastElementIC_InBounds,457,19 +block_count,StoreFastElementIC_InBounds,458,19 block_count,StoreFastElementIC_InBounds,459,0 block_count,StoreFastElementIC_InBounds,460,0 block_count,StoreFastElementIC_InBounds,461,0 -block_count,StoreFastElementIC_InBounds,462,22 +block_count,StoreFastElementIC_InBounds,462,19 block_count,StoreFastElementIC_InBounds,463,5 -block_count,StoreFastElementIC_InBounds,464,27 -block_count,StoreFastElementIC_InBounds,465,27 +block_count,StoreFastElementIC_InBounds,464,24 +block_count,StoreFastElementIC_InBounds,465,24 block_count,StoreFastElementIC_InBounds,466,0 -block_count,StoreFastElementIC_InBounds,467,27 +block_count,StoreFastElementIC_InBounds,467,24 block_count,StoreFastElementIC_InBounds,468,0 block_count,StoreFastElementIC_InBounds,469,0 block_count,StoreFastElementIC_InBounds,470,0 @@ -14122,7 +14125,7 @@ block_count,StoreFastElementIC_InBounds,1346,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,18 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,1,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,3,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,4,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,5,0 @@ -14130,17 +14133,17 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,7,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,8,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,9,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,10,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,11,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,10,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,11,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,12,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,13,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,13,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,14,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,15,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,16,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,15,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,16,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,17,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,18,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,19,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,20,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,20,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,21,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,22,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,23,0 @@ -14155,7 +14158,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,32,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,33,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,34,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,35,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,35,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,36,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,37,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,38,0 @@ -14163,8 +14166,8 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,40,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,41,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,42,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,43,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,44,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,43,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,44,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,45,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,46,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,47,0 @@ -14182,12 +14185,12 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,59,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,60,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,61,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,62,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,63,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,62,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,63,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,64,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,65,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,66,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,67,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,65,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,66,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,67,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,68,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,69,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,70,0 @@ -14216,9 +14219,9 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,93,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,94,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,95,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,96,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,96,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,97,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,98,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,98,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,99,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,100,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,101,0 @@ -14355,8 +14358,8 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,232,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,233,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,234,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,235,12 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,236,11 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,235,14 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,236,13 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,237,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,238,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,239,1 @@ -14831,7 +14834,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,708,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,709,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,710,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,711,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,711,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,712,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,713,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,714,1 @@ -19661,16 +19664,16 @@ block_count,SetDataProperties,694,0 block_count,SetDataProperties,695,0 block_count,SetDataProperties,696,0 -block_count,ReturnReceiver,0,8 +block_count,ReturnReceiver,0,9 block_count,ReturnReceiver,1,0 -block_count,ReturnReceiver,2,8 +block_count,ReturnReceiver,2,9 block_count,ArrayConstructor,0,2 block_count,ArrayConstructor,1,0 block_count,ArrayConstructor,2,2 block_count,ArrayConstructor,3,2 -block_count,ArrayConstructorImpl,0,247 +block_count,ArrayConstructorImpl,0,230 block_count,ArrayConstructorImpl,1,118 -block_count,ArrayConstructorImpl,2,6 +block_count,ArrayConstructorImpl,2,7 block_count,ArrayConstructorImpl,3,6 block_count,ArrayConstructorImpl,4,1 block_count,ArrayConstructorImpl,5,4 @@ -19710,8 +19713,8 @@ block_count,ArrayConstructorImpl,39,0 block_count,ArrayConstructorImpl,40,111 block_count,ArrayConstructorImpl,41,0 -block_count,ArrayConstructorImpl,42,128 -block_count,ArrayConstructorImpl,43,130 +block_count,ArrayConstructorImpl,42,111 +block_count,ArrayConstructorImpl,43,113 block_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,0,0 block_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,1,0 block_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,2,0 @@ -19800,7 +19803,7 @@ block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,3,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,4,111 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,5,111 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,6,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,6,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,7,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,8,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,9,0 @@ -19815,25 +19818,25 @@ block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,18,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,19,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,20,0 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,21,58 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,22,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,21,57 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,22,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,23,0 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,24,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,24,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,25,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,26,0 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,27,58 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,28,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,27,57 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,28,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,29,0 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,30,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,30,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,31,37 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,32,20 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,33,26 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,34,6 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,35,20 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,36,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,36,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,37,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,38,57 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,39,58 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,39,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,40,53 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,41,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,42,53 @@ -20760,26 +20763,26 @@ block_count,ArrayPrototypePop,37,0 block_count,ArrayPrototypePop,38,0 block_count,ArrayPrototypePop,39,0 -block_count,ArrayPrototypePush,0,205 +block_count,ArrayPrototypePush,0,202 block_count,ArrayPrototypePush,1,0 -block_count,ArrayPrototypePush,2,205 -block_count,ArrayPrototypePush,3,205 -block_count,ArrayPrototypePush,4,205 -block_count,ArrayPrototypePush,5,205 -block_count,ArrayPrototypePush,6,205 +block_count,ArrayPrototypePush,2,202 +block_count,ArrayPrototypePush,3,202 +block_count,ArrayPrototypePush,4,202 +block_count,ArrayPrototypePush,5,202 +block_count,ArrayPrototypePush,6,202 block_count,ArrayPrototypePush,7,0 -block_count,ArrayPrototypePush,8,205 -block_count,ArrayPrototypePush,9,205 -block_count,ArrayPrototypePush,10,205 +block_count,ArrayPrototypePush,8,202 +block_count,ArrayPrototypePush,9,202 +block_count,ArrayPrototypePush,10,202 block_count,ArrayPrototypePush,11,0 -block_count,ArrayPrototypePush,12,205 -block_count,ArrayPrototypePush,13,205 +block_count,ArrayPrototypePush,12,202 +block_count,ArrayPrototypePush,13,202 block_count,ArrayPrototypePush,14,0 -block_count,ArrayPrototypePush,15,205 -block_count,ArrayPrototypePush,16,205 -block_count,ArrayPrototypePush,17,8 -block_count,ArrayPrototypePush,18,8 -block_count,ArrayPrototypePush,19,8 +block_count,ArrayPrototypePush,15,202 +block_count,ArrayPrototypePush,16,202 +block_count,ArrayPrototypePush,17,6 +block_count,ArrayPrototypePush,18,6 +block_count,ArrayPrototypePush,19,6 block_count,ArrayPrototypePush,20,0 block_count,ArrayPrototypePush,21,0 block_count,ArrayPrototypePush,22,0 @@ -20793,32 +20796,32 @@ block_count,ArrayPrototypePush,30,0 block_count,ArrayPrototypePush,31,0 block_count,ArrayPrototypePush,32,0 -block_count,ArrayPrototypePush,33,9 -block_count,ArrayPrototypePush,34,8 +block_count,ArrayPrototypePush,33,8 +block_count,ArrayPrototypePush,34,7 block_count,ArrayPrototypePush,35,0 block_count,ArrayPrototypePush,36,0 block_count,ArrayPrototypePush,37,0 block_count,ArrayPrototypePush,38,0 block_count,ArrayPrototypePush,39,0 block_count,ArrayPrototypePush,40,0 -block_count,ArrayPrototypePush,41,18 -block_count,ArrayPrototypePush,42,18 +block_count,ArrayPrototypePush,41,14 +block_count,ArrayPrototypePush,42,14 block_count,ArrayPrototypePush,43,0 block_count,ArrayPrototypePush,44,0 block_count,ArrayPrototypePush,45,0 block_count,ArrayPrototypePush,46,0 block_count,ArrayPrototypePush,47,0 -block_count,ArrayPrototypePush,48,8 -block_count,ArrayPrototypePush,49,8 -block_count,ArrayPrototypePush,50,8 -block_count,ArrayPrototypePush,51,8 -block_count,ArrayPrototypePush,52,8 +block_count,ArrayPrototypePush,48,6 +block_count,ArrayPrototypePush,49,6 +block_count,ArrayPrototypePush,50,7 +block_count,ArrayPrototypePush,51,6 +block_count,ArrayPrototypePush,52,6 block_count,ArrayPrototypePush,53,0 -block_count,ArrayPrototypePush,54,8 +block_count,ArrayPrototypePush,54,6 block_count,ArrayPrototypePush,55,0 block_count,ArrayPrototypePush,56,0 block_count,ArrayPrototypePush,57,0 -block_count,ArrayPrototypePush,58,8 +block_count,ArrayPrototypePush,58,6 block_count,ArrayPrototypePush,59,0 block_count,ArrayPrototypePush,60,0 block_count,ArrayPrototypePush,61,0 @@ -20827,8 +20830,8 @@ block_count,ArrayPrototypePush,64,0 block_count,ArrayPrototypePush,65,0 block_count,ArrayPrototypePush,66,0 -block_count,ArrayPrototypePush,67,196 -block_count,ArrayPrototypePush,68,195 +block_count,ArrayPrototypePush,67,195 +block_count,ArrayPrototypePush,68,194 block_count,ArrayPrototypePush,69,0 block_count,ArrayPrototypePush,70,0 block_count,ArrayPrototypePush,71,0 @@ -20887,8 +20890,8 @@ block_count,ArrayPrototypePush,124,0 block_count,ArrayPrototypePush,125,0 block_count,ArrayPrototypePush,126,0 -block_count,ArrayPrototypePush,127,196 -block_count,ArrayPrototypePush,128,195 +block_count,ArrayPrototypePush,127,195 +block_count,ArrayPrototypePush,128,194 block_count,ArrayPrototypePush,129,173 block_count,ArrayPrototypePush,130,21 block_count,ArrayPrototypePush,131,21 @@ -20911,22 +20914,22 @@ block_count,ArrayPrototypePush,148,20 block_count,ArrayPrototypePush,149,21 block_count,ArrayPrototypePush,150,1 -block_count,ArrayPrototypePush,151,256 +block_count,ArrayPrototypePush,151,257 block_count,ArrayPrototypePush,152,255 block_count,ArrayPrototypePush,153,1 block_count,ArrayPrototypePush,154,20 block_count,ArrayPrototypePush,155,21 block_count,ArrayPrototypePush,156,0 block_count,ArrayPrototypePush,157,0 -block_count,ArrayPrototypePush,158,195 -block_count,ArrayPrototypePush,159,195 -block_count,ArrayPrototypePush,160,210 -block_count,ArrayPrototypePush,161,210 -block_count,ArrayPrototypePush,162,14 -block_count,ArrayPrototypePush,163,195 +block_count,ArrayPrototypePush,158,194 +block_count,ArrayPrototypePush,159,194 +block_count,ArrayPrototypePush,160,209 +block_count,ArrayPrototypePush,161,209 +block_count,ArrayPrototypePush,162,15 +block_count,ArrayPrototypePush,163,194 block_count,ArrayPrototypePush,164,0 block_count,ArrayPrototypePush,165,0 -block_count,ArrayPrototypePush,166,195 +block_count,ArrayPrototypePush,166,194 block_count,ArrayPrototypePush,167,0 block_count,ArrayPrototypePush,168,0 block_count,ArrayPrototypePush,169,0 @@ -21234,8 +21237,8 @@ block_count,ExtractFastJSArray,29,0 block_count,ExtractFastJSArray,30,0 block_count,ExtractFastJSArray,31,0 -block_count,ExtractFastJSArray,32,3 -block_count,ExtractFastJSArray,33,3 +block_count,ExtractFastJSArray,32,4 +block_count,ExtractFastJSArray,33,4 block_count,ExtractFastJSArray,34,0 block_count,ExtractFastJSArray,35,0 block_count,ExtractFastJSArray,36,0 @@ -22362,14 +22365,14 @@ block_count,GlobalIsNaN,9,0 block_count,GlobalIsNaN,10,0 block_count,LoadIC,0,2458 -block_count,LoadIC,1,2458 +block_count,LoadIC,1,2457 block_count,LoadIC,2,0 block_count,LoadIC,3,2458 block_count,LoadIC,4,2458 -block_count,LoadIC,5,762 +block_count,LoadIC,5,764 block_count,LoadIC,6,0 -block_count,LoadIC,7,762 -block_count,LoadIC,8,130 +block_count,LoadIC,7,763 +block_count,LoadIC,8,129 block_count,LoadIC,9,1 block_count,LoadIC,10,1 block_count,LoadIC,11,0 @@ -22383,36 +22386,36 @@ block_count,LoadIC,19,0 block_count,LoadIC,20,0 block_count,LoadIC,21,0 -block_count,LoadIC,22,128 -block_count,LoadIC,23,128 +block_count,LoadIC,22,127 +block_count,LoadIC,23,127 block_count,LoadIC,24,0 -block_count,LoadIC,25,128 -block_count,LoadIC,26,108 +block_count,LoadIC,25,127 +block_count,LoadIC,26,109 block_count,LoadIC,27,108 block_count,LoadIC,28,0 -block_count,LoadIC,29,20 -block_count,LoadIC,30,20 -block_count,LoadIC,31,19 -block_count,LoadIC,32,19 +block_count,LoadIC,29,18 +block_count,LoadIC,30,18 +block_count,LoadIC,31,17 +block_count,LoadIC,32,17 block_count,LoadIC,33,0 block_count,LoadIC,34,1 -block_count,LoadIC,35,631 +block_count,LoadIC,35,634 block_count,LoadIC,36,990 -block_count,LoadIC,37,358 -block_count,LoadIC,38,358 +block_count,LoadIC,37,356 +block_count,LoadIC,38,356 block_count,LoadIC,39,0 -block_count,LoadIC,40,631 -block_count,LoadIC,41,1696 -block_count,LoadIC,42,2455 -block_count,LoadIC,43,859 -block_count,LoadIC,44,854 -block_count,LoadIC,45,620 -block_count,LoadIC,46,620 +block_count,LoadIC,40,634 +block_count,LoadIC,41,1693 +block_count,LoadIC,42,2454 +block_count,LoadIC,43,853 +block_count,LoadIC,44,848 +block_count,LoadIC,45,615 +block_count,LoadIC,46,615 block_count,LoadIC,47,0 -block_count,LoadIC,48,620 +block_count,LoadIC,48,615 block_count,LoadIC,49,0 -block_count,LoadIC,50,620 -block_count,LoadIC,51,80 +block_count,LoadIC,50,615 +block_count,LoadIC,51,79 block_count,LoadIC,52,36 block_count,LoadIC,53,36 block_count,LoadIC,54,0 @@ -22469,8 +22472,8 @@ block_count,LoadIC,105,0 block_count,LoadIC,106,0 block_count,LoadIC,107,1 -block_count,LoadIC,108,43 -block_count,LoadIC,109,43 +block_count,LoadIC,108,42 +block_count,LoadIC,109,42 block_count,LoadIC,110,0 block_count,LoadIC,111,0 block_count,LoadIC,112,0 @@ -22482,28 +22485,28 @@ block_count,LoadIC,118,0 block_count,LoadIC,119,0 block_count,LoadIC,120,0 -block_count,LoadIC,121,43 +block_count,LoadIC,121,42 block_count,LoadIC,122,0 -block_count,LoadIC,123,540 -block_count,LoadIC,124,619 -block_count,LoadIC,125,618 -block_count,LoadIC,126,571 -block_count,LoadIC,127,571 +block_count,LoadIC,123,536 +block_count,LoadIC,124,613 +block_count,LoadIC,125,613 +block_count,LoadIC,126,566 +block_count,LoadIC,127,566 block_count,LoadIC,128,0 block_count,LoadIC,129,47 -block_count,LoadIC,130,618 +block_count,LoadIC,130,613 block_count,LoadIC,131,0 -block_count,LoadIC,132,233 +block_count,LoadIC,132,232 block_count,LoadIC,133,4 block_count,LoadIC,134,4 block_count,LoadIC,135,0 -block_count,LoadIC,136,1596 +block_count,LoadIC,136,1600 block_count,LoadIC,137,2214 -block_count,LoadIC,138,886 -block_count,LoadIC,139,407 -block_count,LoadIC,140,359 -block_count,LoadIC,141,120 -block_count,LoadIC,142,29 +block_count,LoadIC,138,880 +block_count,LoadIC,139,404 +block_count,LoadIC,140,357 +block_count,LoadIC,141,119 +block_count,LoadIC,142,28 block_count,LoadIC,143,2 block_count,LoadIC,144,2 block_count,LoadIC,145,2 @@ -22572,7 +22575,7 @@ block_count,LoadIC,208,0 block_count,LoadIC,209,0 block_count,LoadIC,210,26 -block_count,LoadIC,211,91 +block_count,LoadIC,211,90 block_count,LoadIC,212,238 block_count,LoadIC,213,238 block_count,LoadIC,214,0 @@ -22630,19 +22633,19 @@ block_count,LoadIC,266,0 block_count,LoadIC,267,238 block_count,LoadIC,268,47 -block_count,LoadIC,269,478 -block_count,LoadIC,270,1328 -block_count,LoadIC,271,1328 +block_count,LoadIC,269,475 +block_count,LoadIC,270,1334 +block_count,LoadIC,271,1334 block_count,LoadIC,272,344 -block_count,LoadIC,273,984 -block_count,LoadIC,274,1328 -block_count,LoadIC,275,1284 -block_count,LoadIC,276,44 -block_count,LoadIC,277,44 -block_count,LoadIC,278,44 +block_count,LoadIC,273,989 +block_count,LoadIC,274,1334 +block_count,LoadIC,275,1288 +block_count,LoadIC,276,45 +block_count,LoadIC,277,45 +block_count,LoadIC,278,45 block_count,LoadIC,279,0 -block_count,LoadIC,280,44 -block_count,LoadIC,281,44 +block_count,LoadIC,280,45 +block_count,LoadIC,281,45 block_count,LoadIC,282,0 block_count,LoadIC,283,0 block_count,LoadIC,284,0 @@ -22692,24 +22695,24 @@ block_count,LoadIC_Megamorphic,4,10000 block_count,LoadIC_Megamorphic,5,0 block_count,LoadIC_Megamorphic,6,10000 -block_count,LoadIC_Megamorphic,7,8575 -block_count,LoadIC_Megamorphic,8,8508 -block_count,LoadIC_Megamorphic,9,67 -block_count,LoadIC_Megamorphic,10,1424 -block_count,LoadIC_Megamorphic,11,1491 -block_count,LoadIC_Megamorphic,12,1482 -block_count,LoadIC_Megamorphic,13,1480 +block_count,LoadIC_Megamorphic,7,8066 +block_count,LoadIC_Megamorphic,8,8051 +block_count,LoadIC_Megamorphic,9,15 +block_count,LoadIC_Megamorphic,10,1933 +block_count,LoadIC_Megamorphic,11,1948 +block_count,LoadIC_Megamorphic,12,1940 +block_count,LoadIC_Megamorphic,13,1938 block_count,LoadIC_Megamorphic,14,1 -block_count,LoadIC_Megamorphic,15,9 +block_count,LoadIC_Megamorphic,15,8 block_count,LoadIC_Megamorphic,16,9989 -block_count,LoadIC_Megamorphic,17,3651 -block_count,LoadIC_Megamorphic,18,3651 -block_count,LoadIC_Megamorphic,19,3639 -block_count,LoadIC_Megamorphic,20,3639 +block_count,LoadIC_Megamorphic,17,3650 +block_count,LoadIC_Megamorphic,18,3650 +block_count,LoadIC_Megamorphic,19,3638 +block_count,LoadIC_Megamorphic,20,3638 block_count,LoadIC_Megamorphic,21,0 -block_count,LoadIC_Megamorphic,22,3639 +block_count,LoadIC_Megamorphic,22,3638 block_count,LoadIC_Megamorphic,23,0 -block_count,LoadIC_Megamorphic,24,3639 +block_count,LoadIC_Megamorphic,24,3638 block_count,LoadIC_Megamorphic,25,8 block_count,LoadIC_Megamorphic,26,4 block_count,LoadIC_Megamorphic,27,4 @@ -22784,12 +22787,12 @@ block_count,LoadIC_Megamorphic,96,0 block_count,LoadIC_Megamorphic,97,3630 block_count,LoadIC_Megamorphic,98,3638 -block_count,LoadIC_Megamorphic,99,3637 +block_count,LoadIC_Megamorphic,99,3636 block_count,LoadIC_Megamorphic,100,2859 block_count,LoadIC_Megamorphic,101,2859 block_count,LoadIC_Megamorphic,102,0 block_count,LoadIC_Megamorphic,103,777 -block_count,LoadIC_Megamorphic,104,3637 +block_count,LoadIC_Megamorphic,104,3636 block_count,LoadIC_Megamorphic,105,1 block_count,LoadIC_Megamorphic,106,11 block_count,LoadIC_Megamorphic,107,0 @@ -22798,10 +22801,10 @@ block_count,LoadIC_Megamorphic,110,6338 block_count,LoadIC_Megamorphic,111,9975 block_count,LoadIC_Megamorphic,112,4340 -block_count,LoadIC_Megamorphic,113,2279 +block_count,LoadIC_Megamorphic,113,2280 block_count,LoadIC_Megamorphic,114,1502 -block_count,LoadIC_Megamorphic,115,1495 -block_count,LoadIC_Megamorphic,116,699 +block_count,LoadIC_Megamorphic,115,1496 +block_count,LoadIC_Megamorphic,116,700 block_count,LoadIC_Megamorphic,117,9 block_count,LoadIC_Megamorphic,118,9 block_count,LoadIC_Megamorphic,119,9 @@ -22983,10 +22986,10 @@ block_count,LoadIC_Megamorphic,295,0 block_count,LoadIC_Megamorphic,296,0 block_count,LoadIC_Megamorphic,297,10 -block_count,LoadIC_Noninlined,0,2 -block_count,LoadIC_Noninlined,1,2 +block_count,LoadIC_Noninlined,0,3 +block_count,LoadIC_Noninlined,1,3 block_count,LoadIC_Noninlined,2,0 -block_count,LoadIC_Noninlined,3,2 +block_count,LoadIC_Noninlined,3,3 block_count,LoadIC_Noninlined,4,1 block_count,LoadIC_Noninlined,5,1 block_count,LoadIC_Noninlined,6,0 @@ -23094,7 +23097,7 @@ block_count,LoadIC_Noninlined,108,0 block_count,LoadIC_Noninlined,109,0 block_count,LoadIC_Noninlined,110,0 -block_count,LoadIC_Noninlined,111,0 +block_count,LoadIC_Noninlined,111,1 block_count,LoadIC_Noninlined,112,1 block_count,LoadIC_Noninlined,113,1 block_count,LoadIC_Noninlined,114,0 @@ -23299,11 +23302,11 @@ block_count,LoadICTrampoline,1,307 block_count,LoadICTrampoline,2,0 block_count,LoadICTrampoline,3,307 -block_count,LoadICBaseline,0,1819 -block_count,LoadICTrampoline_Megamorphic,0,5825 -block_count,LoadICTrampoline_Megamorphic,1,5825 +block_count,LoadICBaseline,0,1818 +block_count,LoadICTrampoline_Megamorphic,0,5822 +block_count,LoadICTrampoline_Megamorphic,1,5822 block_count,LoadICTrampoline_Megamorphic,2,0 -block_count,LoadICTrampoline_Megamorphic,3,5825 +block_count,LoadICTrampoline_Megamorphic,3,5822 block_count,LoadSuperIC,0,2 block_count,LoadSuperIC,1,2 block_count,LoadSuperIC,2,2 @@ -23900,16 +23903,16 @@ block_count,LoadSuperIC,593,0 block_count,LoadSuperIC,594,0 block_count,LoadSuperICBaseline,0,2 -block_count,KeyedLoadIC,0,335 -block_count,KeyedLoadIC,1,335 +block_count,KeyedLoadIC,0,336 +block_count,KeyedLoadIC,1,336 block_count,KeyedLoadIC,2,0 -block_count,KeyedLoadIC,3,335 -block_count,KeyedLoadIC,4,335 +block_count,KeyedLoadIC,3,336 +block_count,KeyedLoadIC,4,336 block_count,KeyedLoadIC,5,333 -block_count,KeyedLoadIC,6,35 +block_count,KeyedLoadIC,6,36 block_count,KeyedLoadIC,7,0 -block_count,KeyedLoadIC,8,35 -block_count,KeyedLoadIC,9,20 +block_count,KeyedLoadIC,8,36 +block_count,KeyedLoadIC,9,21 block_count,KeyedLoadIC,10,1 block_count,KeyedLoadIC,11,0 block_count,KeyedLoadIC,12,0 @@ -23949,11 +23952,11 @@ block_count,KeyedLoadIC,46,0 block_count,KeyedLoadIC,47,0 block_count,KeyedLoadIC,48,0 -block_count,KeyedLoadIC,49,19 +block_count,KeyedLoadIC,49,20 block_count,KeyedLoadIC,50,15 -block_count,KeyedLoadIC,51,23 -block_count,KeyedLoadIC,52,8 -block_count,KeyedLoadIC,53,8 +block_count,KeyedLoadIC,51,24 +block_count,KeyedLoadIC,52,9 +block_count,KeyedLoadIC,53,9 block_count,KeyedLoadIC,54,0 block_count,KeyedLoadIC,55,15 block_count,KeyedLoadIC,56,297 @@ -24053,7 +24056,7 @@ block_count,KeyedLoadIC,150,0 block_count,KeyedLoadIC,151,310 block_count,KeyedLoadIC,152,310 -block_count,KeyedLoadIC,153,3 +block_count,KeyedLoadIC,153,2 block_count,KeyedLoadIC,154,0 block_count,KeyedLoadIC,155,0 block_count,KeyedLoadIC,156,0 @@ -24270,7 +24273,7 @@ block_count,KeyedLoadIC,367,0 block_count,KeyedLoadIC,368,0 block_count,KeyedLoadIC,369,0 -block_count,KeyedLoadIC,370,3 +block_count,KeyedLoadIC,370,2 block_count,KeyedLoadIC,371,0 block_count,KeyedLoadIC,372,0 block_count,KeyedLoadIC,373,0 @@ -24278,19 +24281,19 @@ block_count,KeyedLoadIC,375,0 block_count,KeyedLoadIC,376,0 block_count,KeyedLoadIC,377,0 -block_count,KeyedLoadIC,378,3 -block_count,KeyedLoadIC,379,3 -block_count,KeyedLoadIC,380,3 -block_count,KeyedLoadIC,381,5 -block_count,KeyedLoadIC,382,2 -block_count,KeyedLoadIC,383,2 +block_count,KeyedLoadIC,378,2 +block_count,KeyedLoadIC,379,2 +block_count,KeyedLoadIC,380,2 +block_count,KeyedLoadIC,381,4 +block_count,KeyedLoadIC,382,1 +block_count,KeyedLoadIC,383,1 block_count,KeyedLoadIC,384,0 block_count,KeyedLoadIC,385,0 block_count,KeyedLoadIC,386,0 -block_count,KeyedLoadIC,387,2 -block_count,KeyedLoadIC,388,2 +block_count,KeyedLoadIC,387,1 +block_count,KeyedLoadIC,388,1 block_count,KeyedLoadIC,389,0 -block_count,KeyedLoadIC,390,2 +block_count,KeyedLoadIC,390,1 block_count,KeyedLoadIC,391,0 block_count,KeyedLoadIC,392,0 block_count,KeyedLoadIC,393,0 @@ -24303,16 +24306,16 @@ block_count,KeyedLoadIC,400,0 block_count,KeyedLoadIC,401,0 block_count,KeyedLoadIC,402,0 -block_count,KeyedLoadIC,403,3 -block_count,KeyedLoadIC,404,3 +block_count,KeyedLoadIC,403,2 +block_count,KeyedLoadIC,404,2 block_count,KeyedLoadIC,405,0 -block_count,KeyedLoadIC,406,3 -block_count,KeyedLoadIC,407,3 +block_count,KeyedLoadIC,406,2 +block_count,KeyedLoadIC,407,2 block_count,KeyedLoadIC,408,0 block_count,KeyedLoadIC,409,0 block_count,KeyedLoadIC,410,0 block_count,KeyedLoadIC,411,0 -block_count,KeyedLoadIC,412,3 +block_count,KeyedLoadIC,412,2 block_count,KeyedLoadIC,413,0 block_count,KeyedLoadIC,414,0 block_count,KeyedLoadIC,415,0 @@ -24320,7 +24323,7 @@ block_count,KeyedLoadIC,417,0 block_count,KeyedLoadIC,418,0 block_count,KeyedLoadIC,419,0 -block_count,KeyedLoadIC,420,306 +block_count,KeyedLoadIC,420,307 block_count,KeyedLoadIC,421,0 block_count,KeyedLoadIC,422,0 block_count,KeyedLoadIC,423,0 @@ -24333,43 +24336,43 @@ block_count,KeyedLoadIC,430,0 block_count,KeyedLoadIC,431,0 block_count,KeyedLoadIC,432,0 -block_count,KeyedLoadIC,433,306 -block_count,KeyedLoadIC,434,306 -block_count,KeyedLoadIC,435,306 -block_count,KeyedLoadIC,436,171 +block_count,KeyedLoadIC,433,307 +block_count,KeyedLoadIC,434,307 +block_count,KeyedLoadIC,435,307 +block_count,KeyedLoadIC,436,174 block_count,KeyedLoadIC,437,5 -block_count,KeyedLoadIC,438,166 -block_count,KeyedLoadIC,439,171 +block_count,KeyedLoadIC,438,169 +block_count,KeyedLoadIC,439,174 block_count,KeyedLoadIC,440,0 -block_count,KeyedLoadIC,441,171 +block_count,KeyedLoadIC,441,173 block_count,KeyedLoadIC,442,0 block_count,KeyedLoadIC,443,12 -block_count,KeyedLoadIC,444,98 +block_count,KeyedLoadIC,444,99 block_count,KeyedLoadIC,445,0 block_count,KeyedLoadIC,446,0 block_count,KeyedLoadIC,447,0 block_count,KeyedLoadIC,448,0 -block_count,KeyedLoadIC,449,110 +block_count,KeyedLoadIC,449,112 block_count,KeyedLoadIC,450,6 block_count,KeyedLoadIC,451,30 block_count,KeyedLoadIC,452,0 block_count,KeyedLoadIC,453,0 block_count,KeyedLoadIC,454,0 -block_count,KeyedLoadIC,455,37 -block_count,KeyedLoadIC,456,35 +block_count,KeyedLoadIC,455,36 +block_count,KeyedLoadIC,456,34 block_count,KeyedLoadIC,457,1 -block_count,KeyedLoadIC,458,9 +block_count,KeyedLoadIC,458,11 block_count,KeyedLoadIC,459,0 -block_count,KeyedLoadIC,460,9 -block_count,KeyedLoadIC,461,9 +block_count,KeyedLoadIC,460,11 +block_count,KeyedLoadIC,461,11 block_count,KeyedLoadIC,462,13 block_count,KeyedLoadIC,463,13 block_count,KeyedLoadIC,464,0 block_count,KeyedLoadIC,465,13 block_count,KeyedLoadIC,466,13 block_count,KeyedLoadIC,467,0 -block_count,KeyedLoadIC,468,134 -block_count,KeyedLoadIC,469,134 +block_count,KeyedLoadIC,468,133 +block_count,KeyedLoadIC,469,133 block_count,KeyedLoadIC,470,0 block_count,KeyedLoadIC,471,0 block_count,KeyedLoadIC,472,0 @@ -24392,17 +24395,17 @@ block_count,KeyedLoadIC,489,0 block_count,KeyedLoadIC,490,0 block_count,KeyedLoadIC,491,0 -block_count,KeyedLoadIC,492,134 -block_count,KeyedLoadIC,493,134 +block_count,KeyedLoadIC,492,133 +block_count,KeyedLoadIC,493,133 block_count,KeyedLoadIC,494,0 -block_count,KeyedLoadIC,495,134 +block_count,KeyedLoadIC,495,133 block_count,KeyedLoadIC,496,0 -block_count,KeyedLoadIC,497,16 +block_count,KeyedLoadIC,497,15 block_count,KeyedLoadIC,498,0 block_count,KeyedLoadIC,499,0 -block_count,KeyedLoadIC,500,3 +block_count,KeyedLoadIC,500,4 block_count,KeyedLoadIC,501,0 -block_count,KeyedLoadIC,502,1 +block_count,KeyedLoadIC,502,0 block_count,KeyedLoadIC,503,93 block_count,KeyedLoadIC,504,19 block_count,KeyedLoadIC,505,0 @@ -24457,8 +24460,8 @@ block_count,KeyedLoadIC,554,0 block_count,KeyedLoadIC,555,0 block_count,KeyedLoadIC,556,0 -block_count,KeyedLoadIC,557,1 -block_count,KeyedLoadIC,558,1 +block_count,KeyedLoadIC,557,0 +block_count,KeyedLoadIC,558,0 block_count,KeyedLoadIC,559,0 block_count,KeyedLoadIC,560,0 block_count,KeyedLoadIC,561,0 @@ -24505,10 +24508,10 @@ block_count,KeyedLoadIC,602,0 block_count,KeyedLoadIC,603,0 block_count,KeyedLoadIC,604,0 -block_count,KeyedLoadIC,605,2 +block_count,KeyedLoadIC,605,1 block_count,KeyedLoadIC,606,0 -block_count,KeyedLoadIC,607,2 -block_count,KeyedLoadIC,608,2 +block_count,KeyedLoadIC,607,1 +block_count,KeyedLoadIC,608,1 block_count,KeyedLoadIC,609,0 block_count,KeyedLoadIC,610,0 block_count,KeyedLoadIC,611,0 @@ -25209,22 +25212,22 @@ block_count,KeyedLoadIC_Megamorphic,8,0 block_count,KeyedLoadIC_Megamorphic,9,3 block_count,KeyedLoadIC_Megamorphic,10,2063 -block_count,KeyedLoadIC_Megamorphic,11,2061 +block_count,KeyedLoadIC_Megamorphic,11,2062 block_count,KeyedLoadIC_Megamorphic,12,47 block_count,KeyedLoadIC_Megamorphic,13,42 block_count,KeyedLoadIC_Megamorphic,14,5 -block_count,KeyedLoadIC_Megamorphic,15,2013 -block_count,KeyedLoadIC_Megamorphic,16,2013 +block_count,KeyedLoadIC_Megamorphic,15,2014 +block_count,KeyedLoadIC_Megamorphic,16,2014 block_count,KeyedLoadIC_Megamorphic,17,1917 block_count,KeyedLoadIC_Megamorphic,18,1917 -block_count,KeyedLoadIC_Megamorphic,19,1810 +block_count,KeyedLoadIC_Megamorphic,19,1815 block_count,KeyedLoadIC_Megamorphic,20,0 block_count,KeyedLoadIC_Megamorphic,21,0 block_count,KeyedLoadIC_Megamorphic,22,0 -block_count,KeyedLoadIC_Megamorphic,23,1810 -block_count,KeyedLoadIC_Megamorphic,24,972 +block_count,KeyedLoadIC_Megamorphic,23,1815 +block_count,KeyedLoadIC_Megamorphic,24,977 block_count,KeyedLoadIC_Megamorphic,25,837 -block_count,KeyedLoadIC_Megamorphic,26,107 +block_count,KeyedLoadIC_Megamorphic,26,102 block_count,KeyedLoadIC_Megamorphic,27,0 block_count,KeyedLoadIC_Megamorphic,28,96 block_count,KeyedLoadIC_Megamorphic,29,42 @@ -25552,7 +25555,7 @@ block_count,KeyedLoadIC_Megamorphic,351,1 block_count,KeyedLoadIC_Megamorphic,352,1086 block_count,KeyedLoadIC_Megamorphic,353,1086 -block_count,KeyedLoadIC_Megamorphic,354,455 +block_count,KeyedLoadIC_Megamorphic,354,456 block_count,KeyedLoadIC_Megamorphic,355,432 block_count,KeyedLoadIC_Megamorphic,356,51 block_count,KeyedLoadIC_Megamorphic,357,51 @@ -25584,14 +25587,14 @@ block_count,KeyedLoadIC_Megamorphic,383,381 block_count,KeyedLoadIC_Megamorphic,384,9 block_count,KeyedLoadIC_Megamorphic,385,371 -block_count,KeyedLoadIC_Megamorphic,386,1003 -block_count,KeyedLoadIC_Megamorphic,387,860 -block_count,KeyedLoadIC_Megamorphic,388,723 +block_count,KeyedLoadIC_Megamorphic,386,1004 +block_count,KeyedLoadIC_Megamorphic,387,861 +block_count,KeyedLoadIC_Megamorphic,388,724 block_count,KeyedLoadIC_Megamorphic,389,632 block_count,KeyedLoadIC_Megamorphic,390,91 block_count,KeyedLoadIC_Megamorphic,391,136 block_count,KeyedLoadIC_Megamorphic,392,143 -block_count,KeyedLoadIC_Megamorphic,393,100 +block_count,KeyedLoadIC_Megamorphic,393,101 block_count,KeyedLoadIC_Megamorphic,394,68 block_count,KeyedLoadIC_Megamorphic,395,32 block_count,KeyedLoadIC_Megamorphic,396,19 @@ -25616,13 +25619,13 @@ block_count,KeyedLoadIC_Megamorphic,415,111 block_count,KeyedLoadIC_Megamorphic,416,0 block_count,KeyedLoadIC_Megamorphic,417,111 -block_count,KeyedLoadIC_Megamorphic,418,81 -block_count,KeyedLoadIC_Megamorphic,419,80 +block_count,KeyedLoadIC_Megamorphic,418,86 +block_count,KeyedLoadIC_Megamorphic,419,86 block_count,KeyedLoadIC_Megamorphic,420,0 -block_count,KeyedLoadIC_Megamorphic,421,30 -block_count,KeyedLoadIC_Megamorphic,422,30 -block_count,KeyedLoadIC_Megamorphic,423,14 -block_count,KeyedLoadIC_Megamorphic,424,14 +block_count,KeyedLoadIC_Megamorphic,421,25 +block_count,KeyedLoadIC_Megamorphic,422,25 +block_count,KeyedLoadIC_Megamorphic,423,9 +block_count,KeyedLoadIC_Megamorphic,424,9 block_count,KeyedLoadIC_Megamorphic,425,0 block_count,KeyedLoadIC_Megamorphic,426,15 block_count,KeyedLoadIC_Megamorphic,427,95 @@ -26342,16 +26345,16 @@ block_count,KeyedLoadICTrampoline,3,1 block_count,KeyedLoadICBaseline,0,313 block_count,EnumeratedKeyedLoadICBaseline,0,3 -block_count,KeyedLoadICTrampoline_Megamorphic,0,1085 -block_count,KeyedLoadICTrampoline_Megamorphic,1,1085 +block_count,KeyedLoadICTrampoline_Megamorphic,0,1086 +block_count,KeyedLoadICTrampoline_Megamorphic,1,1086 block_count,KeyedLoadICTrampoline_Megamorphic,2,0 -block_count,KeyedLoadICTrampoline_Megamorphic,3,1085 -block_count,StoreGlobalIC,0,565 -block_count,StoreGlobalIC,1,565 -block_count,StoreGlobalIC,2,565 -block_count,StoreGlobalIC,3,565 -block_count,StoreGlobalIC,4,565 -block_count,StoreGlobalIC,5,565 +block_count,KeyedLoadICTrampoline_Megamorphic,3,1086 +block_count,StoreGlobalIC,0,567 +block_count,StoreGlobalIC,1,567 +block_count,StoreGlobalIC,2,567 +block_count,StoreGlobalIC,3,567 +block_count,StoreGlobalIC,4,567 +block_count,StoreGlobalIC,5,567 block_count,StoreGlobalIC,6,1 block_count,StoreGlobalIC,7,0 block_count,StoreGlobalIC,8,0 @@ -26361,7 +26364,7 @@ block_count,StoreGlobalIC,12,1 block_count,StoreGlobalIC,13,0 block_count,StoreGlobalIC,14,1 -block_count,StoreGlobalIC,15,563 +block_count,StoreGlobalIC,15,565 block_count,StoreGlobalIC,16,0 block_count,StoreGlobalIC,17,0 block_count,StoreGlobalIC,18,0 @@ -26873,39 +26876,39 @@ block_count,StoreGlobalICTrampoline,2,0 block_count,StoreGlobalICTrampoline,3,187 block_count,StoreGlobalICBaseline,0,1 -block_count,StoreIC,0,269 -block_count,StoreIC,1,269 +block_count,StoreIC,0,271 +block_count,StoreIC,1,271 block_count,StoreIC,2,0 -block_count,StoreIC,3,269 -block_count,StoreIC,4,269 -block_count,StoreIC,5,263 -block_count,StoreIC,6,99 +block_count,StoreIC,3,271 +block_count,StoreIC,4,271 +block_count,StoreIC,5,265 +block_count,StoreIC,6,100 block_count,StoreIC,7,0 -block_count,StoreIC,8,99 +block_count,StoreIC,8,100 block_count,StoreIC,9,24 block_count,StoreIC,10,0 -block_count,StoreIC,11,24 -block_count,StoreIC,12,24 +block_count,StoreIC,11,23 +block_count,StoreIC,12,23 block_count,StoreIC,13,0 -block_count,StoreIC,14,24 +block_count,StoreIC,14,23 block_count,StoreIC,15,22 block_count,StoreIC,16,22 block_count,StoreIC,17,0 block_count,StoreIC,18,1 block_count,StoreIC,19,1 -block_count,StoreIC,20,1 -block_count,StoreIC,21,1 +block_count,StoreIC,20,0 +block_count,StoreIC,21,0 block_count,StoreIC,22,0 block_count,StoreIC,23,0 -block_count,StoreIC,24,74 -block_count,StoreIC,25,118 +block_count,StoreIC,24,75 +block_count,StoreIC,25,119 block_count,StoreIC,26,43 block_count,StoreIC,27,43 block_count,StoreIC,28,0 -block_count,StoreIC,29,74 -block_count,StoreIC,30,163 -block_count,StoreIC,31,262 -block_count,StoreIC,32,94 +block_count,StoreIC,29,75 +block_count,StoreIC,30,164 +block_count,StoreIC,31,264 +block_count,StoreIC,32,95 block_count,StoreIC,33,5 block_count,StoreIC,34,5 block_count,StoreIC,35,5 @@ -27067,9 +27070,9 @@ block_count,StoreIC,191,0 block_count,StoreIC,192,64 block_count,StoreIC,193,64 -block_count,StoreIC,194,12 +block_count,StoreIC,194,13 block_count,StoreIC,195,0 -block_count,StoreIC,196,12 +block_count,StoreIC,196,13 block_count,StoreIC,197,51 block_count,StoreIC,198,0 block_count,StoreIC,199,2 @@ -27121,11 +27124,11 @@ block_count,StoreIC,245,2 block_count,StoreIC,246,2 block_count,StoreIC,247,0 -block_count,StoreIC,248,2 +block_count,StoreIC,248,1 block_count,StoreIC,249,7 block_count,StoreIC,250,8 block_count,StoreIC,251,16 -block_count,StoreIC,252,61 +block_count,StoreIC,252,62 block_count,StoreIC,253,60 block_count,StoreIC,254,1 block_count,StoreIC,255,1 @@ -27154,7 +27157,7 @@ block_count,StoreIC,278,0 block_count,StoreIC,279,0 block_count,StoreIC,280,0 -block_count,StoreIC,281,167 +block_count,StoreIC,281,169 block_count,StoreIC,282,13 block_count,StoreIC,283,13 block_count,StoreIC,284,13 @@ -27179,9 +27182,9 @@ block_count,StoreIC,303,0 block_count,StoreIC,304,0 block_count,StoreIC,305,0 -block_count,StoreIC,306,153 -block_count,StoreIC,307,134 -block_count,StoreIC,308,134 +block_count,StoreIC,306,155 +block_count,StoreIC,307,135 +block_count,StoreIC,308,135 block_count,StoreIC,309,10 block_count,StoreIC,310,9 block_count,StoreIC,311,9 @@ -27213,7 +27216,7 @@ block_count,StoreIC,337,3 block_count,StoreIC,338,0 block_count,StoreIC,339,3 -block_count,StoreIC,340,64 +block_count,StoreIC,340,63 block_count,StoreIC,341,0 block_count,StoreIC,342,67 block_count,StoreIC,343,15 @@ -27224,13 +27227,13 @@ block_count,StoreIC,348,0 block_count,StoreIC,349,0 block_count,StoreIC,350,0 -block_count,StoreIC,351,54 +block_count,StoreIC,351,55 block_count,StoreIC,352,0 -block_count,StoreIC,353,54 +block_count,StoreIC,353,55 block_count,StoreIC,354,8 -block_count,StoreIC,355,45 -block_count,StoreIC,356,54 -block_count,StoreIC,357,54 +block_count,StoreIC,355,47 +block_count,StoreIC,356,55 +block_count,StoreIC,357,55 block_count,StoreIC,358,0 block_count,StoreIC,359,0 block_count,StoreIC,360,0 @@ -27257,24 +27260,24 @@ block_count,StoreIC,381,6 block_count,StoreIC,382,0 block_count,StoreIC,383,1 -block_count,StoreIC_Megamorphic,0,1373 -block_count,StoreIC_Megamorphic,1,1373 +block_count,StoreIC_Megamorphic,0,1376 +block_count,StoreIC_Megamorphic,1,1376 block_count,StoreIC_Megamorphic,2,0 -block_count,StoreIC_Megamorphic,3,1373 -block_count,StoreIC_Megamorphic,4,1373 +block_count,StoreIC_Megamorphic,3,1376 +block_count,StoreIC_Megamorphic,4,1376 block_count,StoreIC_Megamorphic,5,0 -block_count,StoreIC_Megamorphic,6,1373 -block_count,StoreIC_Megamorphic,7,1222 -block_count,StoreIC_Megamorphic,8,1207 -block_count,StoreIC_Megamorphic,9,15 -block_count,StoreIC_Megamorphic,10,151 -block_count,StoreIC_Megamorphic,11,166 -block_count,StoreIC_Megamorphic,12,165 -block_count,StoreIC_Megamorphic,13,163 +block_count,StoreIC_Megamorphic,6,1376 +block_count,StoreIC_Megamorphic,7,1264 +block_count,StoreIC_Megamorphic,8,1252 +block_count,StoreIC_Megamorphic,9,12 +block_count,StoreIC_Megamorphic,10,111 +block_count,StoreIC_Megamorphic,11,123 +block_count,StoreIC_Megamorphic,12,123 +block_count,StoreIC_Megamorphic,13,121 block_count,StoreIC_Megamorphic,14,1 block_count,StoreIC_Megamorphic,15,0 -block_count,StoreIC_Megamorphic,16,1370 -block_count,StoreIC_Megamorphic,17,590 +block_count,StoreIC_Megamorphic,16,1373 +block_count,StoreIC_Megamorphic,17,592 block_count,StoreIC_Megamorphic,18,1 block_count,StoreIC_Megamorphic,19,1 block_count,StoreIC_Megamorphic,20,1 @@ -27415,41 +27418,41 @@ block_count,StoreIC_Megamorphic,155,0 block_count,StoreIC_Megamorphic,156,0 block_count,StoreIC_Megamorphic,157,0 -block_count,StoreIC_Megamorphic,158,588 -block_count,StoreIC_Megamorphic,159,588 -block_count,StoreIC_Megamorphic,160,394 -block_count,StoreIC_Megamorphic,161,394 -block_count,StoreIC_Megamorphic,162,394 +block_count,StoreIC_Megamorphic,158,590 +block_count,StoreIC_Megamorphic,159,590 +block_count,StoreIC_Megamorphic,160,397 +block_count,StoreIC_Megamorphic,161,397 +block_count,StoreIC_Megamorphic,162,397 block_count,StoreIC_Megamorphic,163,0 -block_count,StoreIC_Megamorphic,164,394 +block_count,StoreIC_Megamorphic,164,397 block_count,StoreIC_Megamorphic,165,0 -block_count,StoreIC_Megamorphic,166,394 -block_count,StoreIC_Megamorphic,167,394 +block_count,StoreIC_Megamorphic,166,397 +block_count,StoreIC_Megamorphic,167,397 block_count,StoreIC_Megamorphic,168,0 block_count,StoreIC_Megamorphic,169,0 block_count,StoreIC_Megamorphic,170,0 -block_count,StoreIC_Megamorphic,171,394 -block_count,StoreIC_Megamorphic,172,242 -block_count,StoreIC_Megamorphic,173,242 +block_count,StoreIC_Megamorphic,171,397 +block_count,StoreIC_Megamorphic,172,243 +block_count,StoreIC_Megamorphic,173,243 block_count,StoreIC_Megamorphic,174,0 block_count,StoreIC_Megamorphic,175,0 block_count,StoreIC_Megamorphic,176,0 -block_count,StoreIC_Megamorphic,177,242 -block_count,StoreIC_Megamorphic,178,242 +block_count,StoreIC_Megamorphic,177,243 +block_count,StoreIC_Megamorphic,178,243 block_count,StoreIC_Megamorphic,179,65 block_count,StoreIC_Megamorphic,180,0 block_count,StoreIC_Megamorphic,181,65 -block_count,StoreIC_Megamorphic,182,176 +block_count,StoreIC_Megamorphic,182,177 block_count,StoreIC_Megamorphic,183,0 block_count,StoreIC_Megamorphic,184,0 block_count,StoreIC_Megamorphic,185,0 block_count,StoreIC_Megamorphic,186,0 block_count,StoreIC_Megamorphic,187,0 block_count,StoreIC_Megamorphic,188,0 -block_count,StoreIC_Megamorphic,189,152 +block_count,StoreIC_Megamorphic,189,153 block_count,StoreIC_Megamorphic,190,0 -block_count,StoreIC_Megamorphic,191,152 -block_count,StoreIC_Megamorphic,192,394 +block_count,StoreIC_Megamorphic,191,153 +block_count,StoreIC_Megamorphic,192,397 block_count,StoreIC_Megamorphic,193,31 block_count,StoreIC_Megamorphic,194,0 block_count,StoreIC_Megamorphic,195,0 @@ -27494,8 +27497,8 @@ block_count,StoreIC_Megamorphic,234,13 block_count,StoreIC_Megamorphic,235,17 block_count,StoreIC_Megamorphic,236,31 -block_count,StoreIC_Megamorphic,237,362 -block_count,StoreIC_Megamorphic,238,362 +block_count,StoreIC_Megamorphic,237,365 +block_count,StoreIC_Megamorphic,238,365 block_count,StoreIC_Megamorphic,239,0 block_count,StoreIC_Megamorphic,240,0 block_count,StoreIC_Megamorphic,241,0 @@ -27523,7 +27526,7 @@ block_count,StoreIC_Megamorphic,263,0 block_count,StoreIC_Megamorphic,264,0 block_count,StoreIC_Megamorphic,265,0 -block_count,StoreIC_Megamorphic,266,780 +block_count,StoreIC_Megamorphic,266,781 block_count,StoreIC_Megamorphic,267,0 block_count,StoreIC_Megamorphic,268,0 block_count,StoreIC_Megamorphic,269,0 @@ -27548,9 +27551,9 @@ block_count,StoreIC_Megamorphic,288,0 block_count,StoreIC_Megamorphic,289,0 block_count,StoreIC_Megamorphic,290,0 -block_count,StoreIC_Megamorphic,291,780 -block_count,StoreIC_Megamorphic,292,780 -block_count,StoreIC_Megamorphic,293,780 +block_count,StoreIC_Megamorphic,291,781 +block_count,StoreIC_Megamorphic,292,781 +block_count,StoreIC_Megamorphic,293,781 block_count,StoreIC_Megamorphic,294,6 block_count,StoreIC_Megamorphic,295,6 block_count,StoreIC_Megamorphic,296,6 @@ -27586,7 +27589,7 @@ block_count,StoreIC_Megamorphic,326,0 block_count,StoreIC_Megamorphic,327,442 block_count,StoreIC_Megamorphic,328,2 -block_count,StoreIC_Megamorphic,329,439 +block_count,StoreIC_Megamorphic,329,440 block_count,StoreIC_Megamorphic,330,442 block_count,StoreIC_Megamorphic,331,442 block_count,StoreIC_Megamorphic,332,0 @@ -27597,7 +27600,7 @@ block_count,StoreIC_Megamorphic,337,0 block_count,StoreIC_Megamorphic,338,330 block_count,StoreIC_Megamorphic,339,2 -block_count,StoreIC_Megamorphic,340,327 +block_count,StoreIC_Megamorphic,340,328 block_count,StoreIC_Megamorphic,341,330 block_count,StoreIC_Megamorphic,342,330 block_count,StoreIC_Megamorphic,343,0 @@ -27628,17 +27631,17 @@ block_count,StoreICTrampoline,1,27 block_count,StoreICTrampoline,2,0 block_count,StoreICTrampoline,3,27 -block_count,StoreICTrampoline_Megamorphic,0,638 -block_count,StoreICTrampoline_Megamorphic,1,638 +block_count,StoreICTrampoline_Megamorphic,0,637 +block_count,StoreICTrampoline_Megamorphic,1,637 block_count,StoreICTrampoline_Megamorphic,2,0 -block_count,StoreICTrampoline_Megamorphic,3,638 -block_count,StoreICBaseline,0,207 +block_count,StoreICTrampoline_Megamorphic,3,637 +block_count,StoreICBaseline,0,208 block_count,DefineNamedOwnIC,0,39 block_count,DefineNamedOwnIC,1,39 block_count,DefineNamedOwnIC,2,0 block_count,DefineNamedOwnIC,3,39 block_count,DefineNamedOwnIC,4,39 -block_count,DefineNamedOwnIC,5,34 +block_count,DefineNamedOwnIC,5,35 block_count,DefineNamedOwnIC,6,0 block_count,DefineNamedOwnIC,7,0 block_count,DefineNamedOwnIC,8,0 @@ -28008,12 +28011,12 @@ block_count,DefineNamedOwnIC,372,0 block_count,DefineNamedOwnIC,373,0 block_count,DefineNamedOwnICBaseline,0,34 -block_count,KeyedStoreIC,0,223 -block_count,KeyedStoreIC,1,223 +block_count,KeyedStoreIC,0,220 +block_count,KeyedStoreIC,1,220 block_count,KeyedStoreIC,2,0 -block_count,KeyedStoreIC,3,223 -block_count,KeyedStoreIC,4,223 -block_count,KeyedStoreIC,5,220 +block_count,KeyedStoreIC,3,220 +block_count,KeyedStoreIC,4,220 +block_count,KeyedStoreIC,5,218 block_count,KeyedStoreIC,6,18 block_count,KeyedStoreIC,7,0 block_count,KeyedStoreIC,8,18 @@ -28027,16 +28030,16 @@ block_count,KeyedStoreIC,16,0 block_count,KeyedStoreIC,17,0 block_count,KeyedStoreIC,18,10 -block_count,KeyedStoreIC,19,6 -block_count,KeyedStoreIC,20,11 +block_count,KeyedStoreIC,19,7 +block_count,KeyedStoreIC,20,13 block_count,KeyedStoreIC,21,5 block_count,KeyedStoreIC,22,5 block_count,KeyedStoreIC,23,0 -block_count,KeyedStoreIC,24,6 -block_count,KeyedStoreIC,25,202 -block_count,KeyedStoreIC,26,210 -block_count,KeyedStoreIC,27,208 -block_count,KeyedStoreIC,28,208 +block_count,KeyedStoreIC,24,7 +block_count,KeyedStoreIC,25,199 +block_count,KeyedStoreIC,26,207 +block_count,KeyedStoreIC,27,206 +block_count,KeyedStoreIC,28,205 block_count,KeyedStoreIC,29,30 block_count,KeyedStoreIC,30,30 block_count,KeyedStoreIC,31,0 @@ -28212,7 +28215,7 @@ block_count,KeyedStoreIC,201,0 block_count,KeyedStoreIC,202,0 block_count,KeyedStoreIC,203,0 -block_count,KeyedStoreIC,204,178 +block_count,KeyedStoreIC,204,175 block_count,KeyedStoreIC,205,0 block_count,KeyedStoreIC,206,0 block_count,KeyedStoreIC,207,0 @@ -28462,7 +28465,7 @@ block_count,KeyedStoreICTrampoline_Megamorphic,1,260 block_count,KeyedStoreICTrampoline_Megamorphic,2,0 block_count,KeyedStoreICTrampoline_Megamorphic,3,260 -block_count,KeyedStoreICBaseline,0,208 +block_count,KeyedStoreICBaseline,0,205 block_count,DefineKeyedOwnIC,0,2 block_count,DefineKeyedOwnIC,1,2 block_count,DefineKeyedOwnIC,2,0 @@ -28923,7 +28926,7 @@ block_count,StoreInArrayLiteralIC,15,1 block_count,StoreInArrayLiteralIC,16,0 block_count,StoreInArrayLiteralIC,17,1 -block_count,StoreInArrayLiteralIC,18,15 +block_count,StoreInArrayLiteralIC,18,14 block_count,StoreInArrayLiteralIC,19,16 block_count,StoreInArrayLiteralIC,20,16 block_count,StoreInArrayLiteralIC,21,0 @@ -28937,11 +28940,11 @@ block_count,StoreInArrayLiteralIC,29,0 block_count,StoreInArrayLiteralIC,30,0 block_count,StoreInArrayLiteralICBaseline,0,15 -block_count,LoadGlobalIC,0,1196 -block_count,LoadGlobalIC,1,1196 -block_count,LoadGlobalIC,2,1129 -block_count,LoadGlobalIC,3,1129 -block_count,LoadGlobalIC,4,1129 +block_count,LoadGlobalIC,0,1392 +block_count,LoadGlobalIC,1,1392 +block_count,LoadGlobalIC,2,1325 +block_count,LoadGlobalIC,3,1325 +block_count,LoadGlobalIC,4,1325 block_count,LoadGlobalIC,5,0 block_count,LoadGlobalIC,6,0 block_count,LoadGlobalIC,7,0 @@ -29368,18 +29371,18 @@ block_count,LoadGlobalICInsideTypeof,210,0 block_count,LoadGlobalICInsideTypeof,211,0 block_count,LoadGlobalICInsideTypeof,212,0 -block_count,LoadGlobalICTrampoline,0,731 -block_count,LoadGlobalICTrampoline,1,731 +block_count,LoadGlobalICTrampoline,0,937 +block_count,LoadGlobalICTrampoline,1,937 block_count,LoadGlobalICTrampoline,2,0 -block_count,LoadGlobalICTrampoline,3,731 +block_count,LoadGlobalICTrampoline,3,937 block_count,LoadGlobalICBaseline,0,400 block_count,LoadGlobalICInsideTypeofBaseline,0,0 -block_count,LookupGlobalICBaseline,0,1 -block_count,LookupGlobalICBaseline,1,1 -block_count,LookupGlobalICBaseline,2,1 +block_count,LookupGlobalICBaseline,0,0 +block_count,LookupGlobalICBaseline,1,0 +block_count,LookupGlobalICBaseline,2,0 block_count,LookupGlobalICBaseline,3,0 -block_count,LookupGlobalICBaseline,4,1 -block_count,LookupGlobalICBaseline,5,1 +block_count,LookupGlobalICBaseline,4,0 +block_count,LookupGlobalICBaseline,5,0 block_count,LookupGlobalICBaseline,6,0 block_count,LookupGlobalICBaseline,7,0 block_count,LookupGlobalICBaseline,8,0 @@ -29799,8 +29802,8 @@ block_count,KeyedHasIC_Megamorphic,115,0 block_count,KeyedHasIC_Megamorphic,116,0 block_count,KeyedHasIC_Megamorphic,117,0 -block_count,KeyedHasIC_Megamorphic,118,2820 -block_count,KeyedHasIC_Megamorphic,119,2820 +block_count,KeyedHasIC_Megamorphic,118,2819 +block_count,KeyedHasIC_Megamorphic,119,2819 block_count,KeyedHasIC_Megamorphic,120,0 block_count,KeyedHasIC_Megamorphic,121,0 block_count,KeyedHasIC_Megamorphic,122,0 @@ -29839,12 +29842,12 @@ block_count,KeyedHasIC_Megamorphic,155,0 block_count,KeyedHasIC_Megamorphic,156,0 block_count,KeyedHasIC_Megamorphic,157,0 -block_count,KeyedHasIC_Megamorphic,158,2820 +block_count,KeyedHasIC_Megamorphic,158,2819 block_count,KeyedHasIC_Megamorphic,159,4 block_count,KeyedHasIC_Megamorphic,160,4 block_count,KeyedHasIC_Megamorphic,161,0 block_count,KeyedHasIC_Megamorphic,162,2815 -block_count,KeyedHasIC_Megamorphic,163,2820 +block_count,KeyedHasIC_Megamorphic,163,2819 block_count,KeyedHasIC_Megamorphic,164,2112 block_count,KeyedHasIC_Megamorphic,165,707 block_count,KeyedHasIC_Megamorphic,166,1 @@ -30214,7 +30217,7 @@ block_count,IterableToListConvertHoles,6,40 block_count,IterableToListConvertHoles,7,40 block_count,IterableToListConvertHoles,8,40 -block_count,FindOrderedHashMapEntry,0,391 +block_count,FindOrderedHashMapEntry,0,394 block_count,FindOrderedHashMapEntry,1,385 block_count,FindOrderedHashMapEntry,2,129 block_count,FindOrderedHashMapEntry,3,129 @@ -30231,9 +30234,9 @@ block_count,FindOrderedHashMapEntry,14,56 block_count,FindOrderedHashMapEntry,15,62 block_count,FindOrderedHashMapEntry,16,129 -block_count,FindOrderedHashMapEntry,17,228 -block_count,FindOrderedHashMapEntry,18,122 -block_count,FindOrderedHashMapEntry,19,98 +block_count,FindOrderedHashMapEntry,17,174 +block_count,FindOrderedHashMapEntry,18,68 +block_count,FindOrderedHashMapEntry,19,44 block_count,FindOrderedHashMapEntry,20,23 block_count,FindOrderedHashMapEntry,21,106 block_count,FindOrderedHashMapEntry,22,0 @@ -30269,7 +30272,7 @@ block_count,FindOrderedHashMapEntry,52,247 block_count,FindOrderedHashMapEntry,53,8 block_count,FindOrderedHashMapEntry,54,256 -block_count,FindOrderedHashMapEntry,55,323 +block_count,FindOrderedHashMapEntry,55,322 block_count,FindOrderedHashMapEntry,56,281 block_count,FindOrderedHashMapEntry,57,281 block_count,FindOrderedHashMapEntry,58,1 @@ -30282,22 +30285,22 @@ block_count,FindOrderedHashMapEntry,65,154 block_count,FindOrderedHashMapEntry,66,214 block_count,FindOrderedHashMapEntry,67,0 -block_count,FindOrderedHashMapEntry,68,67 +block_count,FindOrderedHashMapEntry,68,66 block_count,FindOrderedHashMapEntry,69,41 -block_count,FindOrderedHashMapEntry,70,5 -block_count,FindOrderedHashMapEntry,71,13 -block_count,FindOrderedHashMapEntry,72,9 -block_count,FindOrderedHashMapEntry,73,8 +block_count,FindOrderedHashMapEntry,70,9 +block_count,FindOrderedHashMapEntry,71,25 +block_count,FindOrderedHashMapEntry,72,17 +block_count,FindOrderedHashMapEntry,73,15 block_count,FindOrderedHashMapEntry,74,1 block_count,FindOrderedHashMapEntry,75,0 block_count,FindOrderedHashMapEntry,76,0 block_count,FindOrderedHashMapEntry,77,0 block_count,FindOrderedHashMapEntry,78,1 -block_count,FindOrderedHashMapEntry,79,6 -block_count,FindOrderedHashMapEntry,80,8 -block_count,FindOrderedHashMapEntry,81,0 -block_count,FindOrderedHashMapEntry,82,0 -block_count,FindOrderedHashMapEntry,83,4 +block_count,FindOrderedHashMapEntry,79,14 +block_count,FindOrderedHashMapEntry,80,15 +block_count,FindOrderedHashMapEntry,81,1 +block_count,FindOrderedHashMapEntry,82,1 +block_count,FindOrderedHashMapEntry,83,7 block_count,MapConstructor,0,76 block_count,MapConstructor,1,0 block_count,MapConstructor,2,76 @@ -30705,9 +30708,9 @@ block_count,MapPrototypeSet,27,42 block_count,MapPrototypeSet,28,45 block_count,MapPrototypeSet,29,45 -block_count,MapPrototypeSet,30,77 -block_count,MapPrototypeSet,31,42 -block_count,MapPrototypeSet,32,31 +block_count,MapPrototypeSet,30,75 +block_count,MapPrototypeSet,31,41 +block_count,MapPrototypeSet,32,30 block_count,MapPrototypeSet,33,11 block_count,MapPrototypeSet,34,34 block_count,MapPrototypeSet,35,0 @@ -30879,14 +30882,14 @@ block_count,MapPrototypeDelete,96,0 block_count,MapPrototypeDelete,97,0 block_count,MapPrototypeDelete,98,0 -block_count,MapPrototypeGet,0,21 +block_count,MapPrototypeGet,0,25 block_count,MapPrototypeGet,1,0 -block_count,MapPrototypeGet,2,21 -block_count,MapPrototypeGet,3,21 -block_count,MapPrototypeGet,4,21 +block_count,MapPrototypeGet,2,25 +block_count,MapPrototypeGet,3,25 +block_count,MapPrototypeGet,4,25 block_count,MapPrototypeGet,5,0 -block_count,MapPrototypeGet,6,21 -block_count,MapPrototypeGet,7,14 +block_count,MapPrototypeGet,6,25 +block_count,MapPrototypeGet,7,18 block_count,MapPrototypeGet,8,7 block_count,MapPrototypeGet,9,0 block_count,MapPrototypeGet,10,7 @@ -31073,7 +31076,7 @@ block_count,MapIteratorToList,54,0 block_count,MapIteratorToList,55,0 block_count,MapIteratorToList,56,0 -block_count,Add_Baseline,0,200 +block_count,Add_Baseline,0,192 block_count,Add_Baseline,1,122 block_count,Add_Baseline,2,1 block_count,Add_Baseline,3,1 @@ -31081,18 +31084,18 @@ block_count,Add_Baseline,5,121 block_count,Add_Baseline,6,121 block_count,Add_Baseline,7,0 -block_count,Add_Baseline,8,120 +block_count,Add_Baseline,8,121 block_count,Add_Baseline,9,121 block_count,Add_Baseline,10,0 -block_count,Add_Baseline,11,78 -block_count,Add_Baseline,12,44 -block_count,Add_Baseline,13,39 -block_count,Add_Baseline,14,39 +block_count,Add_Baseline,11,69 +block_count,Add_Baseline,12,36 +block_count,Add_Baseline,13,31 +block_count,Add_Baseline,14,31 block_count,Add_Baseline,15,0 block_count,Add_Baseline,16,5 -block_count,Add_Baseline,17,34 -block_count,Add_Baseline,18,34 -block_count,Add_Baseline,19,32 +block_count,Add_Baseline,17,33 +block_count,Add_Baseline,18,33 +block_count,Add_Baseline,19,31 block_count,Add_Baseline,20,0 block_count,Add_Baseline,21,0 block_count,Add_Baseline,22,0 @@ -31147,7 +31150,7 @@ block_count,Add_Baseline,71,0 block_count,Add_Baseline,72,0 block_count,Add_Baseline,73,0 -block_count,Add_Baseline,74,31 +block_count,Add_Baseline,74,30 block_count,Add_Baseline,75,2 block_count,Add_Baseline,76,2 block_count,Add_Baseline,77,0 @@ -31156,10 +31159,10 @@ block_count,Add_Baseline,80,0 block_count,Add_Baseline,81,0 block_count,Add_Baseline,82,0 -block_count,Add_Baseline,83,29 +block_count,Add_Baseline,83,28 block_count,Add_Baseline,84,0 -block_count,Add_Baseline,85,29 -block_count,Add_Baseline,86,29 +block_count,Add_Baseline,85,28 +block_count,Add_Baseline,86,28 block_count,Add_Baseline,87,1 block_count,Add_Baseline,88,0 block_count,Add_Baseline,89,0 @@ -31175,19 +31178,19 @@ block_count,Add_Baseline,99,0 block_count,Add_Baseline,100,4 block_count,Add_Baseline,101,4 -block_count,Add_Baseline,102,45 +block_count,Add_Baseline,102,38 block_count,Add_Baseline,103,0 -block_count,Add_Baseline,104,45 -block_count,Add_Baseline,105,45 +block_count,Add_Baseline,104,38 +block_count,Add_Baseline,105,38 block_count,Add_Baseline,106,0 -block_count,Add_Baseline,107,45 -block_count,Add_Baseline,108,45 -block_count,AddSmi_Baseline,0,245 -block_count,AddSmi_Baseline,1,244 -block_count,AddSmi_Baseline,2,244 +block_count,Add_Baseline,107,38 +block_count,Add_Baseline,108,38 +block_count,AddSmi_Baseline,0,242 +block_count,AddSmi_Baseline,1,242 +block_count,AddSmi_Baseline,2,242 block_count,AddSmi_Baseline,3,0 -block_count,AddSmi_Baseline,4,244 -block_count,AddSmi_Baseline,5,244 +block_count,AddSmi_Baseline,4,242 +block_count,AddSmi_Baseline,5,242 block_count,AddSmi_Baseline,6,0 block_count,AddSmi_Baseline,7,0 block_count,AddSmi_Baseline,8,0 @@ -31287,18 +31290,18 @@ block_count,Subtract_Baseline,2,1 block_count,Subtract_Baseline,3,1 block_count,Subtract_Baseline,4,0 -block_count,Subtract_Baseline,5,33 -block_count,Subtract_Baseline,6,33 +block_count,Subtract_Baseline,5,32 +block_count,Subtract_Baseline,6,32 block_count,Subtract_Baseline,7,0 block_count,Subtract_Baseline,8,0 block_count,Subtract_Baseline,9,0 block_count,Subtract_Baseline,10,0 -block_count,Subtract_Baseline,11,33 +block_count,Subtract_Baseline,11,32 block_count,Subtract_Baseline,12,0 -block_count,Subtract_Baseline,13,33 -block_count,Subtract_Baseline,14,33 -block_count,Subtract_Baseline,15,12 -block_count,Subtract_Baseline,16,12 +block_count,Subtract_Baseline,13,32 +block_count,Subtract_Baseline,14,32 +block_count,Subtract_Baseline,15,13 +block_count,Subtract_Baseline,16,13 block_count,Subtract_Baseline,17,12 block_count,Subtract_Baseline,18,12 block_count,Subtract_Baseline,19,0 @@ -31399,12 +31402,12 @@ block_count,SubtractSmi_Baseline,16,0 block_count,SubtractSmi_Baseline,17,3 block_count,SubtractSmi_Baseline,18,3 -block_count,Multiply_Baseline,0,58 -block_count,Multiply_Baseline,1,17 -block_count,Multiply_Baseline,2,11 -block_count,Multiply_Baseline,3,11 +block_count,Multiply_Baseline,0,47 +block_count,Multiply_Baseline,1,10 +block_count,Multiply_Baseline,2,6 +block_count,Multiply_Baseline,3,6 block_count,Multiply_Baseline,4,0 -block_count,Multiply_Baseline,5,5 +block_count,Multiply_Baseline,5,4 block_count,Multiply_Baseline,6,4 block_count,Multiply_Baseline,7,3 block_count,Multiply_Baseline,8,3 @@ -31420,17 +31423,17 @@ block_count,Multiply_Baseline,18,0 block_count,Multiply_Baseline,19,0 block_count,Multiply_Baseline,20,0 -block_count,Multiply_Baseline,21,5 +block_count,Multiply_Baseline,21,4 block_count,Multiply_Baseline,22,0 block_count,Multiply_Baseline,23,4 -block_count,Multiply_Baseline,24,5 +block_count,Multiply_Baseline,24,4 block_count,Multiply_Baseline,25,0 -block_count,Multiply_Baseline,26,5 -block_count,Multiply_Baseline,27,5 -block_count,Multiply_Baseline,28,41 -block_count,Multiply_Baseline,29,41 -block_count,Multiply_Baseline,30,39 -block_count,Multiply_Baseline,31,39 +block_count,Multiply_Baseline,26,4 +block_count,Multiply_Baseline,27,4 +block_count,Multiply_Baseline,28,36 +block_count,Multiply_Baseline,29,36 +block_count,Multiply_Baseline,30,34 +block_count,Multiply_Baseline,31,34 block_count,Multiply_Baseline,32,0 block_count,Multiply_Baseline,33,1 block_count,Multiply_Baseline,34,0 @@ -31505,13 +31508,13 @@ block_count,Multiply_Baseline,103,0 block_count,Multiply_Baseline,104,0 block_count,Multiply_Baseline,105,0 -block_count,Multiply_Baseline,106,53 +block_count,Multiply_Baseline,106,42 block_count,Multiply_Baseline,107,0 -block_count,Multiply_Baseline,108,53 -block_count,Multiply_Baseline,109,53 +block_count,Multiply_Baseline,108,42 +block_count,Multiply_Baseline,109,42 block_count,Multiply_Baseline,110,0 -block_count,Multiply_Baseline,111,53 -block_count,Multiply_Baseline,112,53 +block_count,Multiply_Baseline,111,42 +block_count,Multiply_Baseline,112,42 block_count,MultiplySmi_Baseline,0,5 block_count,MultiplySmi_Baseline,1,4 block_count,MultiplySmi_Baseline,2,4 @@ -31615,7 +31618,7 @@ block_count,MultiplySmi_Baseline,100,0 block_count,MultiplySmi_Baseline,101,0 block_count,MultiplySmi_Baseline,102,0 -block_count,Divide_Baseline,0,3 +block_count,Divide_Baseline,0,4 block_count,Divide_Baseline,1,2 block_count,Divide_Baseline,2,1 block_count,Divide_Baseline,3,1 @@ -31724,13 +31727,13 @@ block_count,Divide_Baseline,106,0 block_count,Divide_Baseline,107,0 block_count,Divide_Baseline,108,0 -block_count,Divide_Baseline,109,2 +block_count,Divide_Baseline,109,3 block_count,Divide_Baseline,110,0 -block_count,Divide_Baseline,111,2 -block_count,Divide_Baseline,112,2 +block_count,Divide_Baseline,111,3 +block_count,Divide_Baseline,112,3 block_count,Divide_Baseline,113,0 -block_count,Divide_Baseline,114,2 -block_count,Divide_Baseline,115,2 +block_count,Divide_Baseline,114,3 +block_count,Divide_Baseline,115,3 block_count,DivideSmi_Baseline,0,1 block_count,DivideSmi_Baseline,1,0 block_count,DivideSmi_Baseline,2,0 @@ -32159,7 +32162,7 @@ block_count,BitwiseAnd_Baseline,128,0 block_count,BitwiseAnd_Baseline,129,8 block_count,BitwiseAnd_Baseline,130,8 -block_count,BitwiseAndSmi_Baseline,0,34 +block_count,BitwiseAndSmi_Baseline,0,31 block_count,BitwiseAndSmi_Baseline,1,1 block_count,BitwiseAndSmi_Baseline,2,1 block_count,BitwiseAndSmi_Baseline,3,0 @@ -32190,10 +32193,10 @@ block_count,BitwiseAndSmi_Baseline,28,0 block_count,BitwiseAndSmi_Baseline,29,1 block_count,BitwiseAndSmi_Baseline,30,1 -block_count,BitwiseAndSmi_Baseline,31,32 -block_count,BitwiseAndSmi_Baseline,32,34 +block_count,BitwiseAndSmi_Baseline,31,30 +block_count,BitwiseAndSmi_Baseline,32,31 block_count,BitwiseAndSmi_Baseline,33,0 -block_count,BitwiseAndSmi_Baseline,34,34 +block_count,BitwiseAndSmi_Baseline,34,31 block_count,BitwiseOr_Baseline,0,19 block_count,BitwiseOr_Baseline,1,18 block_count,BitwiseOr_Baseline,2,1 @@ -32359,7 +32362,7 @@ block_count,BitwiseOrSmi_Baseline,31,180 block_count,BitwiseOrSmi_Baseline,32,182 block_count,BitwiseOrSmi_Baseline,33,0 -block_count,BitwiseOrSmi_Baseline,34,181 +block_count,BitwiseOrSmi_Baseline,34,182 block_count,BitwiseXor_Baseline,0,9 block_count,BitwiseXor_Baseline,1,5 block_count,BitwiseXor_Baseline,2,4 @@ -32605,7 +32608,7 @@ block_count,ShiftLeft_Baseline,76,0 block_count,ShiftLeft_Baseline,77,1 block_count,ShiftLeft_Baseline,78,1 -block_count,ShiftLeftSmi_Baseline,0,31 +block_count,ShiftLeftSmi_Baseline,0,30 block_count,ShiftLeftSmi_Baseline,1,1 block_count,ShiftLeftSmi_Baseline,2,1 block_count,ShiftLeftSmi_Baseline,3,0 @@ -32637,20 +32640,20 @@ block_count,ShiftLeftSmi_Baseline,29,0 block_count,ShiftLeftSmi_Baseline,30,1 block_count,ShiftLeftSmi_Baseline,31,29 -block_count,ShiftLeftSmi_Baseline,32,29 +block_count,ShiftLeftSmi_Baseline,32,28 block_count,ShiftLeftSmi_Baseline,33,0 block_count,ShiftLeftSmi_Baseline,34,0 block_count,ShiftLeftSmi_Baseline,35,0 block_count,ShiftLeftSmi_Baseline,36,0 block_count,ShiftLeftSmi_Baseline,37,29 block_count,ShiftLeftSmi_Baseline,38,0 -block_count,ShiftLeftSmi_Baseline,39,29 +block_count,ShiftLeftSmi_Baseline,39,28 block_count,ShiftLeftSmi_Baseline,40,29 -block_count,ShiftLeftSmi_Baseline,41,31 +block_count,ShiftLeftSmi_Baseline,41,30 block_count,ShiftLeftSmi_Baseline,42,0 -block_count,ShiftLeftSmi_Baseline,43,31 -block_count,ShiftRight_Baseline,0,1 -block_count,ShiftRight_Baseline,1,1 +block_count,ShiftLeftSmi_Baseline,43,30 +block_count,ShiftRight_Baseline,0,2 +block_count,ShiftRight_Baseline,1,2 block_count,ShiftRight_Baseline,2,0 block_count,ShiftRight_Baseline,3,0 block_count,ShiftRight_Baseline,4,0 @@ -32693,8 +32696,8 @@ block_count,ShiftRight_Baseline,41,0 block_count,ShiftRight_Baseline,42,0 block_count,ShiftRight_Baseline,43,0 -block_count,ShiftRight_Baseline,44,1 -block_count,ShiftRight_Baseline,45,1 +block_count,ShiftRight_Baseline,44,2 +block_count,ShiftRight_Baseline,45,2 block_count,ShiftRight_Baseline,46,0 block_count,ShiftRight_Baseline,47,0 block_count,ShiftRight_Baseline,48,0 @@ -32715,20 +32718,20 @@ block_count,ShiftRight_Baseline,63,0 block_count,ShiftRight_Baseline,64,0 block_count,ShiftRight_Baseline,65,0 -block_count,ShiftRight_Baseline,66,1 -block_count,ShiftRight_Baseline,67,1 +block_count,ShiftRight_Baseline,66,2 +block_count,ShiftRight_Baseline,67,2 block_count,ShiftRight_Baseline,68,0 block_count,ShiftRight_Baseline,69,0 block_count,ShiftRight_Baseline,70,0 block_count,ShiftRight_Baseline,71,0 -block_count,ShiftRight_Baseline,72,1 +block_count,ShiftRight_Baseline,72,2 block_count,ShiftRight_Baseline,73,0 -block_count,ShiftRight_Baseline,74,1 -block_count,ShiftRight_Baseline,75,1 +block_count,ShiftRight_Baseline,74,2 +block_count,ShiftRight_Baseline,75,2 block_count,ShiftRight_Baseline,76,0 -block_count,ShiftRight_Baseline,77,1 -block_count,ShiftRight_Baseline,78,1 -block_count,ShiftRightSmi_Baseline,0,117 +block_count,ShiftRight_Baseline,77,2 +block_count,ShiftRight_Baseline,78,2 +block_count,ShiftRightSmi_Baseline,0,115 block_count,ShiftRightSmi_Baseline,1,1 block_count,ShiftRightSmi_Baseline,2,1 block_count,ShiftRightSmi_Baseline,3,0 @@ -32759,10 +32762,10 @@ block_count,ShiftRightSmi_Baseline,28,0 block_count,ShiftRightSmi_Baseline,29,1 block_count,ShiftRightSmi_Baseline,30,1 -block_count,ShiftRightSmi_Baseline,31,116 -block_count,ShiftRightSmi_Baseline,32,117 +block_count,ShiftRightSmi_Baseline,31,114 +block_count,ShiftRightSmi_Baseline,32,115 block_count,ShiftRightSmi_Baseline,33,0 -block_count,ShiftRightSmi_Baseline,34,117 +block_count,ShiftRightSmi_Baseline,34,115 block_count,ShiftRightLogical_Baseline,0,0 block_count,ShiftRightLogical_Baseline,1,0 block_count,ShiftRightLogical_Baseline,2,0 @@ -32957,7 +32960,7 @@ block_count,Add_WithFeedback,71,0 block_count,Add_WithFeedback,72,0 block_count,Add_WithFeedback,73,0 -block_count,Add_WithFeedback,74,32 +block_count,Add_WithFeedback,74,31 block_count,Add_WithFeedback,75,30 block_count,Add_WithFeedback,76,30 block_count,Add_WithFeedback,77,0 @@ -33422,9 +33425,9 @@ block_count,BitwiseOr_WithFeedback,128,0 block_count,BitwiseOr_WithFeedback,129,0 block_count,BitwiseOr_WithFeedback,130,0 -block_count,Equal_Baseline,0,153 -block_count,Equal_Baseline,1,154 -block_count,Equal_Baseline,2,126 +block_count,Equal_Baseline,0,154 +block_count,Equal_Baseline,1,155 +block_count,Equal_Baseline,2,127 block_count,Equal_Baseline,3,22 block_count,Equal_Baseline,4,21 block_count,Equal_Baseline,5,9 @@ -33488,7 +33491,7 @@ block_count,Equal_Baseline,63,0 block_count,Equal_Baseline,64,0 block_count,Equal_Baseline,65,0 -block_count,Equal_Baseline,66,2 +block_count,Equal_Baseline,66,1 block_count,Equal_Baseline,67,1 block_count,Equal_Baseline,68,0 block_count,Equal_Baseline,69,1 @@ -33522,7 +33525,7 @@ block_count,Equal_Baseline,97,12 block_count,Equal_Baseline,98,0 block_count,Equal_Baseline,99,12 -block_count,Equal_Baseline,100,8 +block_count,Equal_Baseline,100,9 block_count,Equal_Baseline,101,3 block_count,Equal_Baseline,102,3 block_count,Equal_Baseline,103,3 @@ -33536,7 +33539,7 @@ block_count,Equal_Baseline,111,12 block_count,Equal_Baseline,112,0 block_count,Equal_Baseline,113,0 -block_count,Equal_Baseline,114,103 +block_count,Equal_Baseline,114,104 block_count,Equal_Baseline,115,1 block_count,Equal_Baseline,116,0 block_count,Equal_Baseline,117,0 @@ -33575,7 +33578,7 @@ block_count,Equal_Baseline,150,28 block_count,Equal_Baseline,151,6 block_count,Equal_Baseline,152,6 -block_count,Equal_Baseline,153,4 +block_count,Equal_Baseline,153,3 block_count,Equal_Baseline,154,1 block_count,Equal_Baseline,155,0 block_count,Equal_Baseline,156,0 @@ -33590,7 +33593,7 @@ block_count,Equal_Baseline,165,0 block_count,Equal_Baseline,166,1 block_count,Equal_Baseline,167,0 -block_count,Equal_Baseline,168,1 +block_count,Equal_Baseline,168,0 block_count,Equal_Baseline,169,2 block_count,Equal_Baseline,170,2 block_count,Equal_Baseline,171,0 @@ -33601,25 +33604,25 @@ block_count,Equal_Baseline,176,0 block_count,Equal_Baseline,177,22 block_count,Equal_Baseline,178,29 -block_count,Equal_Baseline,179,111 -block_count,Equal_Baseline,180,153 +block_count,Equal_Baseline,179,112 +block_count,Equal_Baseline,180,154 block_count,Equal_Baseline,181,0 -block_count,Equal_Baseline,182,153 -block_count,StrictEqual_Baseline,0,198 -block_count,StrictEqual_Baseline,1,167 -block_count,StrictEqual_Baseline,2,122 -block_count,StrictEqual_Baseline,3,122 -block_count,StrictEqual_Baseline,4,121 -block_count,StrictEqual_Baseline,5,56 -block_count,StrictEqual_Baseline,6,56 -block_count,StrictEqual_Baseline,7,25 -block_count,StrictEqual_Baseline,8,24 -block_count,StrictEqual_Baseline,9,19 +block_count,Equal_Baseline,182,154 +block_count,StrictEqual_Baseline,0,191 +block_count,StrictEqual_Baseline,1,160 +block_count,StrictEqual_Baseline,2,115 +block_count,StrictEqual_Baseline,3,115 +block_count,StrictEqual_Baseline,4,114 +block_count,StrictEqual_Baseline,5,57 +block_count,StrictEqual_Baseline,6,57 +block_count,StrictEqual_Baseline,7,26 +block_count,StrictEqual_Baseline,8,25 +block_count,StrictEqual_Baseline,9,20 block_count,StrictEqual_Baseline,10,0 -block_count,StrictEqual_Baseline,11,19 +block_count,StrictEqual_Baseline,11,20 block_count,StrictEqual_Baseline,12,0 -block_count,StrictEqual_Baseline,13,19 -block_count,StrictEqual_Baseline,14,4 +block_count,StrictEqual_Baseline,13,20 +block_count,StrictEqual_Baseline,14,5 block_count,StrictEqual_Baseline,15,2 block_count,StrictEqual_Baseline,16,2 block_count,StrictEqual_Baseline,17,1 @@ -33660,16 +33663,16 @@ block_count,StrictEqual_Baseline,52,0 block_count,StrictEqual_Baseline,53,0 block_count,StrictEqual_Baseline,54,0 -block_count,StrictEqual_Baseline,55,65 +block_count,StrictEqual_Baseline,55,57 block_count,StrictEqual_Baseline,56,0 -block_count,StrictEqual_Baseline,57,65 -block_count,StrictEqual_Baseline,58,22 -block_count,StrictEqual_Baseline,59,43 -block_count,StrictEqual_Baseline,60,65 +block_count,StrictEqual_Baseline,57,57 +block_count,StrictEqual_Baseline,58,15 +block_count,StrictEqual_Baseline,59,41 +block_count,StrictEqual_Baseline,60,57 block_count,StrictEqual_Baseline,61,0 -block_count,StrictEqual_Baseline,62,64 -block_count,StrictEqual_Baseline,63,65 -block_count,StrictEqual_Baseline,64,49 +block_count,StrictEqual_Baseline,62,56 +block_count,StrictEqual_Baseline,63,57 +block_count,StrictEqual_Baseline,64,41 block_count,StrictEqual_Baseline,65,15 block_count,StrictEqual_Baseline,66,0 block_count,StrictEqual_Baseline,67,0 @@ -33689,7 +33692,7 @@ block_count,StrictEqual_Baseline,81,0 block_count,StrictEqual_Baseline,82,44 block_count,StrictEqual_Baseline,83,5 -block_count,StrictEqual_Baseline,84,30 +block_count,StrictEqual_Baseline,84,31 block_count,StrictEqual_Baseline,85,15 block_count,StrictEqual_Baseline,86,15 block_count,StrictEqual_Baseline,87,8 @@ -33717,13 +33720,13 @@ block_count,StrictEqual_Baseline,109,0 block_count,StrictEqual_Baseline,110,0 block_count,StrictEqual_Baseline,111,15 -block_count,StrictEqual_Baseline,112,102 -block_count,StrictEqual_Baseline,113,30 -block_count,StrictEqual_Baseline,114,198 +block_count,StrictEqual_Baseline,112,103 +block_count,StrictEqual_Baseline,113,31 +block_count,StrictEqual_Baseline,114,191 block_count,StrictEqual_Baseline,115,0 -block_count,StrictEqual_Baseline,116,198 -block_count,LessThan_Baseline,0,152 -block_count,LessThan_Baseline,1,152 +block_count,StrictEqual_Baseline,116,191 +block_count,LessThan_Baseline,0,147 +block_count,LessThan_Baseline,1,148 block_count,LessThan_Baseline,2,9 block_count,LessThan_Baseline,3,3 block_count,LessThan_Baseline,4,0 @@ -33817,7 +33820,7 @@ block_count,LessThan_Baseline,92,0 block_count,LessThan_Baseline,93,0 block_count,LessThan_Baseline,94,0 -block_count,LessThan_Baseline,95,3 +block_count,LessThan_Baseline,95,2 block_count,LessThan_Baseline,96,0 block_count,LessThan_Baseline,97,0 block_count,LessThan_Baseline,98,0 @@ -33827,7 +33830,7 @@ block_count,LessThan_Baseline,102,0 block_count,LessThan_Baseline,103,0 block_count,LessThan_Baseline,104,0 -block_count,LessThan_Baseline,105,3 +block_count,LessThan_Baseline,105,2 block_count,LessThan_Baseline,106,6 block_count,LessThan_Baseline,107,0 block_count,LessThan_Baseline,108,0 @@ -33839,7 +33842,7 @@ block_count,LessThan_Baseline,114,0 block_count,LessThan_Baseline,115,0 block_count,LessThan_Baseline,116,6 -block_count,LessThan_Baseline,117,142 +block_count,LessThan_Baseline,117,138 block_count,LessThan_Baseline,118,0 block_count,LessThan_Baseline,119,0 block_count,LessThan_Baseline,120,0 @@ -33851,24 +33854,24 @@ block_count,LessThan_Baseline,126,0 block_count,LessThan_Baseline,127,0 block_count,LessThan_Baseline,128,0 -block_count,LessThan_Baseline,129,141 -block_count,LessThan_Baseline,130,40 -block_count,LessThan_Baseline,131,100 +block_count,LessThan_Baseline,129,138 +block_count,LessThan_Baseline,130,41 +block_count,LessThan_Baseline,131,97 block_count,LessThan_Baseline,132,0 block_count,LessThan_Baseline,133,0 block_count,LessThan_Baseline,134,0 block_count,LessThan_Baseline,135,0 block_count,LessThan_Baseline,136,0 -block_count,LessThan_Baseline,137,10 +block_count,LessThan_Baseline,137,9 block_count,LessThan_Baseline,138,7 block_count,LessThan_Baseline,139,2 block_count,LessThan_Baseline,140,48 -block_count,LessThan_Baseline,141,103 -block_count,LessThan_Baseline,142,152 +block_count,LessThan_Baseline,141,99 +block_count,LessThan_Baseline,142,147 block_count,LessThan_Baseline,143,0 -block_count,LessThan_Baseline,144,152 -block_count,GreaterThan_Baseline,0,44 -block_count,GreaterThan_Baseline,1,44 +block_count,LessThan_Baseline,144,147 +block_count,GreaterThan_Baseline,0,45 +block_count,GreaterThan_Baseline,1,45 block_count,GreaterThan_Baseline,2,3 block_count,GreaterThan_Baseline,3,2 block_count,GreaterThan_Baseline,4,0 @@ -34007,13 +34010,13 @@ block_count,GreaterThan_Baseline,137,3 block_count,GreaterThan_Baseline,138,2 block_count,GreaterThan_Baseline,139,1 -block_count,GreaterThan_Baseline,140,26 +block_count,GreaterThan_Baseline,140,27 block_count,GreaterThan_Baseline,141,18 -block_count,GreaterThan_Baseline,142,44 +block_count,GreaterThan_Baseline,142,45 block_count,GreaterThan_Baseline,143,0 -block_count,GreaterThan_Baseline,144,44 -block_count,LessThanOrEqual_Baseline,0,19 -block_count,LessThanOrEqual_Baseline,1,19 +block_count,GreaterThan_Baseline,144,45 +block_count,LessThanOrEqual_Baseline,0,20 +block_count,LessThanOrEqual_Baseline,1,20 block_count,LessThanOrEqual_Baseline,2,1 block_count,LessThanOrEqual_Baseline,3,0 block_count,LessThanOrEqual_Baseline,4,0 @@ -34118,7 +34121,7 @@ block_count,LessThanOrEqual_Baseline,103,0 block_count,LessThanOrEqual_Baseline,104,0 block_count,LessThanOrEqual_Baseline,105,0 -block_count,LessThanOrEqual_Baseline,106,0 +block_count,LessThanOrEqual_Baseline,106,1 block_count,LessThanOrEqual_Baseline,107,0 block_count,LessThanOrEqual_Baseline,108,0 block_count,LessThanOrEqual_Baseline,109,0 @@ -34128,7 +34131,7 @@ block_count,LessThanOrEqual_Baseline,113,0 block_count,LessThanOrEqual_Baseline,114,0 block_count,LessThanOrEqual_Baseline,115,0 -block_count,LessThanOrEqual_Baseline,116,0 +block_count,LessThanOrEqual_Baseline,116,1 block_count,LessThanOrEqual_Baseline,117,18 block_count,LessThanOrEqual_Baseline,118,0 block_count,LessThanOrEqual_Baseline,119,0 @@ -34141,7 +34144,7 @@ block_count,LessThanOrEqual_Baseline,126,0 block_count,LessThanOrEqual_Baseline,127,0 block_count,LessThanOrEqual_Baseline,128,0 -block_count,LessThanOrEqual_Baseline,129,17 +block_count,LessThanOrEqual_Baseline,129,18 block_count,LessThanOrEqual_Baseline,130,1 block_count,LessThanOrEqual_Baseline,131,16 block_count,LessThanOrEqual_Baseline,132,0 @@ -34153,12 +34156,12 @@ block_count,LessThanOrEqual_Baseline,138,0 block_count,LessThanOrEqual_Baseline,139,1 block_count,LessThanOrEqual_Baseline,140,2 -block_count,LessThanOrEqual_Baseline,141,17 -block_count,LessThanOrEqual_Baseline,142,19 +block_count,LessThanOrEqual_Baseline,141,18 +block_count,LessThanOrEqual_Baseline,142,20 block_count,LessThanOrEqual_Baseline,143,0 -block_count,LessThanOrEqual_Baseline,144,19 +block_count,LessThanOrEqual_Baseline,144,20 block_count,GreaterThanOrEqual_Baseline,0,39 -block_count,GreaterThanOrEqual_Baseline,1,39 +block_count,GreaterThanOrEqual_Baseline,1,40 block_count,GreaterThanOrEqual_Baseline,2,3 block_count,GreaterThanOrEqual_Baseline,3,2 block_count,GreaterThanOrEqual_Baseline,4,0 @@ -34263,7 +34266,7 @@ block_count,GreaterThanOrEqual_Baseline,103,0 block_count,GreaterThanOrEqual_Baseline,104,0 block_count,GreaterThanOrEqual_Baseline,105,2 -block_count,GreaterThanOrEqual_Baseline,106,0 +block_count,GreaterThanOrEqual_Baseline,106,1 block_count,GreaterThanOrEqual_Baseline,107,0 block_count,GreaterThanOrEqual_Baseline,108,0 block_count,GreaterThanOrEqual_Baseline,109,0 @@ -34273,7 +34276,7 @@ block_count,GreaterThanOrEqual_Baseline,113,0 block_count,GreaterThanOrEqual_Baseline,114,0 block_count,GreaterThanOrEqual_Baseline,115,0 -block_count,GreaterThanOrEqual_Baseline,116,0 +block_count,GreaterThanOrEqual_Baseline,116,1 block_count,GreaterThanOrEqual_Baseline,117,36 block_count,GreaterThanOrEqual_Baseline,118,0 block_count,GreaterThanOrEqual_Baseline,119,0 @@ -34297,25 +34300,25 @@ block_count,GreaterThanOrEqual_Baseline,137,3 block_count,GreaterThanOrEqual_Baseline,138,1 block_count,GreaterThanOrEqual_Baseline,139,1 -block_count,GreaterThanOrEqual_Baseline,140,22 +block_count,GreaterThanOrEqual_Baseline,140,23 block_count,GreaterThanOrEqual_Baseline,141,16 block_count,GreaterThanOrEqual_Baseline,142,39 block_count,GreaterThanOrEqual_Baseline,143,0 block_count,GreaterThanOrEqual_Baseline,144,39 -block_count,Equal_WithFeedback,0,11 -block_count,Equal_WithFeedback,1,15 -block_count,Equal_WithFeedback,2,11 -block_count,Equal_WithFeedback,3,9 -block_count,Equal_WithFeedback,4,9 -block_count,Equal_WithFeedback,5,8 +block_count,Equal_WithFeedback,0,10 +block_count,Equal_WithFeedback,1,13 +block_count,Equal_WithFeedback,2,9 +block_count,Equal_WithFeedback,3,8 +block_count,Equal_WithFeedback,4,8 +block_count,Equal_WithFeedback,5,7 block_count,Equal_WithFeedback,6,6 -block_count,Equal_WithFeedback,7,6 -block_count,Equal_WithFeedback,8,5 -block_count,Equal_WithFeedback,9,5 +block_count,Equal_WithFeedback,7,5 +block_count,Equal_WithFeedback,8,4 +block_count,Equal_WithFeedback,9,4 block_count,Equal_WithFeedback,10,1 -block_count,Equal_WithFeedback,11,1 -block_count,Equal_WithFeedback,12,1 -block_count,Equal_WithFeedback,13,1 +block_count,Equal_WithFeedback,11,0 +block_count,Equal_WithFeedback,12,0 +block_count,Equal_WithFeedback,13,0 block_count,Equal_WithFeedback,14,0 block_count,Equal_WithFeedback,15,0 block_count,Equal_WithFeedback,16,0 @@ -34394,13 +34397,13 @@ block_count,Equal_WithFeedback,89,0 block_count,Equal_WithFeedback,90,0 block_count,Equal_WithFeedback,91,0 -block_count,Equal_WithFeedback,92,1 +block_count,Equal_WithFeedback,92,0 block_count,Equal_WithFeedback,93,0 -block_count,Equal_WithFeedback,94,1 -block_count,Equal_WithFeedback,95,1 +block_count,Equal_WithFeedback,94,0 +block_count,Equal_WithFeedback,95,0 block_count,Equal_WithFeedback,96,0 block_count,Equal_WithFeedback,97,1 -block_count,Equal_WithFeedback,98,1 +block_count,Equal_WithFeedback,98,0 block_count,Equal_WithFeedback,99,0 block_count,Equal_WithFeedback,100,0 block_count,Equal_WithFeedback,101,0 @@ -34444,7 +34447,7 @@ block_count,Equal_WithFeedback,139,0 block_count,Equal_WithFeedback,140,0 block_count,Equal_WithFeedback,141,0 -block_count,Equal_WithFeedback,142,4 +block_count,Equal_WithFeedback,142,2 block_count,Equal_WithFeedback,143,0 block_count,Equal_WithFeedback,144,0 block_count,Equal_WithFeedback,145,0 @@ -34481,10 +34484,10 @@ block_count,Equal_WithFeedback,176,0 block_count,Equal_WithFeedback,177,0 block_count,Equal_WithFeedback,178,3 -block_count,Equal_WithFeedback,179,7 -block_count,Equal_WithFeedback,180,11 +block_count,Equal_WithFeedback,179,6 +block_count,Equal_WithFeedback,180,10 block_count,Equal_WithFeedback,181,0 -block_count,Equal_WithFeedback,182,11 +block_count,Equal_WithFeedback,182,10 block_count,StrictEqual_WithFeedback,0,120 block_count,StrictEqual_WithFeedback,1,106 block_count,StrictEqual_WithFeedback,2,96 @@ -34542,13 +34545,13 @@ block_count,StrictEqual_WithFeedback,54,0 block_count,StrictEqual_WithFeedback,55,75 block_count,StrictEqual_WithFeedback,56,0 -block_count,StrictEqual_WithFeedback,57,74 -block_count,StrictEqual_WithFeedback,58,13 -block_count,StrictEqual_WithFeedback,59,60 -block_count,StrictEqual_WithFeedback,60,74 +block_count,StrictEqual_WithFeedback,57,75 +block_count,StrictEqual_WithFeedback,58,14 +block_count,StrictEqual_WithFeedback,59,61 +block_count,StrictEqual_WithFeedback,60,75 block_count,StrictEqual_WithFeedback,61,0 block_count,StrictEqual_WithFeedback,62,74 -block_count,StrictEqual_WithFeedback,63,74 +block_count,StrictEqual_WithFeedback,63,75 block_count,StrictEqual_WithFeedback,64,62 block_count,StrictEqual_WithFeedback,65,12 block_count,StrictEqual_WithFeedback,66,2 @@ -35098,8 +35101,8 @@ block_count,Decrement_Baseline,23,16 block_count,Decrement_Baseline,24,0 block_count,Decrement_Baseline,25,16 -block_count,Increment_Baseline,0,109 -block_count,Increment_Baseline,1,109 +block_count,Increment_Baseline,0,103 +block_count,Increment_Baseline,1,103 block_count,Increment_Baseline,2,0 block_count,Increment_Baseline,3,0 block_count,Increment_Baseline,4,0 @@ -35114,16 +35117,16 @@ block_count,Increment_Baseline,13,0 block_count,Increment_Baseline,14,0 block_count,Increment_Baseline,15,0 -block_count,Increment_Baseline,16,109 -block_count,Increment_Baseline,17,109 +block_count,Increment_Baseline,16,103 +block_count,Increment_Baseline,17,103 block_count,Increment_Baseline,18,0 block_count,Increment_Baseline,19,0 block_count,Increment_Baseline,20,0 block_count,Increment_Baseline,21,0 block_count,Increment_Baseline,22,0 -block_count,Increment_Baseline,23,109 +block_count,Increment_Baseline,23,103 block_count,Increment_Baseline,24,0 -block_count,Increment_Baseline,25,109 +block_count,Increment_Baseline,25,103 block_count,Negate_Baseline,0,3 block_count,Negate_Baseline,1,3 block_count,Negate_Baseline,2,2 @@ -36132,7 +36135,7 @@ block_count,ObjectPrototypeHasOwnProperty,71,146 block_count,ObjectPrototypeHasOwnProperty,72,0 block_count,ObjectPrototypeHasOwnProperty,73,146 -block_count,ObjectPrototypeHasOwnProperty,74,166 +block_count,ObjectPrototypeHasOwnProperty,74,165 block_count,ObjectPrototypeHasOwnProperty,75,117 block_count,ObjectPrototypeHasOwnProperty,76,68 block_count,ObjectPrototypeHasOwnProperty,77,19 @@ -36336,7 +36339,7 @@ block_count,OrdinaryHasInstance,11,3 block_count,OrdinaryHasInstance,12,3 block_count,OrdinaryHasInstance,13,0 -block_count,OrdinaryHasInstance,14,108 +block_count,OrdinaryHasInstance,14,107 block_count,OrdinaryHasInstance,15,111 block_count,OrdinaryHasInstance,16,355 block_count,OrdinaryHasInstance,17,313 @@ -37625,7 +37628,7 @@ block_count,SetPrototypeAdd,29,70 block_count,SetPrototypeAdd,30,100 block_count,SetPrototypeAdd,31,31 -block_count,SetPrototypeAdd,32,30 +block_count,SetPrototypeAdd,32,29 block_count,SetPrototypeAdd,33,1 block_count,SetPrototypeAdd,34,68 block_count,SetPrototypeAdd,35,0 @@ -38363,16 +38366,16 @@ block_count,TypedArrayPrototypeByteLength,10,0 block_count,TypedArrayPrototypeByteLength,11,0 block_count,TypedArrayPrototypeByteLength,12,0 -block_count,TypedArrayPrototypeLength,0,38 +block_count,TypedArrayPrototypeLength,0,36 block_count,TypedArrayPrototypeLength,1,0 -block_count,TypedArrayPrototypeLength,2,38 -block_count,TypedArrayPrototypeLength,3,38 -block_count,TypedArrayPrototypeLength,4,38 +block_count,TypedArrayPrototypeLength,2,36 +block_count,TypedArrayPrototypeLength,3,36 +block_count,TypedArrayPrototypeLength,4,36 block_count,TypedArrayPrototypeLength,5,0 -block_count,TypedArrayPrototypeLength,6,38 -block_count,TypedArrayPrototypeLength,7,38 -block_count,TypedArrayPrototypeLength,8,38 -block_count,TypedArrayPrototypeLength,9,38 +block_count,TypedArrayPrototypeLength,6,36 +block_count,TypedArrayPrototypeLength,7,36 +block_count,TypedArrayPrototypeLength,8,36 +block_count,TypedArrayPrototypeLength,9,36 block_count,TypedArrayPrototypeLength,10,0 block_count,TypedArrayPrototypeLength,11,0 block_count,TypedArrayPrototypeLength,12,0 @@ -38408,8 +38411,8 @@ block_count,TypedArrayPrototypeLength,42,0 block_count,TypedArrayPrototypeLength,43,0 block_count,TypedArrayPrototypeLength,44,0 -block_count,TypedArrayPrototypeLength,45,38 -block_count,TypedArrayPrototypeLength,46,38 +block_count,TypedArrayPrototypeLength,45,36 +block_count,TypedArrayPrototypeLength,46,36 block_count,TypedArrayPrototypeToStringTag,0,0 block_count,TypedArrayPrototypeToStringTag,1,0 block_count,TypedArrayPrototypeToStringTag,2,0 @@ -39156,9 +39159,9 @@ block_count,WeakMapLookupHashIndex,30,0 block_count,WeakMapLookupHashIndex,31,73 block_count,WeakMapLookupHashIndex,32,73 -block_count,WeakMapLookupHashIndex,33,106 -block_count,WeakMapLookupHashIndex,34,106 -block_count,WeakMapLookupHashIndex,35,33 +block_count,WeakMapLookupHashIndex,33,112 +block_count,WeakMapLookupHashIndex,34,112 +block_count,WeakMapLookupHashIndex,35,39 block_count,WeakMapLookupHashIndex,36,72 block_count,WeakMapLookupHashIndex,37,0 block_count,WeakMapGet,0,37 @@ -39693,22 +39696,22 @@ block_count,AsyncGeneratorYieldWithAwaitResolveClosure,3,8 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,4,0 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,5,8 -block_count,StringAdd_CheckNone,0,8563 -block_count,StringAdd_CheckNone,1,8146 +block_count,StringAdd_CheckNone,0,8562 +block_count,StringAdd_CheckNone,1,8145 block_count,StringAdd_CheckNone,2,8098 block_count,StringAdd_CheckNone,3,8098 block_count,StringAdd_CheckNone,4,6391 -block_count,StringAdd_CheckNone,5,6363 +block_count,StringAdd_CheckNone,5,6362 block_count,StringAdd_CheckNone,6,28 block_count,StringAdd_CheckNone,7,6391 -block_count,StringAdd_CheckNone,8,6391 +block_count,StringAdd_CheckNone,8,6390 block_count,StringAdd_CheckNone,9,0 block_count,StringAdd_CheckNone,10,6391 block_count,StringAdd_CheckNone,11,2 -block_count,StringAdd_CheckNone,12,6389 +block_count,StringAdd_CheckNone,12,6388 block_count,StringAdd_CheckNone,13,6391 block_count,StringAdd_CheckNone,14,0 -block_count,StringAdd_CheckNone,15,6391 +block_count,StringAdd_CheckNone,15,6390 block_count,StringAdd_CheckNone,16,6391 block_count,StringAdd_CheckNone,17,1706 block_count,StringAdd_CheckNone,18,1708 @@ -39737,37 +39740,37 @@ block_count,StringAdd_CheckNone,41,0 block_count,StringAdd_CheckNone,42,0 block_count,StringAdd_CheckNone,43,1 -block_count,StringAdd_CheckNone,44,1706 -block_count,StringAdd_CheckNone,45,1697 -block_count,StringAdd_CheckNone,46,1697 +block_count,StringAdd_CheckNone,44,1705 +block_count,StringAdd_CheckNone,45,1696 +block_count,StringAdd_CheckNone,46,1696 block_count,StringAdd_CheckNone,47,1696 block_count,StringAdd_CheckNone,48,0 block_count,StringAdd_CheckNone,49,1696 block_count,StringAdd_CheckNone,50,0 block_count,StringAdd_CheckNone,51,0 -block_count,StringAdd_CheckNone,52,1697 +block_count,StringAdd_CheckNone,52,1696 block_count,StringAdd_CheckNone,53,0 -block_count,StringAdd_CheckNone,54,1697 +block_count,StringAdd_CheckNone,54,1696 block_count,StringAdd_CheckNone,55,829 block_count,StringAdd_CheckNone,56,867 block_count,StringAdd_CheckNone,57,2001 block_count,StringAdd_CheckNone,58,1134 block_count,StringAdd_CheckNone,59,867 -block_count,StringAdd_CheckNone,60,1697 +block_count,StringAdd_CheckNone,60,1696 block_count,StringAdd_CheckNone,61,358 block_count,StringAdd_CheckNone,62,1338 -block_count,StringAdd_CheckNone,63,1697 +block_count,StringAdd_CheckNone,63,1696 block_count,StringAdd_CheckNone,64,0 -block_count,StringAdd_CheckNone,65,1697 +block_count,StringAdd_CheckNone,65,1696 block_count,StringAdd_CheckNone,66,1014 -block_count,StringAdd_CheckNone,67,682 +block_count,StringAdd_CheckNone,67,681 block_count,StringAdd_CheckNone,68,1304 block_count,StringAdd_CheckNone,69,622 -block_count,StringAdd_CheckNone,70,682 -block_count,StringAdd_CheckNone,71,1697 +block_count,StringAdd_CheckNone,70,681 +block_count,StringAdd_CheckNone,71,1696 block_count,StringAdd_CheckNone,72,361 -block_count,StringAdd_CheckNone,73,1335 -block_count,StringAdd_CheckNone,74,1697 +block_count,StringAdd_CheckNone,73,1334 +block_count,StringAdd_CheckNone,74,1696 block_count,StringAdd_CheckNone,75,0 block_count,StringAdd_CheckNone,76,9 block_count,StringAdd_CheckNone,77,9 @@ -40000,15 +40003,15 @@ block_count,SubString,190,0 block_count,SubString,191,268 block_count,SubString,192,403 -block_count,SubString,193,134 -block_count,SubString,194,134 +block_count,SubString,193,135 +block_count,SubString,194,135 block_count,SubString,195,133 block_count,SubString,196,0 block_count,SubString,197,132 block_count,SubString,198,1 block_count,SubString,199,1 block_count,SubString,200,0 -block_count,SubString,201,134 +block_count,SubString,201,135 block_count,SubString,202,0 block_count,SubString,203,0 block_count,SubString,204,0 @@ -40211,7 +40214,7 @@ block_count,GetProperty,173,0 block_count,GetProperty,174,0 block_count,GetProperty,175,1064 -block_count,GetProperty,176,1055 +block_count,GetProperty,176,1054 block_count,GetProperty,177,9 block_count,GetProperty,178,697 block_count,GetProperty,179,2 @@ -45381,13 +45384,13 @@ block_count,ArrayMap,66,0 block_count,ArrayMap,67,17 block_count,ArrayMap,68,14 -block_count,ArrayMap,69,3 +block_count,ArrayMap,69,2 block_count,ArrayMap,70,12 block_count,ArrayMap,71,9 -block_count,ArrayMap,72,3 +block_count,ArrayMap,72,2 block_count,ArrayMap,73,17 block_count,ArrayMap,74,2 -block_count,ArrayMap,75,14 +block_count,ArrayMap,75,15 block_count,ArrayMap,76,17 block_count,ArrayMap,77,0 block_count,ArrayMap,78,26 @@ -45425,8 +45428,8 @@ block_count,ArrayMap,110,0 block_count,ArrayMap,111,0 block_count,ArrayMap,112,39 -block_count,ArrayMap,113,18 -block_count,ArrayMap,114,18 +block_count,ArrayMap,113,19 +block_count,ArrayMap,114,19 block_count,ArrayMap,115,0 block_count,ArrayMap,116,20 block_count,ArrayMap,117,0 @@ -45537,10 +45540,10 @@ block_count,ArrayMap,222,26 block_count,ArrayMap,223,0 block_count,ArrayMap,224,26 -block_count,ArrayMap,225,25 +block_count,ArrayMap,225,26 block_count,ArrayMap,226,0 -block_count,ArrayMap,227,25 -block_count,ArrayMap,228,25 +block_count,ArrayMap,227,26 +block_count,ArrayMap,228,26 block_count,ArrayMap,229,0 block_count,ArrayMap,230,0 block_count,ArrayMap,231,0 @@ -46097,9 +46100,9 @@ block_count,ArrayPrototypeSlice,134,3 block_count,ArrayPrototypeSlice,135,23 block_count,ArrayPrototypeSlice,136,18 -block_count,ArrayPrototypeSlice,137,4 -block_count,ArrayPrototypeSlice,138,4 -block_count,ArrayPrototypeSlice,139,4 +block_count,ArrayPrototypeSlice,137,5 +block_count,ArrayPrototypeSlice,138,5 +block_count,ArrayPrototypeSlice,139,5 block_count,ArrayPrototypeSlice,140,3 block_count,ArrayPrototypeSlice,141,3 block_count,ArrayPrototypeSlice,142,0 @@ -47788,7 +47791,7 @@ block_count,StringPrototypeCharAt,38,125 block_count,StringPrototypeCharAt,39,125 block_count,StringPrototypeCharAt,40,15 -block_count,StringPrototypeCharAt,41,110 +block_count,StringPrototypeCharAt,41,109 block_count,StringPrototypeCharAt,42,125 block_count,StringPrototypeCharAt,43,0 block_count,StringPrototypeCharAt,44,0 @@ -47796,32 +47799,32 @@ block_count,StringPrototypeCharAt,46,0 block_count,StringPrototypeCharAt,47,125 block_count,StringPrototypeCharAt,48,2 -block_count,StringPrototypeCharCodeAt,0,69 +block_count,StringPrototypeCharCodeAt,0,68 block_count,StringPrototypeCharCodeAt,1,0 -block_count,StringPrototypeCharCodeAt,2,69 -block_count,StringPrototypeCharCodeAt,3,69 -block_count,StringPrototypeCharCodeAt,4,69 +block_count,StringPrototypeCharCodeAt,2,68 +block_count,StringPrototypeCharCodeAt,3,68 +block_count,StringPrototypeCharCodeAt,4,68 block_count,StringPrototypeCharCodeAt,5,0 block_count,StringPrototypeCharCodeAt,6,0 block_count,StringPrototypeCharCodeAt,7,0 -block_count,StringPrototypeCharCodeAt,8,69 +block_count,StringPrototypeCharCodeAt,8,68 block_count,StringPrototypeCharCodeAt,9,0 -block_count,StringPrototypeCharCodeAt,10,69 -block_count,StringPrototypeCharCodeAt,11,69 +block_count,StringPrototypeCharCodeAt,10,68 +block_count,StringPrototypeCharCodeAt,11,68 block_count,StringPrototypeCharCodeAt,12,0 -block_count,StringPrototypeCharCodeAt,13,69 -block_count,StringPrototypeCharCodeAt,14,69 -block_count,StringPrototypeCharCodeAt,15,69 -block_count,StringPrototypeCharCodeAt,16,78 -block_count,StringPrototypeCharCodeAt,17,9 -block_count,StringPrototypeCharCodeAt,18,9 +block_count,StringPrototypeCharCodeAt,13,68 +block_count,StringPrototypeCharCodeAt,14,68 +block_count,StringPrototypeCharCodeAt,15,68 +block_count,StringPrototypeCharCodeAt,16,76 +block_count,StringPrototypeCharCodeAt,17,8 +block_count,StringPrototypeCharCodeAt,18,8 block_count,StringPrototypeCharCodeAt,19,0 block_count,StringPrototypeCharCodeAt,20,0 block_count,StringPrototypeCharCodeAt,21,0 -block_count,StringPrototypeCharCodeAt,22,9 -block_count,StringPrototypeCharCodeAt,23,9 +block_count,StringPrototypeCharCodeAt,22,8 +block_count,StringPrototypeCharCodeAt,23,8 block_count,StringPrototypeCharCodeAt,24,0 -block_count,StringPrototypeCharCodeAt,25,9 +block_count,StringPrototypeCharCodeAt,25,8 block_count,StringPrototypeCharCodeAt,26,0 block_count,StringPrototypeCharCodeAt,27,0 block_count,StringPrototypeCharCodeAt,28,0 @@ -47834,10 +47837,10 @@ block_count,StringPrototypeCharCodeAt,35,0 block_count,StringPrototypeCharCodeAt,36,0 block_count,StringPrototypeCharCodeAt,37,0 -block_count,StringPrototypeCharCodeAt,38,69 -block_count,StringPrototypeCharCodeAt,39,69 +block_count,StringPrototypeCharCodeAt,38,68 +block_count,StringPrototypeCharCodeAt,39,68 block_count,StringPrototypeCharCodeAt,40,8 -block_count,StringPrototypeCharCodeAt,41,60 +block_count,StringPrototypeCharCodeAt,41,59 block_count,StringPrototypeCharCodeAt,42,0 block_count,StringPrototypeCodePointAt,0,0 block_count,StringPrototypeCodePointAt,1,0 @@ -48423,7 +48426,7 @@ block_count,StringCharAt,30,0 block_count,StringCharAt,31,0 block_count,StringCharAt,32,9 -block_count,FastNewClosureBaseline,0,32 +block_count,FastNewClosureBaseline,0,31 block_count,FastNewFunctionContextFunction,0,61 block_count,FastNewFunctionContextFunction,1,61 block_count,FastNewFunctionContextFunction,2,0 @@ -48443,15 +48446,15 @@ block_count,FastNewFunctionContextFunction,16,61 block_count,FastNewFunctionContextFunction,17,46 block_count,FastNewFunctionContextFunction,18,15 -block_count,CreateRegExpLiteral,0,13 -block_count,CreateRegExpLiteral,1,13 +block_count,CreateRegExpLiteral,0,12 +block_count,CreateRegExpLiteral,1,12 block_count,CreateRegExpLiteral,2,0 -block_count,CreateRegExpLiteral,3,13 +block_count,CreateRegExpLiteral,3,12 block_count,CreateRegExpLiteral,4,0 -block_count,CreateRegExpLiteral,5,13 -block_count,CreateRegExpLiteral,6,13 +block_count,CreateRegExpLiteral,5,12 +block_count,CreateRegExpLiteral,6,12 block_count,CreateRegExpLiteral,7,0 -block_count,CreateRegExpLiteral,8,13 +block_count,CreateRegExpLiteral,8,12 block_count,CreateRegExpLiteral,9,0 block_count,CreateRegExpLiteral,10,0 block_count,CreateShallowArrayLiteral,0,9 @@ -48925,11 +48928,11 @@ block_count,ToBoolean,16,0 block_count,ToBoolean,17,0 block_count,ToBoolean,18,0 -block_count,ToBooleanForBaselineJump,0,411 -block_count,ToBooleanForBaselineJump,1,382 -block_count,ToBooleanForBaselineJump,2,153 -block_count,ToBooleanForBaselineJump,3,67 -block_count,ToBooleanForBaselineJump,4,67 +block_count,ToBooleanForBaselineJump,0,405 +block_count,ToBooleanForBaselineJump,1,376 +block_count,ToBooleanForBaselineJump,2,152 +block_count,ToBooleanForBaselineJump,3,66 +block_count,ToBooleanForBaselineJump,4,66 block_count,ToBooleanForBaselineJump,5,66 block_count,ToBooleanForBaselineJump,6,66 block_count,ToBooleanForBaselineJump,7,0 @@ -48939,8 +48942,8 @@ block_count,ToBooleanForBaselineJump,11,0 block_count,ToBooleanForBaselineJump,12,0 block_count,ToBooleanForBaselineJump,13,0 -block_count,ToBooleanForBaselineJump,14,85 -block_count,ToBooleanForBaselineJump,15,229 +block_count,ToBooleanForBaselineJump,14,86 +block_count,ToBooleanForBaselineJump,15,223 block_count,ToBooleanForBaselineJump,16,29 block_count,ToBooleanForBaselineJump,17,17 block_count,ToBooleanForBaselineJump,18,11 @@ -49714,7 +49717,7 @@ block_count,FunctionPrototypeHasInstance,17,44 block_count,FunctionPrototypeHasInstance,18,46 block_count,FunctionPrototypeHasInstance,19,146 -block_count,FunctionPrototypeHasInstance,20,143 +block_count,FunctionPrototypeHasInstance,20,144 block_count,FunctionPrototypeHasInstance,21,2 block_count,FunctionPrototypeHasInstance,22,2 block_count,FunctionPrototypeHasInstance,23,2 @@ -50338,20 +50341,20 @@ block_count,MathSign,13,0 block_count,MathSign,14,0 block_count,MathSign,15,0 -block_count,MathSqrt,0,9 +block_count,MathSqrt,0,10 block_count,MathSqrt,1,0 -block_count,MathSqrt,2,9 -block_count,MathSqrt,3,9 -block_count,MathSqrt,4,6 -block_count,MathSqrt,5,6 +block_count,MathSqrt,2,10 +block_count,MathSqrt,3,10 +block_count,MathSqrt,4,7 +block_count,MathSqrt,5,7 block_count,MathSqrt,6,0 -block_count,MathSqrt,7,6 +block_count,MathSqrt,7,7 block_count,MathSqrt,8,2 -block_count,MathSqrt,9,9 -block_count,MathSqrt,10,6 +block_count,MathSqrt,9,10 +block_count,MathSqrt,10,7 block_count,MathSqrt,11,2 -block_count,MathSqrt,12,9 -block_count,MathSqrt,13,6 +block_count,MathSqrt,12,10 +block_count,MathSqrt,13,7 block_count,MathSqrt,14,2 block_count,MathSqrt,15,2 block_count,MathSqrt,16,0 @@ -50360,10 +50363,10 @@ block_count,MathSqrt,19,2 block_count,MathSqrt,20,2 block_count,MathSqrt,21,0 -block_count,MathSqrt,22,6 +block_count,MathSqrt,22,7 block_count,MathSqrt,23,0 -block_count,MathSqrt,24,6 -block_count,MathSqrt,25,6 +block_count,MathSqrt,24,7 +block_count,MathSqrt,25,7 block_count,MathTan,0,0 block_count,MathTan,1,0 block_count,MathTan,2,0 @@ -50711,7 +50714,7 @@ block_count,Add,19,0 block_count,Add,20,0 block_count,Add,21,0 -block_count,Add,22,48 +block_count,Add,22,47 block_count,Add,23,0 block_count,Add,24,0 block_count,Add,25,0 @@ -50730,8 +50733,8 @@ block_count,Add,38,0 block_count,Add,39,0 block_count,Add,40,0 -block_count,Add,41,48 -block_count,Add,42,48 +block_count,Add,41,47 +block_count,Add,42,47 block_count,Add,43,1 block_count,Add,44,1 block_count,Add,45,1 @@ -50982,10 +50985,10 @@ block_count,BitwiseOr,32,0 block_count,BitwiseOr,33,0 block_count,BitwiseOr,34,4 -block_count,LessThan,0,761 -block_count,LessThan,1,1280 -block_count,LessThan,2,1247 -block_count,LessThan,3,1247 +block_count,LessThan,0,758 +block_count,LessThan,1,1277 +block_count,LessThan,2,1244 +block_count,LessThan,3,1244 block_count,LessThan,4,10 block_count,LessThan,5,10 block_count,LessThan,6,3 @@ -51032,34 +51035,34 @@ block_count,LessThan,47,0 block_count,LessThan,48,0 block_count,LessThan,49,0 -block_count,LessThan,50,1236 +block_count,LessThan,50,1234 block_count,LessThan,51,512 block_count,LessThan,52,512 block_count,LessThan,53,0 -block_count,LessThan,54,724 +block_count,LessThan,54,722 block_count,LessThan,55,0 block_count,LessThan,56,0 block_count,LessThan,57,0 block_count,LessThan,58,0 block_count,LessThan,59,0 -block_count,LessThan,60,33 -block_count,LessThan,61,33 +block_count,LessThan,60,32 +block_count,LessThan,61,32 block_count,LessThan,62,0 block_count,LessThan,63,0 block_count,LessThan,64,0 -block_count,LessThan,65,33 +block_count,LessThan,65,32 block_count,LessThan,66,0 block_count,LessThan,67,0 block_count,LessThan,68,0 block_count,LessThan,69,519 -block_count,LessThan,70,757 -block_count,LessThan,71,624 +block_count,LessThan,70,754 +block_count,LessThan,71,622 block_count,LessThan,72,132 -block_count,LessThan,73,624 +block_count,LessThan,73,622 block_count,LessThan,74,132 block_count,GreaterThan,0,659 block_count,GreaterThan,1,1144 -block_count,GreaterThan,2,1126 +block_count,GreaterThan,2,1125 block_count,GreaterThan,3,1023 block_count,GreaterThan,4,16 block_count,GreaterThan,5,16 @@ -51202,18 +51205,18 @@ block_count,GreaterThanOrEqual,67,0 block_count,GreaterThanOrEqual,68,0 block_count,GreaterThanOrEqual,69,6 -block_count,Equal,0,49 -block_count,Equal,1,141 -block_count,Equal,2,139 -block_count,Equal,3,79 -block_count,Equal,4,59 -block_count,Equal,5,38 +block_count,Equal,0,50 +block_count,Equal,1,143 +block_count,Equal,2,141 +block_count,Equal,3,80 +block_count,Equal,4,60 +block_count,Equal,5,39 block_count,Equal,6,26 block_count,Equal,7,20 block_count,Equal,8,20 block_count,Equal,9,20 -block_count,Equal,10,17 -block_count,Equal,11,17 +block_count,Equal,10,18 +block_count,Equal,11,18 block_count,Equal,12,0 block_count,Equal,13,0 block_count,Equal,14,0 @@ -51279,8 +51282,8 @@ block_count,Equal,74,12 block_count,Equal,75,0 block_count,Equal,76,12 -block_count,Equal,77,20 -block_count,Equal,78,17 +block_count,Equal,77,21 +block_count,Equal,78,18 block_count,Equal,79,3 block_count,Equal,80,3 block_count,Equal,81,0 @@ -51303,7 +51306,7 @@ block_count,Equal,98,27 block_count,Equal,99,0 block_count,Equal,100,30 -block_count,Equal,101,92 +block_count,Equal,101,93 block_count,Equal,102,29 block_count,Equal,103,29 block_count,Equal,104,0 @@ -51353,7 +51356,7 @@ block_count,StrictEqual,34,0 block_count,StrictEqual,35,0 block_count,StrictEqual,36,0 -block_count,StrictEqual,37,974 +block_count,StrictEqual,37,973 block_count,StrictEqual,38,49 block_count,StrictEqual,39,924 block_count,StrictEqual,40,514 @@ -52924,7 +52927,7 @@ block_count,RegExpPrototypeExec,141,0 block_count,RegExpPrototypeExec,142,0 block_count,RegExpPrototypeExec,143,0 -block_count,RegExpPrototypeExec,144,0 +block_count,RegExpPrototypeExec,144,1 block_count,RegExpPrototypeExec,145,0 block_count,RegExpPrototypeExec,146,0 block_count,RegExpPrototypeExec,147,0 @@ -52943,7 +52946,7 @@ block_count,RegExpPrototypeExec,160,0 block_count,RegExpPrototypeExec,161,0 block_count,RegExpPrototypeExec,162,0 -block_count,RegExpPrototypeExec,163,0 +block_count,RegExpPrototypeExec,163,1 block_count,RegExpPrototypeExec,164,0 block_count,RegExpPrototypeExec,165,26 block_count,RegExpPrototypeExec,166,26 @@ -54440,7 +54443,7 @@ block_count,RegExpReplace,332,193 block_count,RegExpReplace,333,143 block_count,RegExpReplace,334,143 -block_count,RegExpReplace,335,147 +block_count,RegExpReplace,335,146 block_count,RegExpReplace,336,3 block_count,RegExpReplace,337,3 block_count,RegExpReplace,338,1 @@ -55467,7 +55470,7 @@ block_count,RegExpPrototypeTest,5,114 block_count,RegExpPrototypeTest,6,114 block_count,RegExpPrototypeTest,7,38 -block_count,RegExpPrototypeTest,8,75 +block_count,RegExpPrototypeTest,8,76 block_count,RegExpPrototypeTest,9,0 block_count,RegExpPrototypeTest,10,38 block_count,RegExpPrototypeTest,11,114 @@ -55550,8 +55553,8 @@ block_count,RegExpPrototypeTest,88,0 block_count,RegExpPrototypeTest,89,17 block_count,RegExpPrototypeTest,90,0 -block_count,RegExpPrototypeTest,91,75 -block_count,RegExpPrototypeTest,92,75 +block_count,RegExpPrototypeTest,91,76 +block_count,RegExpPrototypeTest,92,76 block_count,RegExpPrototypeTest,93,114 block_count,RegExpPrototypeTest,94,0 block_count,RegExpPrototypeTest,95,113 @@ -55568,8 +55571,8 @@ block_count,RegExpPrototypeTest,106,0 block_count,RegExpPrototypeTest,107,0 block_count,RegExpPrototypeTest,108,0 -block_count,RegExpPrototypeTest,109,112 -block_count,RegExpPrototypeTest,110,112 +block_count,RegExpPrototypeTest,109,113 +block_count,RegExpPrototypeTest,110,113 block_count,RegExpPrototypeTest,111,0 block_count,RegExpPrototypeTest,112,113 block_count,RegExpPrototypeTest,113,0 @@ -55618,18 +55621,18 @@ block_count,RegExpPrototypeTest,156,99 block_count,RegExpPrototypeTest,157,0 block_count,RegExpPrototypeTest,158,99 -block_count,RegExpPrototypeTestFast,0,427 -block_count,RegExpPrototypeTestFast,1,427 +block_count,RegExpPrototypeTestFast,0,426 +block_count,RegExpPrototypeTestFast,1,426 block_count,RegExpPrototypeTestFast,2,422 block_count,RegExpPrototypeTestFast,3,4 -block_count,RegExpPrototypeTestFast,4,427 -block_count,RegExpPrototypeTestFast,5,427 -block_count,RegExpPrototypeTestFast,6,427 +block_count,RegExpPrototypeTestFast,4,426 +block_count,RegExpPrototypeTestFast,5,426 +block_count,RegExpPrototypeTestFast,6,426 block_count,RegExpPrototypeTestFast,7,0 block_count,RegExpPrototypeTestFast,8,0 block_count,RegExpPrototypeTestFast,9,0 -block_count,RegExpPrototypeTestFast,10,427 -block_count,RegExpPrototypeTestFast,11,547 +block_count,RegExpPrototypeTestFast,10,426 +block_count,RegExpPrototypeTestFast,11,546 block_count,RegExpPrototypeTestFast,12,120 block_count,RegExpPrototypeTestFast,13,120 block_count,RegExpPrototypeTestFast,14,120 @@ -55656,9 +55659,9 @@ block_count,RegExpPrototypeTestFast,35,0 block_count,RegExpPrototypeTestFast,36,120 block_count,RegExpPrototypeTestFast,37,0 -block_count,RegExpPrototypeTestFast,38,427 -block_count,RegExpPrototypeTestFast,39,427 -block_count,RegExpPrototypeTestFast,40,427 +block_count,RegExpPrototypeTestFast,38,426 +block_count,RegExpPrototypeTestFast,39,426 +block_count,RegExpPrototypeTestFast,40,426 block_count,RegExpPrototypeTestFast,41,0 block_count,RegExpPrototypeTestFast,42,422 block_count,RegExpPrototypeTestFast,43,4 @@ -55696,7 +55699,7 @@ block_count,RegExpPrototypeTestFast,75,0 block_count,RegExpPrototypeTestFast,76,0 block_count,RegExpPrototypeTestFast,77,0 -block_count,RegExpPrototypeTestFast,78,427 +block_count,RegExpPrototypeTestFast,78,426 block_count,RegExpPrototypeTestFast,79,129 block_count,RegExpPrototypeTestFast,80,0 block_count,RegExpPrototypeTestFast,81,129 @@ -55710,7 +55713,7 @@ block_count,RegExpPrototypeTestFast,89,129 block_count,RegExpPrototypeTestFast,90,0 block_count,RegExpPrototypeTestFast,91,129 -block_count,RegExpPrototypeTestFast,92,1670 +block_count,RegExpPrototypeTestFast,92,1669 block_count,RegExpPrototypeTestFast,93,1540 block_count,RegExpPrototypeTestFast,94,129 block_count,RegExpPrototypeTestFast,95,129 @@ -56470,29 +56473,29 @@ block_count,StringPrototypeIncludes,73,0 block_count,StringPrototypeIncludes,74,0 block_count,StringPrototypeIncludes,75,0 -block_count,StringPrototypeIndexOf,0,13 +block_count,StringPrototypeIndexOf,0,12 block_count,StringPrototypeIndexOf,1,0 -block_count,StringPrototypeIndexOf,2,13 -block_count,StringPrototypeIndexOf,3,13 -block_count,StringPrototypeIndexOf,4,13 +block_count,StringPrototypeIndexOf,2,12 +block_count,StringPrototypeIndexOf,3,12 +block_count,StringPrototypeIndexOf,4,12 block_count,StringPrototypeIndexOf,5,0 -block_count,StringPrototypeIndexOf,6,13 +block_count,StringPrototypeIndexOf,6,12 block_count,StringPrototypeIndexOf,7,1 block_count,StringPrototypeIndexOf,8,11 -block_count,StringPrototypeIndexOf,9,13 -block_count,StringPrototypeIndexOf,10,13 +block_count,StringPrototypeIndexOf,9,12 +block_count,StringPrototypeIndexOf,10,12 block_count,StringPrototypeIndexOf,11,0 block_count,StringPrototypeIndexOf,12,0 block_count,StringPrototypeIndexOf,13,0 -block_count,StringPrototypeIndexOf,14,13 +block_count,StringPrototypeIndexOf,14,12 block_count,StringPrototypeIndexOf,15,0 -block_count,StringPrototypeIndexOf,16,13 -block_count,StringPrototypeIndexOf,17,13 +block_count,StringPrototypeIndexOf,16,12 +block_count,StringPrototypeIndexOf,17,12 block_count,StringPrototypeIndexOf,18,0 -block_count,StringPrototypeIndexOf,19,13 +block_count,StringPrototypeIndexOf,19,12 block_count,StringPrototypeIndexOf,20,0 block_count,StringPrototypeIndexOf,21,0 -block_count,StringPrototypeIndexOf,22,13 +block_count,StringPrototypeIndexOf,22,12 block_count,StringPrototypeIndexOf,23,11 block_count,StringPrototypeIndexOf,24,1 block_count,StringPrototypeIndexOf,25,1 @@ -57299,8 +57302,8 @@ block_count,StringPrototypeSubstr,56,1 block_count,StringPrototypeSubstr,57,2 block_count,StringPrototypeSubstr,58,2 -block_count,StringPrototypeSubstr,59,2 -block_count,StringPrototypeSubstr,60,2 +block_count,StringPrototypeSubstr,59,1 +block_count,StringPrototypeSubstr,60,1 block_count,StringPrototypeSubstr,61,1 block_count,StringPrototypeSubstr,62,2 block_count,StringPrototypeSubstr,63,0 @@ -60792,10 +60795,10 @@ block_count,StringIndexOf,7,0 block_count,StringIndexOf,8,367 block_count,StringIndexOf,9,182 -block_count,StringIndexOf,10,215 -block_count,StringIndexOf,11,52 -block_count,StringIndexOf,12,32 -block_count,StringIndexOf,13,31 +block_count,StringIndexOf,10,213 +block_count,StringIndexOf,11,50 +block_count,StringIndexOf,12,30 +block_count,StringIndexOf,13,29 block_count,StringIndexOf,14,1 block_count,StringIndexOf,15,0 block_count,StringIndexOf,16,0 @@ -60835,7 +60838,7 @@ block_count,StringIndexOf,50,0 block_count,StringIndexOf,51,0 block_count,StringIndexOf,52,1 -block_count,StringIndexOf,53,32 +block_count,StringIndexOf,53,30 block_count,StringIndexOf,54,19 block_count,StringIndexOf,55,19 block_count,StringIndexOf,56,19 @@ -61551,10 +61554,10 @@ block_count,ArrayTimSort,123,395 block_count,ArrayTimSort,124,0 block_count,ArrayTimSort,125,143 -block_count,ArrayTimSort,126,756 -block_count,ArrayTimSort,127,613 -block_count,ArrayTimSort,128,613 -block_count,ArrayTimSort,129,613 +block_count,ArrayTimSort,126,757 +block_count,ArrayTimSort,127,614 +block_count,ArrayTimSort,128,614 +block_count,ArrayTimSort,129,614 block_count,ArrayTimSort,130,0 block_count,ArrayTimSort,131,0 block_count,ArrayTimSort,132,143 @@ -62804,20 +62807,20 @@ block_count,StringToLowerCaseIntl,41,0 block_count,StringToLowerCaseIntl,42,0 block_count,WideHandler,0,62 -block_count,ExtraWideHandler,0,10 -block_count,LdarHandler,0,84 +block_count,ExtraWideHandler,0,11 +block_count,LdarHandler,0,86 block_count,LdaZeroHandler,0,11 -block_count,LdaZeroHandler,1,7 +block_count,LdaZeroHandler,1,8 block_count,LdaZeroHandler,2,3 block_count,LdaSmiHandler,0,12 -block_count,LdaSmiHandler,1,7 +block_count,LdaSmiHandler,1,8 block_count,LdaSmiHandler,2,4 -block_count,LdaUndefinedHandler,0,7 +block_count,LdaUndefinedHandler,0,8 block_count,LdaUndefinedHandler,1,7 block_count,LdaUndefinedHandler,2,0 block_count,LdaNullHandler,0,1 block_count,LdaNullHandler,1,0 -block_count,LdaNullHandler,2,0 +block_count,LdaNullHandler,2,1 block_count,LdaTheHoleHandler,0,0 block_count,LdaTheHoleHandler,1,0 block_count,LdaTheHoleHandler,2,0 @@ -62906,7 +62909,7 @@ block_count,LdaCurrentContextSlotHandler,0,5 block_count,LdaCurrentContextSlotHandler,1,0 block_count,LdaCurrentContextSlotHandler,2,5 -block_count,LdaCurrentContextSlotHandler,3,2 +block_count,LdaCurrentContextSlotHandler,3,3 block_count,LdaCurrentContextSlotHandler,4,2 block_count,LdaCurrentScriptContextSlotHandler,0,0 block_count,LdaCurrentScriptContextSlotHandler,1,0 @@ -62956,8 +62959,8 @@ block_count,LdaImmutableCurrentContextSlotHandler,2,20 block_count,LdaImmutableCurrentContextSlotHandler,3,4 block_count,LdaImmutableCurrentContextSlotHandler,4,15 -block_count,StarHandler,0,19 -block_count,MovHandler,0,18 +block_count,StarHandler,0,20 +block_count,MovHandler,0,19 block_count,PushContextHandler,0,2 block_count,PopContextHandler,0,0 block_count,TestReferenceEqualHandler,0,0 @@ -63030,13 +63033,13 @@ block_count,TestTypeOfHandler,48,0 block_count,TestTypeOfHandler,49,0 block_count,TestTypeOfHandler,50,0 -block_count,LdaGlobalHandler,0,23 -block_count,LdaGlobalHandler,1,13 +block_count,LdaGlobalHandler,0,24 +block_count,LdaGlobalHandler,1,14 block_count,LdaGlobalHandler,2,13 -block_count,LdaGlobalHandler,3,12 -block_count,LdaGlobalHandler,4,12 +block_count,LdaGlobalHandler,3,13 +block_count,LdaGlobalHandler,4,13 block_count,LdaGlobalHandler,5,4 -block_count,LdaGlobalHandler,6,8 +block_count,LdaGlobalHandler,6,9 block_count,LdaGlobalHandler,7,0 block_count,LdaGlobalHandler,8,0 block_count,LdaGlobalHandler,9,0 @@ -63291,13 +63294,13 @@ block_count,LdaGlobalHandler,258,0 block_count,LdaGlobalHandler,259,0 block_count,LdaGlobalHandler,260,0 -block_count,LdaGlobalHandler,261,0 +block_count,LdaGlobalHandler,261,1 block_count,LdaGlobalHandler,262,0 -block_count,LdaGlobalHandler,263,0 +block_count,LdaGlobalHandler,263,1 block_count,LdaGlobalHandler,264,0 -block_count,LdaGlobalHandler,265,0 +block_count,LdaGlobalHandler,265,1 block_count,LdaGlobalHandler,266,0 -block_count,LdaGlobalHandler,267,0 +block_count,LdaGlobalHandler,267,1 block_count,LdaGlobalHandler,268,9 block_count,LdaGlobalHandler,269,2 block_count,LdaGlobalHandler,270,7 @@ -64369,31 +64372,31 @@ block_count,StaLookupSlotHandler,3,0 block_count,StaLookupSlotHandler,4,0 block_count,StaLookupSlotHandler,5,0 -block_count,GetNamedPropertyHandler,0,73 -block_count,GetNamedPropertyHandler,1,45 -block_count,GetNamedPropertyHandler,2,45 +block_count,GetNamedPropertyHandler,0,76 +block_count,GetNamedPropertyHandler,1,49 +block_count,GetNamedPropertyHandler,2,48 block_count,GetNamedPropertyHandler,3,0 -block_count,GetNamedPropertyHandler,4,45 -block_count,GetNamedPropertyHandler,5,5 +block_count,GetNamedPropertyHandler,4,49 +block_count,GetNamedPropertyHandler,5,6 block_count,GetNamedPropertyHandler,6,0 -block_count,GetNamedPropertyHandler,7,5 -block_count,GetNamedPropertyHandler,8,2 +block_count,GetNamedPropertyHandler,7,6 +block_count,GetNamedPropertyHandler,8,3 block_count,GetNamedPropertyHandler,9,2 block_count,GetNamedPropertyHandler,10,5 block_count,GetNamedPropertyHandler,11,2 block_count,GetNamedPropertyHandler,12,2 block_count,GetNamedPropertyHandler,13,0 block_count,GetNamedPropertyHandler,14,2 -block_count,GetNamedPropertyHandler,15,39 -block_count,GetNamedPropertyHandler,16,42 -block_count,GetNamedPropertyHandler,17,14 -block_count,GetNamedPropertyHandler,18,14 -block_count,GetNamedPropertyHandler,19,13 -block_count,GetNamedPropertyHandler,20,13 +block_count,GetNamedPropertyHandler,15,42 +block_count,GetNamedPropertyHandler,16,45 +block_count,GetNamedPropertyHandler,17,15 +block_count,GetNamedPropertyHandler,18,15 +block_count,GetNamedPropertyHandler,19,14 +block_count,GetNamedPropertyHandler,20,14 block_count,GetNamedPropertyHandler,21,0 -block_count,GetNamedPropertyHandler,22,13 +block_count,GetNamedPropertyHandler,22,14 block_count,GetNamedPropertyHandler,23,0 -block_count,GetNamedPropertyHandler,24,13 +block_count,GetNamedPropertyHandler,24,14 block_count,GetNamedPropertyHandler,25,2 block_count,GetNamedPropertyHandler,26,0 block_count,GetNamedPropertyHandler,27,0 @@ -64467,25 +64470,25 @@ block_count,GetNamedPropertyHandler,95,0 block_count,GetNamedPropertyHandler,96,2 block_count,GetNamedPropertyHandler,97,0 -block_count,GetNamedPropertyHandler,98,10 -block_count,GetNamedPropertyHandler,99,13 -block_count,GetNamedPropertyHandler,100,13 -block_count,GetNamedPropertyHandler,101,12 -block_count,GetNamedPropertyHandler,102,12 +block_count,GetNamedPropertyHandler,98,11 +block_count,GetNamedPropertyHandler,99,14 +block_count,GetNamedPropertyHandler,100,14 +block_count,GetNamedPropertyHandler,101,13 +block_count,GetNamedPropertyHandler,102,13 block_count,GetNamedPropertyHandler,103,0 block_count,GetNamedPropertyHandler,104,0 -block_count,GetNamedPropertyHandler,105,13 +block_count,GetNamedPropertyHandler,105,14 block_count,GetNamedPropertyHandler,106,0 block_count,GetNamedPropertyHandler,107,1 block_count,GetNamedPropertyHandler,108,0 block_count,GetNamedPropertyHandler,109,0 block_count,GetNamedPropertyHandler,110,0 -block_count,GetNamedPropertyHandler,111,27 -block_count,GetNamedPropertyHandler,112,40 -block_count,GetNamedPropertyHandler,113,14 +block_count,GetNamedPropertyHandler,111,30 +block_count,GetNamedPropertyHandler,112,44 +block_count,GetNamedPropertyHandler,113,15 block_count,GetNamedPropertyHandler,114,3 block_count,GetNamedPropertyHandler,115,2 -block_count,GetNamedPropertyHandler,116,1 +block_count,GetNamedPropertyHandler,116,2 block_count,GetNamedPropertyHandler,117,0 block_count,GetNamedPropertyHandler,118,0 block_count,GetNamedPropertyHandler,119,0 @@ -64616,13 +64619,13 @@ block_count,GetNamedPropertyHandler,244,0 block_count,GetNamedPropertyHandler,245,0 block_count,GetNamedPropertyHandler,246,0 -block_count,GetNamedPropertyHandler,247,10 -block_count,GetNamedPropertyHandler,248,26 -block_count,GetNamedPropertyHandler,249,26 -block_count,GetNamedPropertyHandler,250,4 -block_count,GetNamedPropertyHandler,251,21 -block_count,GetNamedPropertyHandler,252,26 -block_count,GetNamedPropertyHandler,253,25 +block_count,GetNamedPropertyHandler,247,11 +block_count,GetNamedPropertyHandler,248,29 +block_count,GetNamedPropertyHandler,249,29 +block_count,GetNamedPropertyHandler,250,6 +block_count,GetNamedPropertyHandler,251,22 +block_count,GetNamedPropertyHandler,252,29 +block_count,GetNamedPropertyHandler,253,28 block_count,GetNamedPropertyHandler,254,1 block_count,GetNamedPropertyHandler,255,1 block_count,GetNamedPropertyHandler,256,1 @@ -64670,9 +64673,9 @@ block_count,GetNamedPropertyHandler,298,1 block_count,GetNamedPropertyHandler,299,0 block_count,GetNamedPropertyHandler,300,27 -block_count,GetNamedPropertyHandler,301,73 -block_count,GetNamedPropertyHandler,302,20 -block_count,GetNamedPropertyHandler,303,52 +block_count,GetNamedPropertyHandler,301,76 +block_count,GetNamedPropertyHandler,302,21 +block_count,GetNamedPropertyHandler,303,55 block_count,GetNamedPropertyFromSuperHandler,0,0 block_count,GetKeyedPropertyHandler,0,20 block_count,GetKeyedPropertyHandler,1,9 @@ -64680,7 +64683,7 @@ block_count,GetEnumeratedKeyedPropertyHandler,0,1 block_count,SetNamedPropertyHandler,0,10 block_count,DefineNamedOwnPropertyHandler,0,3 -block_count,SetKeyedPropertyHandler,0,11 +block_count,SetKeyedPropertyHandler,0,12 block_count,DefineKeyedOwnPropertyHandler,0,0 block_count,StaInArrayLiteralHandler,0,1 block_count,DefineKeyedOwnPropertyInLiteralHandler,0,0 @@ -64925,7 +64928,7 @@ block_count,SubHandler,110,1 block_count,SubHandler,111,0 block_count,SubHandler,112,0 -block_count,MulHandler,0,4 +block_count,MulHandler,0,5 block_count,MulHandler,1,1 block_count,MulHandler,2,1 block_count,MulHandler,3,1 @@ -65050,7 +65053,7 @@ block_count,MulHandler,122,0 block_count,MulHandler,123,4 block_count,MulHandler,124,4 -block_count,MulHandler,125,4 +block_count,MulHandler,125,5 block_count,MulHandler,126,3 block_count,MulHandler,127,1 block_count,DivHandler,0,0 @@ -65370,7 +65373,7 @@ block_count,ExpHandler,55,0 block_count,ExpHandler,56,0 block_count,ExpHandler,57,0 -block_count,BitwiseOrHandler,0,0 +block_count,BitwiseOrHandler,0,1 block_count,BitwiseOrHandler,1,0 block_count,BitwiseOrHandler,2,0 block_count,BitwiseOrHandler,3,0 @@ -65476,7 +65479,7 @@ block_count,BitwiseOrHandler,103,0 block_count,BitwiseOrHandler,104,0 block_count,BitwiseOrHandler,105,0 -block_count,BitwiseOrHandler,106,0 +block_count,BitwiseOrHandler,106,1 block_count,BitwiseOrHandler,107,0 block_count,BitwiseOrHandler,108,0 block_count,BitwiseOrHandler,109,0 @@ -65502,22 +65505,22 @@ block_count,BitwiseOrHandler,129,0 block_count,BitwiseOrHandler,130,0 block_count,BitwiseOrHandler,131,0 -block_count,BitwiseOrHandler,132,0 +block_count,BitwiseOrHandler,132,1 block_count,BitwiseOrHandler,133,0 block_count,BitwiseOrHandler,134,0 block_count,BitwiseOrHandler,135,0 block_count,BitwiseOrHandler,136,0 block_count,BitwiseOrHandler,137,0 -block_count,BitwiseOrHandler,138,0 +block_count,BitwiseOrHandler,138,1 block_count,BitwiseOrHandler,139,0 block_count,BitwiseOrHandler,140,0 -block_count,BitwiseOrHandler,141,0 +block_count,BitwiseOrHandler,141,1 block_count,BitwiseOrHandler,142,0 block_count,BitwiseOrHandler,143,0 block_count,BitwiseOrHandler,144,0 block_count,BitwiseOrHandler,145,0 -block_count,BitwiseOrHandler,146,0 -block_count,BitwiseOrHandler,147,0 +block_count,BitwiseOrHandler,146,1 +block_count,BitwiseOrHandler,147,1 block_count,BitwiseXorHandler,0,0 block_count,BitwiseXorHandler,1,0 block_count,BitwiseXorHandler,2,0 @@ -66131,7 +66134,7 @@ block_count,SubSmiHandler,5,0 block_count,SubSmiHandler,6,0 block_count,SubSmiHandler,7,1 -block_count,SubSmiHandler,8,0 +block_count,SubSmiHandler,8,1 block_count,SubSmiHandler,9,0 block_count,SubSmiHandler,10,0 block_count,SubSmiHandler,11,0 @@ -66601,15 +66604,15 @@ block_count,IncHandler,23,0 block_count,IncHandler,24,0 block_count,IncHandler,25,11 -block_count,IncHandler,26,10 +block_count,IncHandler,26,11 block_count,IncHandler,27,0 -block_count,IncHandler,28,10 +block_count,IncHandler,28,11 block_count,IncHandler,29,0 block_count,IncHandler,30,11 block_count,IncHandler,31,1 block_count,IncHandler,32,10 -block_count,DecHandler,0,2 -block_count,DecHandler,1,2 +block_count,DecHandler,0,3 +block_count,DecHandler,1,3 block_count,DecHandler,2,0 block_count,DecHandler,3,0 block_count,DecHandler,4,0 @@ -66626,21 +66629,21 @@ block_count,DecHandler,15,0 block_count,DecHandler,16,0 block_count,DecHandler,17,0 -block_count,DecHandler,18,2 -block_count,DecHandler,19,2 +block_count,DecHandler,18,3 +block_count,DecHandler,19,3 block_count,DecHandler,20,0 block_count,DecHandler,21,0 block_count,DecHandler,22,0 block_count,DecHandler,23,0 block_count,DecHandler,24,0 -block_count,DecHandler,25,2 -block_count,DecHandler,26,2 +block_count,DecHandler,25,3 +block_count,DecHandler,26,3 block_count,DecHandler,27,0 -block_count,DecHandler,28,2 +block_count,DecHandler,28,3 block_count,DecHandler,29,0 -block_count,DecHandler,30,2 -block_count,DecHandler,31,0 -block_count,DecHandler,32,1 +block_count,DecHandler,30,3 +block_count,DecHandler,31,1 +block_count,DecHandler,32,2 block_count,NegateHandler,0,0 block_count,NegateHandler,1,0 block_count,NegateHandler,2,0 @@ -66965,8 +66968,8 @@ block_count,CallPropertyHandler,66,1 block_count,CallPropertyHandler,67,0 block_count,CallPropertyHandler,68,2 -block_count,CallProperty0Handler,0,5 -block_count,CallProperty0Handler,1,3 +block_count,CallProperty0Handler,0,6 +block_count,CallProperty0Handler,1,4 block_count,CallProperty0Handler,2,0 block_count,CallProperty0Handler,3,0 block_count,CallProperty0Handler,4,0 @@ -67031,9 +67034,9 @@ block_count,CallProperty0Handler,63,0 block_count,CallProperty0Handler,64,0 block_count,CallProperty0Handler,65,0 -block_count,CallProperty0Handler,66,3 +block_count,CallProperty0Handler,66,4 block_count,CallProperty0Handler,67,1 -block_count,CallProperty0Handler,68,5 +block_count,CallProperty0Handler,68,6 block_count,CallProperty1Handler,0,12 block_count,CallProperty1Handler,1,8 block_count,CallProperty1Handler,2,0 @@ -67103,7 +67106,7 @@ block_count,CallProperty1Handler,66,8 block_count,CallProperty1Handler,67,4 block_count,CallProperty1Handler,68,12 -block_count,CallProperty2Handler,0,3 +block_count,CallProperty2Handler,0,4 block_count,CallProperty2Handler,1,2 block_count,CallProperty2Handler,2,0 block_count,CallProperty2Handler,3,0 @@ -67171,7 +67174,7 @@ block_count,CallProperty2Handler,65,0 block_count,CallProperty2Handler,66,1 block_count,CallProperty2Handler,67,1 -block_count,CallProperty2Handler,68,3 +block_count,CallProperty2Handler,68,4 block_count,CallUndefinedReceiverHandler,0,1 block_count,CallUndefinedReceiverHandler,1,0 block_count,CallUndefinedReceiverHandler,2,0 @@ -67241,7 +67244,7 @@ block_count,CallUndefinedReceiverHandler,66,0 block_count,CallUndefinedReceiverHandler,67,0 block_count,CallUndefinedReceiverHandler,68,1 -block_count,CallUndefinedReceiver0Handler,0,1 +block_count,CallUndefinedReceiver0Handler,0,2 block_count,CallUndefinedReceiver0Handler,1,1 block_count,CallUndefinedReceiver0Handler,2,0 block_count,CallUndefinedReceiver0Handler,3,0 @@ -67309,7 +67312,7 @@ block_count,CallUndefinedReceiver0Handler,65,0 block_count,CallUndefinedReceiver0Handler,66,1 block_count,CallUndefinedReceiver0Handler,67,0 -block_count,CallUndefinedReceiver0Handler,68,1 +block_count,CallUndefinedReceiver0Handler,68,2 block_count,CallUndefinedReceiver1Handler,0,5 block_count,CallUndefinedReceiver1Handler,1,2 block_count,CallUndefinedReceiver1Handler,2,0 @@ -67707,9 +67710,9 @@ block_count,ConstructForwardAllArgsHandler,45,0 block_count,ConstructForwardAllArgsHandler,46,0 block_count,ConstructForwardAllArgsHandler,47,0 -block_count,TestEqualHandler,0,4 -block_count,TestEqualHandler,1,4 -block_count,TestEqualHandler,2,3 +block_count,TestEqualHandler,0,5 +block_count,TestEqualHandler,1,5 +block_count,TestEqualHandler,2,4 block_count,TestEqualHandler,3,1 block_count,TestEqualHandler,4,1 block_count,TestEqualHandler,5,0 @@ -67889,17 +67892,17 @@ block_count,TestEqualHandler,179,0 block_count,TestEqualHandler,180,0 block_count,TestEqualHandler,181,2 -block_count,TestEqualHandler,182,4 +block_count,TestEqualHandler,182,5 block_count,TestEqualHandler,183,4 block_count,TestEqualHandler,184,0 block_count,TestEqualHandler,185,4 block_count,TestEqualHandler,186,0 -block_count,TestEqualHandler,187,4 +block_count,TestEqualHandler,187,5 block_count,TestEqualStrictHandler,0,7 block_count,TestEqualStrictHandler,1,6 block_count,TestEqualStrictHandler,2,5 block_count,TestEqualStrictHandler,3,5 -block_count,TestEqualStrictHandler,4,4 +block_count,TestEqualStrictHandler,4,5 block_count,TestEqualStrictHandler,5,2 block_count,TestEqualStrictHandler,6,2 block_count,TestEqualStrictHandler,7,0 @@ -68294,7 +68297,7 @@ block_count,TestGreaterThanHandler,114,0 block_count,TestGreaterThanHandler,115,0 block_count,TestGreaterThanHandler,116,0 -block_count,TestGreaterThanHandler,117,1 +block_count,TestGreaterThanHandler,117,2 block_count,TestGreaterThanHandler,118,0 block_count,TestGreaterThanHandler,119,0 block_count,TestGreaterThanHandler,120,0 @@ -68306,7 +68309,7 @@ block_count,TestGreaterThanHandler,126,0 block_count,TestGreaterThanHandler,127,0 block_count,TestGreaterThanHandler,128,0 -block_count,TestGreaterThanHandler,129,1 +block_count,TestGreaterThanHandler,129,2 block_count,TestGreaterThanHandler,130,0 block_count,TestGreaterThanHandler,131,1 block_count,TestGreaterThanHandler,132,0 @@ -68322,9 +68325,9 @@ block_count,TestGreaterThanHandler,142,0 block_count,TestGreaterThanHandler,143,1 block_count,TestGreaterThanHandler,144,2 -block_count,TestGreaterThanHandler,145,1 +block_count,TestGreaterThanHandler,145,2 block_count,TestGreaterThanHandler,146,0 -block_count,TestGreaterThanHandler,147,1 +block_count,TestGreaterThanHandler,147,2 block_count,TestGreaterThanHandler,148,0 block_count,TestGreaterThanHandler,149,2 block_count,TestLessThanOrEqualHandler,0,0 @@ -68700,19 +68703,19 @@ block_count,ToNumberHandler,8,0 block_count,ToNumberHandler,9,0 block_count,ToNumberHandler,10,0 -block_count,ToNumericHandler,0,3 +block_count,ToNumericHandler,0,4 block_count,ToNumericHandler,1,0 block_count,ToNumericHandler,2,0 block_count,ToNumericHandler,3,0 block_count,ToNumericHandler,4,0 block_count,ToNumericHandler,5,0 -block_count,ToNumericHandler,6,3 -block_count,ToNumericHandler,7,3 +block_count,ToNumericHandler,6,4 +block_count,ToNumericHandler,7,4 block_count,ToNumericHandler,8,3 block_count,ToNumericHandler,9,0 block_count,ToNumericHandler,10,3 block_count,ToNumericHandler,11,0 -block_count,ToNumericHandler,12,3 +block_count,ToNumericHandler,12,4 block_count,ToObjectHandler,0,0 block_count,ToStringHandler,0,0 block_count,ToStringHandler,1,0 @@ -69242,12 +69245,12 @@ block_count,CreateRestParameterHandler,34,0 block_count,CreateRestParameterHandler,35,0 block_count,CreateRestParameterHandler,36,0 -block_count,JumpLoopHandler,0,13 +block_count,JumpLoopHandler,0,14 block_count,JumpLoopHandler,1,12 block_count,JumpLoopHandler,2,1 block_count,JumpLoopHandler,3,0 block_count,JumpLoopHandler,4,1 -block_count,JumpLoopHandler,5,12 +block_count,JumpLoopHandler,5,13 block_count,JumpLoopHandler,6,0 block_count,JumpLoopHandler,7,0 block_count,JumpLoopHandler,8,0 @@ -69277,15 +69280,15 @@ block_count,JumpLoopHandler,32,0 block_count,JumpLoopHandler,33,0 block_count,JumpLoopHandler,34,0 -block_count,JumpLoopHandler,35,11 -block_count,JumpLoopHandler,36,11 +block_count,JumpLoopHandler,35,12 +block_count,JumpLoopHandler,36,12 block_count,JumpLoopHandler,37,0 -block_count,JumpLoopHandler,38,11 -block_count,JumpLoopHandler,39,11 +block_count,JumpLoopHandler,38,12 +block_count,JumpLoopHandler,39,12 block_count,JumpLoopHandler,40,0 -block_count,JumpLoopHandler,41,11 -block_count,JumpLoopHandler,42,11 -block_count,JumpLoopHandler,43,11 +block_count,JumpLoopHandler,41,12 +block_count,JumpLoopHandler,42,12 +block_count,JumpLoopHandler,43,12 block_count,JumpLoopHandler,44,0 block_count,JumpLoopHandler,45,0 block_count,JumpLoopHandler,46,0 @@ -69365,7 +69368,7 @@ block_count,JumpIfToBooleanFalseConstantHandler,18,0 block_count,JumpIfToBooleanFalseConstantHandler,19,0 block_count,JumpIfToBooleanFalseConstantHandler,20,0 -block_count,JumpIfToBooleanTrueHandler,0,5 +block_count,JumpIfToBooleanTrueHandler,0,6 block_count,JumpIfToBooleanTrueHandler,1,5 block_count,JumpIfToBooleanTrueHandler,2,2 block_count,JumpIfToBooleanTrueHandler,3,1 @@ -69401,16 +69404,16 @@ block_count,JumpIfToBooleanFalseHandler,12,0 block_count,JumpIfToBooleanFalseHandler,13,0 block_count,JumpIfToBooleanFalseHandler,14,1 -block_count,JumpIfToBooleanFalseHandler,15,4 +block_count,JumpIfToBooleanFalseHandler,15,5 block_count,JumpIfToBooleanFalseHandler,16,2 block_count,JumpIfToBooleanFalseHandler,17,2 block_count,JumpIfToBooleanFalseHandler,18,0 -block_count,JumpIfToBooleanFalseHandler,19,6 +block_count,JumpIfToBooleanFalseHandler,19,7 block_count,JumpIfToBooleanFalseHandler,20,5 block_count,JumpIfTrueHandler,0,6 block_count,JumpIfTrueHandler,1,4 block_count,JumpIfTrueHandler,2,1 -block_count,JumpIfFalseHandler,0,22 +block_count,JumpIfFalseHandler,0,23 block_count,JumpIfFalseHandler,1,13 block_count,JumpIfFalseHandler,2,9 block_count,JumpIfNullHandler,0,0 @@ -69516,9 +69519,9 @@ block_count,SetPendingMessageHandler,0,0 block_count,ThrowHandler,0,2 block_count,ReThrowHandler,0,0 -block_count,ReturnHandler,0,20 +block_count,ReturnHandler,0,21 block_count,ReturnHandler,1,0 -block_count,ReturnHandler,2,19 +block_count,ReturnHandler,2,21 block_count,ThrowReferenceErrorIfHoleHandler,0,1 block_count,ThrowReferenceErrorIfHoleHandler,1,1 block_count,ThrowReferenceErrorIfHoleHandler,2,0 @@ -69555,7 +69558,7 @@ block_count,ResumeGeneratorHandler,6,0 block_count,ResumeGeneratorHandler,7,0 block_count,GetIteratorHandler,0,0 -block_count,ShortStarHandler,0,53 +block_count,ShortStarHandler,0,55 block_count,LdarWideHandler,0,0 block_count,LdaSmiWideHandler,0,7 block_count,LdaConstantWideHandler,0,1 @@ -74654,6 +74657,7 @@ builtin_hash,RecordWriteSaveFP,51072216 builtin_hash,RecordWriteIgnoreFP,51072216 builtin_hash,EphemeronKeyBarrierSaveFP,329371410 +builtin_hash,IndirectPointerBarrierIgnoreFP,54101550 builtin_hash,AdaptorWithBuiltinExitFrame0,-129141056 builtin_hash,AdaptorWithBuiltinExitFrame1,-172012137 builtin_hash,AdaptorWithBuiltinExitFrame2,-172012137 diff -Nru chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x64.profile chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64.profile --- chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x64.profile 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x64.profile 2025-03-07 21:29:53.000000000 +0000 @@ -12,13 +12,13 @@ block_hint,RecordWriteSaveFP,32,31,0 block_hint,RecordWriteSaveFP,61,51,0 block_hint,RecordWriteSaveFP,53,52,1 +block_hint,RecordWriteSaveFP,55,56,1 block_hint,RecordWriteIgnoreFP,2,3,0 block_hint,RecordWriteIgnoreFP,5,4,1 block_hint,RecordWriteIgnoreFP,11,6,0 block_hint,RecordWriteIgnoreFP,8,7,1 block_hint,RecordWriteIgnoreFP,10,9,0 block_hint,RecordWriteIgnoreFP,15,29,0 -block_hint,RecordWriteIgnoreFP,17,18,1 block_hint,RecordWriteIgnoreFP,32,31,0 block_hint,RecordWriteIgnoreFP,61,51,0 block_hint,RecordWriteIgnoreFP,53,52,1 @@ -132,7 +132,6 @@ block_hint,Construct_Baseline,13,12,1 block_hint,Construct_Baseline,22,21,1 block_hint,Construct_Baseline,24,23,1 -block_hint,Construct_Baseline,26,25,0 block_hint,Construct_Baseline,32,40,1 block_hint,Construct_Baseline,39,36,0 block_hint,Construct_WithFeedback,45,2,0 @@ -364,6 +363,7 @@ block_hint,KeyedStoreIC_Megamorphic,288,287,0 block_hint,KeyedStoreIC_Megamorphic,290,291,1 block_hint,KeyedStoreIC_Megamorphic,297,296,1 +block_hint,KeyedStoreIC_Megamorphic,317,316,1 block_hint,KeyedStoreIC_Megamorphic,687,615,1 block_hint,KeyedStoreIC_Megamorphic,686,685,1 block_hint,KeyedStoreIC_Megamorphic,701,695,0 @@ -421,7 +421,6 @@ block_hint,KeyedStoreIC_Megamorphic,1228,1222,0 block_hint,KeyedStoreIC_Megamorphic,1226,1223,0 block_hint,KeyedStoreIC_Megamorphic,1224,1225,1 -block_hint,KeyedStoreIC_Megamorphic,1298,1301,0 block_hint,KeyedStoreIC_Megamorphic,1310,1387,0 block_hint,KeyedStoreIC_Megamorphic,1321,1385,0 block_hint,KeyedStoreIC_Megamorphic,1384,1351,1 @@ -469,7 +468,6 @@ block_hint,LoadIC_NoFeedback,1,306,1 block_hint,LoadIC_NoFeedback,10,7,1 block_hint,LoadIC_NoFeedback,17,12,0 -block_hint,LoadIC_NoFeedback,297,19,0 block_hint,LoadIC_NoFeedback,24,23,0 block_hint,LoadIC_NoFeedback,28,27,0 block_hint,LoadIC_NoFeedback,46,36,0 @@ -974,7 +972,6 @@ block_hint,ArrayPrototypePop,31,16,0 block_hint,ArrayPrototypePop,30,17,0 block_hint,ArrayPrototypePop,25,18,0 -block_hint,ArrayPrototypePop,24,19,1 block_hint,ArrayPrototypePop,29,28,1 block_hint,ArrayPrototypePush,2,1,1 block_hint,ArrayPrototypePush,4,180,1 @@ -1030,7 +1027,6 @@ block_hint,CloneFastJSArray,7,6,1 block_hint,CloneFastJSArray,12,11,0 block_hint,CloneFastJSArray,22,23,1 -block_hint,CloneFastJSArray,29,30,1 block_hint,CloneFastJSArray,58,39,0 block_hint,CloneFastJSArray,41,40,1 block_hint,CloneFastJSArray,43,42,1 @@ -1070,9 +1066,7 @@ block_hint,ExtractFastJSArray,11,10,1 block_hint,ExtractFastJSArray,16,15,0 block_hint,ExtractFastJSArray,26,27,1 -block_hint,ExtractFastJSArray,29,28,1 block_hint,ExtractFastJSArray,33,34,1 -block_hint,ExtractFastJSArray,37,36,1 block_hint,ExtractFastJSArray,60,41,0 block_hint,ExtractFastJSArray,43,42,1 block_hint,ExtractFastJSArray,45,44,1 @@ -2037,6 +2031,7 @@ block_hint,BitwiseXorSmi_Baseline,12,5,1 block_hint,BitwiseXorSmi_Baseline,14,15,1 block_hint,BitwiseXorSmi_Baseline,35,34,0 +block_hint,ShiftLeft_Baseline,2,1,0 block_hint,ShiftLeft_Baseline,46,45,0 block_hint,ShiftLeftSmi_Baseline,20,3,1 block_hint,ShiftLeftSmi_Baseline,34,33,0 @@ -2095,7 +2090,6 @@ block_hint,Equal_Baseline,136,137,0 block_hint,Equal_Baseline,174,152,0 block_hint,Equal_Baseline,157,156,0 -block_hint,Equal_Baseline,168,167,1 block_hint,Equal_Baseline,171,172,0 block_hint,Equal_Baseline,176,175,1 block_hint,Equal_Baseline,182,181,1 @@ -2854,7 +2848,6 @@ block_hint,CreateDataProperty,382,325,1 block_hint,CreateDataProperty,381,326,1 block_hint,CreateDataProperty,407,388,1 -block_hint,CreateDataProperty,412,411,0 block_hint,CreateDataProperty,813,414,1 block_hint,CreateDataProperty,812,415,1 block_hint,CreateDataProperty,811,659,1 @@ -3429,12 +3422,10 @@ block_hint,ArrayPrototypeSplice,486,471,1 block_hint,ArrayPrototypeSplice,493,494,1 block_hint,ArrayPrototypeSplice,561,495,0 +block_hint,ArrayPrototypeSplice,536,498,0 block_hint,ArrayPrototypeSplice,518,503,1 block_hint,ArrayPrototypeSplice,505,508,0 block_hint,ArrayPrototypeSplice,516,512,1 -block_hint,ArrayPrototypeSplice,535,534,0 -block_hint,ArrayPrototypeSplice,537,538,0 -block_hint,ArrayPrototypeSplice,550,539,0 block_hint,ArrayPrototypeSplice,585,584,0 block_hint,ArrayPrototypeSplice,588,591,0 block_hint,ArrayPrototypeSplice,594,593,1 @@ -4850,6 +4841,7 @@ block_hint,AllocateIfMutableHeapNumberScriptContextSlot,10,9,1 block_hint,AllocateIfMutableHeapNumberScriptContextSlot,11,12,0 block_hint,AllocateIfMutableHeapNumberScriptContextSlot,13,16,0 +block_hint,AllocateIfMutableHeapNumberScriptContextSlot,27,18,1 block_hint,AllocateIfMutableHeapNumberScriptContextSlot,21,26,0 block_hint,AllocateIfMutableHeapNumberScriptContextSlot,31,30,0 block_hint,StoreCurrentScriptContextSlotBaseline,1,183,1 @@ -5243,6 +5235,7 @@ block_hint,LdaLookupGlobalSlotHandler,2,237,1 block_hint,LdaLookupGlobalSlotHandler,4,3,1 block_hint,LdaLookupGlobalSlotHandler,5,8,1 +block_hint,LdaLookupGlobalSlotHandler,6,7,1 block_hint,LdaLookupGlobalSlotHandler,10,236,1 block_hint,LdaLookupGlobalSlotHandler,11,12,0 block_hint,LdaLookupGlobalSlotHandler,235,13,0 @@ -5255,7 +5248,6 @@ block_hint,GetNamedPropertyHandler,23,20,0 block_hint,GetNamedPropertyHandler,22,21,1 block_hint,GetNamedPropertyHandler,26,83,0 -block_hint,GetNamedPropertyHandler,34,33,0 block_hint,GetNamedPropertyHandler,97,84,0 block_hint,GetNamedPropertyHandler,96,85,1 block_hint,GetNamedPropertyHandler,100,106,1 @@ -5357,6 +5349,7 @@ block_hint,DivSmiHandler,48,45,1 block_hint,ModSmiHandler,4,12,0 block_hint,ModSmiHandler,22,19,1 +block_hint,ModSmiHandler,25,35,1 block_hint,ModSmiHandler,29,26,1 block_hint,ModSmiHandler,33,32,0 block_hint,ModSmiHandler,45,42,1 @@ -5393,12 +5386,6 @@ block_hint,FindNonDefaultConstructorOrConstructHandler,6,13,1 block_hint,FindNonDefaultConstructorOrConstructHandler,12,7,0 block_hint,CallAnyReceiverHandler,66,2,1 -block_hint,CallPropertyHandler,46,45,1 -block_hint,CallPropertyHandler,48,47,0 -block_hint,CallPropertyHandler,55,63,1 -block_hint,CallPropertyHandler,57,58,0 -block_hint,CallPropertyHandler,62,59,0 -block_hint,CallPropertyHandler,60,61,1 block_hint,CallProperty0Handler,46,45,1 block_hint,CallProperty0Handler,48,47,0 block_hint,CallProperty0Handler,55,63,1 @@ -5460,12 +5447,6 @@ block_hint,CallUndefinedReceiver2Handler,28,37,1 block_hint,CallUndefinedReceiver2Handler,36,29,0 block_hint,CallUndefinedReceiver2Handler,35,30,1 -block_hint,CallUndefinedReceiver2Handler,46,45,1 -block_hint,CallUndefinedReceiver2Handler,48,47,0 -block_hint,CallUndefinedReceiver2Handler,55,63,1 -block_hint,CallUndefinedReceiver2Handler,57,58,0 -block_hint,CallUndefinedReceiver2Handler,62,59,0 -block_hint,CallUndefinedReceiver2Handler,60,61,1 block_hint,ConstructHandler,5,6,0 block_hint,ConstructHandler,7,16,1 block_hint,ConstructHandler,8,15,1 @@ -5502,7 +5483,6 @@ block_hint,TestLessThanHandler,118,129,0 block_hint,TestLessThanHandler,147,146,1 block_hint,TestGreaterThanHandler,95,4,1 -block_hint,TestGreaterThanHandler,105,96,1 block_hint,TestGreaterThanHandler,116,107,1 block_hint,TestGreaterThanHandler,118,129,0 block_hint,TestGreaterThanHandler,147,146,1 @@ -5581,9 +5561,18 @@ block_hint,CreateRestParameterHandler,38,2,0 block_hint,CreateRestParameterHandler,4,3,1 block_hint,CreateRestParameterHandler,7,6,1 +block_hint,CreateRestParameterHandler,31,12,0 +block_hint,CreateRestParameterHandler,30,13,0 +block_hint,CreateRestParameterHandler,29,14,0 +block_hint,CreateRestParameterHandler,15,18,1 +block_hint,CreateRestParameterHandler,17,16,1 block_hint,CreateRestParameterHandler,27,23,0 block_hint,CreateRestParameterHandler,25,24,0 -block_hint,JumpLoopHandler,35,6,1 +block_hint,JumpLoopHandler,10,7,1 +block_hint,JumpLoopHandler,12,16,1 +block_hint,JumpLoopHandler,18,21,1 +block_hint,JumpLoopHandler,27,23,0 +block_hint,JumpLoopHandler,25,24,1 block_hint,JumpLoopHandler,36,40,1 block_hint,JumpLoopHandler,37,38,0 block_hint,JumpLoopHandler,42,56,1 @@ -5709,8 +5698,8 @@ block_hint,BitwiseAndSmiExtraWideHandler,27,26,0 block_hint,BitwiseAndSmiExtraWideHandler,41,38,1 block_hint,CallUndefinedReceiver1ExtraWideHandler,1,67,0 -builtin_count,RecordWriteSaveFP,1793 -builtin_count,RecordWriteIgnoreFP,21 +builtin_count,RecordWriteSaveFP,1753 +builtin_count,RecordWriteIgnoreFP,15 builtin_count,EphemeronKeyBarrierSaveFP,0 builtin_count,IndirectPointerBarrierIgnoreFP,0 builtin_count,AdaptorWithBuiltinExitFrame0,118 @@ -5718,12 +5707,12 @@ builtin_count,AdaptorWithBuiltinExitFrame2,0 builtin_count,AdaptorWithBuiltinExitFrame3,8 builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,135 -builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,512 +builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,519 builtin_count,Call_ReceiverIsAny_Baseline_Compact,2 builtin_count,CallProxy,0 builtin_count,CallWithSpread,27 -builtin_count,CallWithSpread_Baseline,1 -builtin_count,CallWithArrayLike,32 +builtin_count,CallWithSpread_Baseline,0 +builtin_count,CallWithArrayLike,33 builtin_count,CallFunctionTemplate_Generic,0 builtin_count,ConstructWithSpread,0 builtin_count,ConstructWithSpread_Baseline,0 @@ -5732,15 +5721,15 @@ builtin_count,ConstructForwardAllArgs_WithFeedback,2 builtin_count,Construct_Baseline,43 builtin_count,Construct_WithFeedback,44 -builtin_count,FastNewObject,268 +builtin_count,FastNewObject,269 builtin_count,FastNewClosure,187 -builtin_count,StringEqual,748 +builtin_count,StringEqual,749 builtin_count,StringGreaterThan,0 builtin_count,StringGreaterThanOrEqual,4 builtin_count,StringLessThan,477 builtin_count,StringLessThanOrEqual,48 builtin_count,StringCompare,3 -builtin_count,StringSubstring,554 +builtin_count,StringSubstring,555 builtin_count,OrderedHashTableHealIndex,0 builtin_count,CompileLazy,1 builtin_count,InstantiateAsmJs,0 @@ -5757,7 +5746,7 @@ builtin_count,GrowFastSmiOrObjectElements,350 builtin_count,ToNumber,0 builtin_count,ToNumber_Baseline,0 -builtin_count,ToNumeric_Baseline,28 +builtin_count,ToNumeric_Baseline,30 builtin_count,ToNumberConvertBigInt,2 builtin_count,Typeof,31 builtin_count,Typeof_Baseline,0 @@ -5772,7 +5761,7 @@ builtin_count,StoreIC_NoFeedback,6 builtin_count,DefineNamedOwnIC_NoFeedback,4 builtin_count,KeyedLoadIC_SloppyArguments,2 -builtin_count,StoreFastElementIC_InBounds,200 +builtin_count,StoreFastElementIC_InBounds,202 builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,19 builtin_count,StoreFastElementIC_NoTransitionHandleCOW,0 builtin_count,ElementsTransitionAndStore_InBounds,0 @@ -5796,7 +5785,7 @@ builtin_count,ArraySingleArgumentConstructor_HoleySmi_DontOverride,0 builtin_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,110 builtin_count,ArraySingleArgumentConstructor_Holey_DisableAllocationSites,2 -builtin_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,1 +builtin_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,2 builtin_count,ArrayIncludesSmi,0 builtin_count,ArrayIncludesSmiOrObject,18 builtin_count,ArrayIncludes,2 @@ -5839,42 +5828,42 @@ builtin_count,ResumeGeneratorBaseline,1 builtin_count,GlobalIsFinite,0 builtin_count,GlobalIsNaN,0 -builtin_count,LoadIC,2442 +builtin_count,LoadIC,2482 builtin_count,LoadIC_Megamorphic,10000 -builtin_count,LoadIC_Noninlined,3 -builtin_count,LoadICTrampoline,305 -builtin_count,LoadICBaseline,1802 -builtin_count,LoadICTrampoline_Megamorphic,5824 +builtin_count,LoadIC_Noninlined,2 +builtin_count,LoadICTrampoline,308 +builtin_count,LoadICBaseline,1840 +builtin_count,LoadICTrampoline_Megamorphic,5826 builtin_count,LoadSuperIC,2 builtin_count,LoadSuperICBaseline,2 -builtin_count,KeyedLoadIC,332 +builtin_count,KeyedLoadIC,339 builtin_count,EnumeratedKeyedLoadIC,4 builtin_count,KeyedLoadIC_Megamorphic,2387 builtin_count,KeyedLoadICTrampoline,1 -builtin_count,KeyedLoadICBaseline,309 +builtin_count,KeyedLoadICBaseline,317 builtin_count,EnumeratedKeyedLoadICBaseline,3 builtin_count,KeyedLoadICTrampoline_Megamorphic,1091 -builtin_count,StoreGlobalIC,680 -builtin_count,StoreGlobalICTrampoline,186 +builtin_count,StoreGlobalIC,379 +builtin_count,StoreGlobalICTrampoline,0 builtin_count,StoreGlobalICBaseline,1 -builtin_count,StoreIC,267 +builtin_count,StoreIC,271 builtin_count,StoreIC_Megamorphic,1372 builtin_count,StoreICTrampoline,27 builtin_count,StoreICTrampoline_Megamorphic,638 -builtin_count,StoreICBaseline,204 -builtin_count,DefineNamedOwnIC,36 -builtin_count,DefineNamedOwnICBaseline,31 -builtin_count,KeyedStoreIC,219 +builtin_count,StoreICBaseline,210 +builtin_count,DefineNamedOwnIC,39 +builtin_count,DefineNamedOwnICBaseline,34 +builtin_count,KeyedStoreIC,222 builtin_count,KeyedStoreICTrampoline,1 builtin_count,KeyedStoreICTrampoline_Megamorphic,332 -builtin_count,KeyedStoreICBaseline,204 +builtin_count,KeyedStoreICBaseline,207 builtin_count,DefineKeyedOwnIC,2 builtin_count,StoreInArrayLiteralIC,17 -builtin_count,StoreInArrayLiteralICBaseline,14 -builtin_count,LoadGlobalIC,1419 +builtin_count,StoreInArrayLiteralICBaseline,15 +builtin_count,LoadGlobalIC,1197 builtin_count,LoadGlobalICInsideTypeof,0 -builtin_count,LoadGlobalICTrampoline,939 -builtin_count,LoadGlobalICBaseline,397 +builtin_count,LoadGlobalICTrampoline,731 +builtin_count,LoadGlobalICBaseline,403 builtin_count,LoadGlobalICInsideTypeofBaseline,0 builtin_count,LookupGlobalICBaseline,0 builtin_count,LookupGlobalICInsideTypeofBaseline,0 @@ -5898,27 +5887,27 @@ builtin_count,MapPrototypeValues,1 builtin_count,MapIteratorPrototypeNext,12 builtin_count,MapIteratorToList,0 -builtin_count,Add_Baseline,190 -builtin_count,AddSmi_Baseline,241 +builtin_count,Add_Baseline,199 +builtin_count,AddSmi_Baseline,244 builtin_count,Subtract_Baseline,47 builtin_count,SubtractSmi_Baseline,20 -builtin_count,Multiply_Baseline,50 +builtin_count,Multiply_Baseline,55 builtin_count,MultiplySmi_Baseline,5 -builtin_count,Divide_Baseline,3 +builtin_count,Divide_Baseline,4 builtin_count,DivideSmi_Baseline,1 builtin_count,Modulus_Baseline,0 builtin_count,ModulusSmi_Baseline,0 builtin_count,Exponentiate_Baseline,0 -builtin_count,BitwiseAnd_Baseline,9 -builtin_count,BitwiseAndSmi_Baseline,31 -builtin_count,BitwiseOr_Baseline,19 +builtin_count,BitwiseAnd_Baseline,8 +builtin_count,BitwiseAndSmi_Baseline,33 +builtin_count,BitwiseOr_Baseline,20 builtin_count,BitwiseOrSmi_Baseline,181 builtin_count,BitwiseXor_Baseline,9 builtin_count,BitwiseXorSmi_Baseline,0 builtin_count,ShiftLeft_Baseline,1 builtin_count,ShiftLeftSmi_Baseline,30 -builtin_count,ShiftRight_Baseline,1 -builtin_count,ShiftRightSmi_Baseline,115 +builtin_count,ShiftRight_Baseline,2 +builtin_count,ShiftRightSmi_Baseline,116 builtin_count,ShiftRightLogical_Baseline,0 builtin_count,ShiftRightLogicalSmi_Baseline,3 builtin_count,Add_WithFeedback,44 @@ -5926,20 +5915,20 @@ builtin_count,Divide_WithFeedback,0 builtin_count,Modulus_WithFeedback,1 builtin_count,BitwiseOr_WithFeedback,0 -builtin_count,Equal_Baseline,151 -builtin_count,StrictEqual_Baseline,190 -builtin_count,LessThan_Baseline,147 +builtin_count,Equal_Baseline,154 +builtin_count,StrictEqual_Baseline,210 +builtin_count,LessThan_Baseline,153 builtin_count,GreaterThan_Baseline,44 -builtin_count,LessThanOrEqual_Baseline,20 -builtin_count,GreaterThanOrEqual_Baseline,38 +builtin_count,LessThanOrEqual_Baseline,21 +builtin_count,GreaterThanOrEqual_Baseline,40 builtin_count,Equal_WithFeedback,10 builtin_count,StrictEqual_WithFeedback,122 builtin_count,LessThan_WithFeedback,3 builtin_count,GreaterThan_WithFeedback,2 builtin_count,GreaterThanOrEqual_WithFeedback,0 builtin_count,BitwiseNot_Baseline,1 -builtin_count,Decrement_Baseline,18 -builtin_count,Increment_Baseline,101 +builtin_count,Decrement_Baseline,17 +builtin_count,Increment_Baseline,109 builtin_count,Negate_Baseline,3 builtin_count,ObjectAssign,2 builtin_count,ObjectCreate,7 @@ -5950,7 +5939,7 @@ builtin_count,ObjectKeys,14 builtin_count,ObjectPrototypeHasOwnProperty,240 builtin_count,ObjectToString,62 -builtin_count,OrdinaryHasInstance,109 +builtin_count,OrdinaryHasInstance,107 builtin_count,InstanceOf,7 builtin_count,InstanceOf_WithFeedback,3 builtin_count,InstanceOf_Baseline,34 @@ -5969,7 +5958,7 @@ builtin_count,SetPrototypeValues,6 builtin_count,SetIteratorPrototypeNext,50 builtin_count,SetOrSetIteratorToList,0 -builtin_count,StringFromCharCode,15 +builtin_count,StringFromCharCode,20 builtin_count,StringPrototypeReplace,244 builtin_count,StringPrototypeSplit,53 builtin_count,TypedArrayConstructor,3 @@ -6022,7 +6011,7 @@ builtin_count,ArrayPrototypeLastIndexOf,1 builtin_count,ArrayMapLoopLazyDeoptContinuation,0 builtin_count,ArrayMapLoopContinuation,0 -builtin_count,ArrayMap,27 +builtin_count,ArrayMap,26 builtin_count,ArrayReduceLoopLazyDeoptContinuation,0 builtin_count,ArrayReduceLoopContinuation,0 builtin_count,ArrayReduce,1 @@ -6048,9 +6037,9 @@ builtin_count,StringAddConvertLeft,17 builtin_count,StringAddConvertRight,202 builtin_count,StringCharAt,9 -builtin_count,FastNewClosureBaseline,32 +builtin_count,FastNewClosureBaseline,33 builtin_count,FastNewFunctionContextFunction,61 -builtin_count,CreateRegExpLiteral,11 +builtin_count,CreateRegExpLiteral,12 builtin_count,CreateShallowArrayLiteral,8 builtin_count,CreateEmptyArrayLiteral,13 builtin_count,CreateShallowObjectLiteral,16 @@ -6063,7 +6052,7 @@ builtin_count,ToNumeric,16 builtin_count,NumberToString,1499 builtin_count,ToBoolean,34 -builtin_count,ToBooleanForBaselineJump,407 +builtin_count,ToBooleanForBaselineJump,413 builtin_count,ToLength,2 builtin_count,ToName,47 builtin_count,ToObject,243 @@ -6081,7 +6070,7 @@ builtin_count,FastFunctionPrototypeBind,5 builtin_count,ForInNext,34 builtin_count,GetIteratorWithFeedback,0 -builtin_count,GetIteratorBaseline,12 +builtin_count,GetIteratorBaseline,13 builtin_count,CallIteratorWithFeedback,13 builtin_count,MathAbs,0 builtin_count,MathCeil,0 @@ -6108,7 +6097,7 @@ builtin_count,NumberIsNaN,0 builtin_count,NumberParseFloat,12 builtin_count,ParseInt,133 -builtin_count,NumberParseInt,7 +builtin_count,NumberParseInt,6 builtin_count,Add,47 builtin_count,Subtract,0 builtin_count,Multiply,0 @@ -6154,8 +6143,8 @@ builtin_count,RegExpSearchFast,1 builtin_count,RegExpPrototypeSourceGetter,0 builtin_count,RegExpSplit,13 -builtin_count,RegExpPrototypeTest,114 -builtin_count,RegExpPrototypeTestFast,427 +builtin_count,RegExpPrototypeTest,115 +builtin_count,RegExpPrototypeTestFast,426 builtin_count,RegExpPrototypeGlobalGetter,0 builtin_count,RegExpPrototypeIgnoreCaseGetter,0 builtin_count,RegExpPrototypeMultilineGetter,0 @@ -6167,7 +6156,7 @@ builtin_count,RegExpPrototypeFlagsGetter,0 builtin_count,StringPrototypeEndsWith,0 builtin_count,StringPrototypeIncludes,0 -builtin_count,StringPrototypeIndexOf,12 +builtin_count,StringPrototypeIndexOf,11 builtin_count,StringPrototypeIterator,0 builtin_count,StringIteratorPrototypeNext,0 builtin_count,StringPrototypeMatch,1235 @@ -6222,10 +6211,10 @@ builtin_count,StringToLowerCaseIntl,146 builtin_count,WideHandler,61 builtin_count,ExtraWideHandler,10 -builtin_count,LdarHandler,86 +builtin_count,LdarHandler,82 builtin_count,LdaZeroHandler,10 -builtin_count,LdaSmiHandler,11 -builtin_count,LdaUndefinedHandler,8 +builtin_count,LdaSmiHandler,12 +builtin_count,LdaUndefinedHandler,7 builtin_count,LdaNullHandler,1 builtin_count,LdaTheHoleHandler,0 builtin_count,LdaTrueHandler,2 @@ -6233,12 +6222,12 @@ builtin_count,LdaConstantHandler,13 builtin_count,LdaContextSlotHandler,0 builtin_count,LdaScriptContextSlotHandler,0 -builtin_count,LdaImmutableContextSlotHandler,7 +builtin_count,LdaImmutableContextSlotHandler,6 builtin_count,LdaCurrentContextSlotHandler,5 builtin_count,LdaCurrentScriptContextSlotHandler,0 -builtin_count,LdaImmutableCurrentContextSlotHandler,20 +builtin_count,LdaImmutableCurrentContextSlotHandler,18 builtin_count,StarHandler,19 -builtin_count,MovHandler,19 +builtin_count,MovHandler,18 builtin_count,PushContextHandler,2 builtin_count,PopContextHandler,0 builtin_count,TestReferenceEqualHandler,0 @@ -6246,23 +6235,23 @@ builtin_count,TestNullHandler,0 builtin_count,TestUndefinedHandler,0 builtin_count,TestTypeOfHandler,0 -builtin_count,LdaGlobalHandler,23 +builtin_count,LdaGlobalHandler,24 builtin_count,LdaGlobalInsideTypeofHandler,0 builtin_count,StaGlobalHandler,0 builtin_count,StaContextSlotHandler,0 -builtin_count,StaCurrentContextSlotHandler,8 +builtin_count,StaCurrentContextSlotHandler,7 builtin_count,StaScriptContextSlotHandler,0 builtin_count,StaCurrentScriptContextSlotHandler,0 builtin_count,LdaLookupGlobalSlotHandler,0 builtin_count,LdaLookupGlobalSlotInsideTypeofHandler,0 builtin_count,StaLookupSlotHandler,0 -builtin_count,GetNamedPropertyHandler,72 +builtin_count,GetNamedPropertyHandler,74 builtin_count,GetNamedPropertyFromSuperHandler,0 -builtin_count,GetKeyedPropertyHandler,20 +builtin_count,GetKeyedPropertyHandler,19 builtin_count,GetEnumeratedKeyedPropertyHandler,1 builtin_count,SetNamedPropertyHandler,10 builtin_count,DefineNamedOwnPropertyHandler,3 -builtin_count,SetKeyedPropertyHandler,12 +builtin_count,SetKeyedPropertyHandler,11 builtin_count,DefineKeyedOwnPropertyHandler,0 builtin_count,StaInArrayLiteralHandler,1 builtin_count,DefineKeyedOwnPropertyInLiteralHandler,0 @@ -6272,7 +6261,7 @@ builtin_count,DivHandler,0 builtin_count,ModHandler,0 builtin_count,ExpHandler,0 -builtin_count,BitwiseOrHandler,0 +builtin_count,BitwiseOrHandler,1 builtin_count,BitwiseXorHandler,0 builtin_count,BitwiseAndHandler,0 builtin_count,ShiftLeftHandler,0 @@ -6289,7 +6278,7 @@ builtin_count,ShiftLeftSmiHandler,1 builtin_count,ShiftRightSmiHandler,2 builtin_count,ShiftRightLogicalSmiHandler,0 -builtin_count,IncHandler,12 +builtin_count,IncHandler,11 builtin_count,DecHandler,2 builtin_count,NegateHandler,0 builtin_count,BitwiseNotHandler,0 @@ -6301,11 +6290,11 @@ builtin_count,FindNonDefaultConstructorOrConstructHandler,0 builtin_count,CallAnyReceiverHandler,0 builtin_count,CallPropertyHandler,2 -builtin_count,CallProperty0Handler,4 +builtin_count,CallProperty0Handler,5 builtin_count,CallProperty1Handler,12 -builtin_count,CallProperty2Handler,3 +builtin_count,CallProperty2Handler,4 builtin_count,CallUndefinedReceiverHandler,1 -builtin_count,CallUndefinedReceiver0Handler,1 +builtin_count,CallUndefinedReceiver0Handler,2 builtin_count,CallUndefinedReceiver1Handler,5 builtin_count,CallUndefinedReceiver2Handler,3 builtin_count,CallWithSpreadHandler,0 @@ -6318,14 +6307,14 @@ builtin_count,TestEqualHandler,4 builtin_count,TestEqualStrictHandler,7 builtin_count,TestLessThanHandler,10 -builtin_count,TestGreaterThanHandler,1 +builtin_count,TestGreaterThanHandler,2 builtin_count,TestLessThanOrEqualHandler,0 builtin_count,TestGreaterThanOrEqualHandler,1 builtin_count,TestInstanceOfHandler,0 builtin_count,TestInHandler,0 builtin_count,ToNameHandler,0 builtin_count,ToNumberHandler,0 -builtin_count,ToNumericHandler,4 +builtin_count,ToNumericHandler,3 builtin_count,ToObjectHandler,0 builtin_count,ToStringHandler,0 builtin_count,ToBooleanHandler,0 @@ -6353,8 +6342,8 @@ builtin_count,JumpIfForInDoneConstantHandler,0 builtin_count,JumpIfToBooleanTrueConstantHandler,0 builtin_count,JumpIfToBooleanFalseConstantHandler,0 -builtin_count,JumpIfToBooleanTrueHandler,6 -builtin_count,JumpIfToBooleanFalseHandler,12 +builtin_count,JumpIfToBooleanTrueHandler,5 +builtin_count,JumpIfToBooleanFalseHandler,11 builtin_count,JumpIfTrueHandler,6 builtin_count,JumpIfFalseHandler,22 builtin_count,JumpIfNullHandler,0 @@ -6381,7 +6370,7 @@ builtin_count,SuspendGeneratorHandler,0 builtin_count,ResumeGeneratorHandler,0 builtin_count,GetIteratorHandler,0 -builtin_count,ShortStarHandler,54 +builtin_count,ShortStarHandler,53 builtin_count,LdarWideHandler,0 builtin_count,LdaSmiWideHandler,7 builtin_count,LdaConstantWideHandler,1 @@ -6479,24 +6468,24 @@ builtin_count,CallUndefinedReceiverExtraWideHandler,0 builtin_count,CallUndefinedReceiver1ExtraWideHandler,4 builtin_count,CallUndefinedReceiver2ExtraWideHandler,0 -block_count,RecordWriteSaveFP,0,1793 -block_count,RecordWriteSaveFP,1,1762 +block_count,RecordWriteSaveFP,0,1753 +block_count,RecordWriteSaveFP,1,1735 block_count,RecordWriteSaveFP,2,0 -block_count,RecordWriteSaveFP,3,1762 +block_count,RecordWriteSaveFP,3,1735 block_count,RecordWriteSaveFP,4,0 -block_count,RecordWriteSaveFP,5,1762 -block_count,RecordWriteSaveFP,6,1762 +block_count,RecordWriteSaveFP,5,1735 +block_count,RecordWriteSaveFP,6,1735 block_count,RecordWriteSaveFP,7,0 -block_count,RecordWriteSaveFP,8,1762 -block_count,RecordWriteSaveFP,9,1761 +block_count,RecordWriteSaveFP,8,1735 +block_count,RecordWriteSaveFP,9,1734 block_count,RecordWriteSaveFP,10,0 block_count,RecordWriteSaveFP,11,0 block_count,RecordWriteSaveFP,12,0 -block_count,RecordWriteSaveFP,13,1762 -block_count,RecordWriteSaveFP,14,30 -block_count,RecordWriteSaveFP,15,11 -block_count,RecordWriteSaveFP,16,11 -block_count,RecordWriteSaveFP,17,11 +block_count,RecordWriteSaveFP,13,1735 +block_count,RecordWriteSaveFP,14,18 +block_count,RecordWriteSaveFP,15,8 +block_count,RecordWriteSaveFP,16,7 +block_count,RecordWriteSaveFP,17,7 block_count,RecordWriteSaveFP,18,0 block_count,RecordWriteSaveFP,19,0 block_count,RecordWriteSaveFP,20,0 @@ -6508,9 +6497,9 @@ block_count,RecordWriteSaveFP,26,0 block_count,RecordWriteSaveFP,27,0 block_count,RecordWriteSaveFP,28,0 -block_count,RecordWriteSaveFP,29,18 -block_count,RecordWriteSaveFP,30,30 -block_count,RecordWriteSaveFP,31,30 +block_count,RecordWriteSaveFP,29,10 +block_count,RecordWriteSaveFP,30,18 +block_count,RecordWriteSaveFP,31,18 block_count,RecordWriteSaveFP,32,0 block_count,RecordWriteSaveFP,33,0 block_count,RecordWriteSaveFP,34,0 @@ -6529,17 +6518,17 @@ block_count,RecordWriteSaveFP,47,0 block_count,RecordWriteSaveFP,48,0 block_count,RecordWriteSaveFP,49,0 -block_count,RecordWriteSaveFP,50,30 -block_count,RecordWriteSaveFP,51,30 +block_count,RecordWriteSaveFP,50,18 +block_count,RecordWriteSaveFP,51,18 block_count,RecordWriteSaveFP,52,0 -block_count,RecordWriteSaveFP,53,30 -block_count,RecordWriteSaveFP,54,28 -block_count,RecordWriteSaveFP,55,23 -block_count,RecordWriteSaveFP,56,4 -block_count,RecordWriteSaveFP,57,4 +block_count,RecordWriteSaveFP,53,18 +block_count,RecordWriteSaveFP,54,17 +block_count,RecordWriteSaveFP,55,17 +block_count,RecordWriteSaveFP,56,0 +block_count,RecordWriteSaveFP,57,0 block_count,RecordWriteSaveFP,58,0 -block_count,RecordWriteSaveFP,59,2 -block_count,RecordWriteSaveFP,60,6 +block_count,RecordWriteSaveFP,59,1 +block_count,RecordWriteSaveFP,60,1 block_count,RecordWriteSaveFP,61,0 block_count,RecordWriteSaveFP,62,0 block_count,RecordWriteSaveFP,63,0 @@ -6547,22 +6536,22 @@ block_count,RecordWriteSaveFP,65,0 block_count,RecordWriteSaveFP,66,0 block_count,RecordWriteSaveFP,67,0 -block_count,RecordWriteSaveFP,68,30 -block_count,RecordWriteIgnoreFP,0,21 +block_count,RecordWriteSaveFP,68,18 +block_count,RecordWriteIgnoreFP,0,15 block_count,RecordWriteIgnoreFP,1,14 block_count,RecordWriteIgnoreFP,2,0 block_count,RecordWriteIgnoreFP,3,14 block_count,RecordWriteIgnoreFP,4,0 block_count,RecordWriteIgnoreFP,5,14 -block_count,RecordWriteIgnoreFP,6,14 +block_count,RecordWriteIgnoreFP,6,13 block_count,RecordWriteIgnoreFP,7,0 -block_count,RecordWriteIgnoreFP,8,14 -block_count,RecordWriteIgnoreFP,9,14 +block_count,RecordWriteIgnoreFP,8,13 +block_count,RecordWriteIgnoreFP,9,13 block_count,RecordWriteIgnoreFP,10,0 block_count,RecordWriteIgnoreFP,11,0 block_count,RecordWriteIgnoreFP,12,0 block_count,RecordWriteIgnoreFP,13,14 -block_count,RecordWriteIgnoreFP,14,6 +block_count,RecordWriteIgnoreFP,14,1 block_count,RecordWriteIgnoreFP,15,0 block_count,RecordWriteIgnoreFP,16,0 block_count,RecordWriteIgnoreFP,17,0 @@ -6577,9 +6566,9 @@ block_count,RecordWriteIgnoreFP,26,0 block_count,RecordWriteIgnoreFP,27,0 block_count,RecordWriteIgnoreFP,28,0 -block_count,RecordWriteIgnoreFP,29,6 -block_count,RecordWriteIgnoreFP,30,6 -block_count,RecordWriteIgnoreFP,31,6 +block_count,RecordWriteIgnoreFP,29,1 +block_count,RecordWriteIgnoreFP,30,1 +block_count,RecordWriteIgnoreFP,31,1 block_count,RecordWriteIgnoreFP,32,0 block_count,RecordWriteIgnoreFP,33,0 block_count,RecordWriteIgnoreFP,34,0 @@ -6598,12 +6587,12 @@ block_count,RecordWriteIgnoreFP,47,0 block_count,RecordWriteIgnoreFP,48,0 block_count,RecordWriteIgnoreFP,49,0 -block_count,RecordWriteIgnoreFP,50,6 -block_count,RecordWriteIgnoreFP,51,6 +block_count,RecordWriteIgnoreFP,50,1 +block_count,RecordWriteIgnoreFP,51,1 block_count,RecordWriteIgnoreFP,52,0 -block_count,RecordWriteIgnoreFP,53,6 -block_count,RecordWriteIgnoreFP,54,5 -block_count,RecordWriteIgnoreFP,55,5 +block_count,RecordWriteIgnoreFP,53,1 +block_count,RecordWriteIgnoreFP,54,1 +block_count,RecordWriteIgnoreFP,55,1 block_count,RecordWriteIgnoreFP,56,0 block_count,RecordWriteIgnoreFP,57,0 block_count,RecordWriteIgnoreFP,58,0 @@ -6616,7 +6605,7 @@ block_count,RecordWriteIgnoreFP,65,0 block_count,RecordWriteIgnoreFP,66,0 block_count,RecordWriteIgnoreFP,67,0 -block_count,RecordWriteIgnoreFP,68,6 +block_count,RecordWriteIgnoreFP,68,1 block_count,EphemeronKeyBarrierSaveFP,0,0 block_count,IndirectPointerBarrierIgnoreFP,0,0 block_count,AdaptorWithBuiltinExitFrame0,0,118 @@ -6634,14 +6623,14 @@ block_count,AdaptorWithBuiltinExitFrame3,3,8 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,135 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,135 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,36 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,5,32 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,35 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,5,31 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,6,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,7,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,8,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,9,32 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,7,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,8,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,9,31 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,10,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,11,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,12,0 @@ -6659,15 +6648,15 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,24,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,25,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,26,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,27,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,28,32 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,29,32 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,27,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,28,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,29,31 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,30,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,31,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,32,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,33,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,34,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,32 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,31 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,36,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,37,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,38,0 @@ -6698,12 +6687,12 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,64,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,65,3 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,98 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,99 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,67,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,135 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,512 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,512 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,28 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,519 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,519 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,29 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,3,12 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,4,11 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,5,11 @@ -6766,10 +6755,10 @@ block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,62,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,64,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,15 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,484 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,16 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,490 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,512 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,519 block_count,Call_ReceiverIsAny_Baseline_Compact,0,2 block_count,Call_ReceiverIsAny_Baseline_Compact,1,2 block_count,Call_ReceiverIsAny_Baseline_Compact,2,0 @@ -6943,8 +6932,8 @@ block_count,CallWithSpread,62,0 block_count,CallWithSpread,63,0 block_count,CallWithSpread,64,22 -block_count,CallWithSpread_Baseline,0,1 -block_count,CallWithSpread_Baseline,1,1 +block_count,CallWithSpread_Baseline,0,0 +block_count,CallWithSpread_Baseline,1,0 block_count,CallWithSpread_Baseline,2,0 block_count,CallWithSpread_Baseline,3,0 block_count,CallWithSpread_Baseline,4,0 @@ -7011,8 +7000,8 @@ block_count,CallWithSpread_Baseline,65,0 block_count,CallWithSpread_Baseline,66,0 block_count,CallWithSpread_Baseline,67,0 -block_count,CallWithSpread_Baseline,68,1 -block_count,CallWithSpread_Baseline,69,1 +block_count,CallWithSpread_Baseline,68,0 +block_count,CallWithSpread_Baseline,69,0 block_count,CallWithSpread_Baseline,70,0 block_count,CallWithSpread_Baseline,71,0 block_count,CallWithSpread_Baseline,72,0 @@ -7076,13 +7065,13 @@ block_count,CallWithSpread_Baseline,130,0 block_count,CallWithSpread_Baseline,131,0 block_count,CallWithSpread_Baseline,132,0 -block_count,CallWithArrayLike,0,32 -block_count,CallWithArrayLike,1,32 +block_count,CallWithArrayLike,0,33 +block_count,CallWithArrayLike,1,33 block_count,CallWithArrayLike,2,0 -block_count,CallWithArrayLike,3,32 -block_count,CallWithArrayLike,4,32 +block_count,CallWithArrayLike,3,33 +block_count,CallWithArrayLike,4,33 block_count,CallWithArrayLike,5,0 -block_count,CallWithArrayLike,6,32 +block_count,CallWithArrayLike,6,33 block_count,CallWithArrayLike,7,31 block_count,CallWithArrayLike,8,0 block_count,CallWithArrayLike,9,31 @@ -7105,18 +7094,18 @@ block_count,CallWithArrayLike,26,0 block_count,CallWithArrayLike,27,0 block_count,CallWithArrayLike,28,1 -block_count,CallWithArrayLike,29,1 +block_count,CallWithArrayLike,29,2 block_count,CallWithArrayLike,30,0 -block_count,CallWithArrayLike,31,1 +block_count,CallWithArrayLike,31,2 block_count,CallWithArrayLike,32,0 -block_count,CallWithArrayLike,33,0 +block_count,CallWithArrayLike,33,1 block_count,CallWithArrayLike,34,0 block_count,CallWithArrayLike,35,0 block_count,CallWithArrayLike,36,0 block_count,CallWithArrayLike,37,0 -block_count,CallWithArrayLike,38,30 +block_count,CallWithArrayLike,38,31 block_count,CallWithArrayLike,39,1 -block_count,CallWithArrayLike,40,32 +block_count,CallWithArrayLike,40,33 block_count,CallWithArrayLike,41,0 block_count,CallWithArrayLike,42,0 block_count,CallWithArrayLike,43,0 @@ -7149,7 +7138,7 @@ block_count,CallWithArrayLike,70,0 block_count,CallWithArrayLike,71,0 block_count,CallWithArrayLike,72,0 -block_count,CallWithArrayLike,73,32 +block_count,CallWithArrayLike,73,33 block_count,CallFunctionTemplate_Generic,0,0 block_count,CallFunctionTemplate_Generic,1,0 block_count,CallFunctionTemplate_Generic,2,0 @@ -7593,23 +7582,23 @@ block_count,Construct_Baseline,40,0 block_count,Construct_Baseline,41,1 block_count,Construct_Baseline,42,1 -block_count,Construct_Baseline,43,41 +block_count,Construct_Baseline,43,40 block_count,Construct_Baseline,44,42 block_count,Construct_WithFeedback,0,44 block_count,Construct_WithFeedback,1,44 block_count,Construct_WithFeedback,2,10 -block_count,Construct_WithFeedback,3,3 -block_count,Construct_WithFeedback,4,3 +block_count,Construct_WithFeedback,3,4 +block_count,Construct_WithFeedback,4,4 block_count,Construct_WithFeedback,5,0 -block_count,Construct_WithFeedback,6,3 -block_count,Construct_WithFeedback,7,3 -block_count,Construct_WithFeedback,8,3 +block_count,Construct_WithFeedback,6,4 +block_count,Construct_WithFeedback,7,4 +block_count,Construct_WithFeedback,8,4 block_count,Construct_WithFeedback,9,0 -block_count,Construct_WithFeedback,10,3 +block_count,Construct_WithFeedback,10,4 block_count,Construct_WithFeedback,11,0 -block_count,Construct_WithFeedback,12,3 +block_count,Construct_WithFeedback,12,4 block_count,Construct_WithFeedback,13,0 -block_count,Construct_WithFeedback,14,3 +block_count,Construct_WithFeedback,14,4 block_count,Construct_WithFeedback,15,0 block_count,Construct_WithFeedback,16,0 block_count,Construct_WithFeedback,17,0 @@ -7637,18 +7626,18 @@ block_count,Construct_WithFeedback,39,0 block_count,Construct_WithFeedback,40,0 block_count,Construct_WithFeedback,41,0 -block_count,Construct_WithFeedback,42,3 +block_count,Construct_WithFeedback,42,4 block_count,Construct_WithFeedback,43,6 block_count,Construct_WithFeedback,44,33 block_count,Construct_WithFeedback,45,0 block_count,Construct_WithFeedback,46,40 -block_count,FastNewObject,0,268 +block_count,FastNewObject,0,269 block_count,FastNewObject,1,0 -block_count,FastNewObject,2,268 -block_count,FastNewObject,3,268 -block_count,FastNewObject,4,265 -block_count,FastNewObject,5,265 -block_count,FastNewObject,6,265 +block_count,FastNewObject,2,269 +block_count,FastNewObject,3,269 +block_count,FastNewObject,4,266 +block_count,FastNewObject,5,266 +block_count,FastNewObject,6,266 block_count,FastNewObject,7,0 block_count,FastNewObject,8,0 block_count,FastNewObject,9,0 @@ -7674,25 +7663,25 @@ block_count,FastNewObject,29,0 block_count,FastNewObject,30,0 block_count,FastNewObject,31,0 -block_count,FastNewObject,32,265 -block_count,FastNewObject,33,265 +block_count,FastNewObject,32,266 +block_count,FastNewObject,33,266 block_count,FastNewObject,34,0 -block_count,FastNewObject,35,265 +block_count,FastNewObject,35,266 block_count,FastNewObject,36,0 block_count,FastNewObject,37,0 -block_count,FastNewObject,38,265 -block_count,FastNewObject,39,264 +block_count,FastNewObject,38,266 +block_count,FastNewObject,39,266 block_count,FastNewObject,40,1 -block_count,FastNewObject,41,263 +block_count,FastNewObject,41,265 block_count,FastNewObject,42,47 -block_count,FastNewObject,43,215 -block_count,FastNewObject,44,389 -block_count,FastNewObject,45,173 -block_count,FastNewObject,46,215 -block_count,FastNewObject,47,263 -block_count,FastNewObject,48,181 -block_count,FastNewObject,49,81 -block_count,FastNewObject,50,264 +block_count,FastNewObject,43,217 +block_count,FastNewObject,44,392 +block_count,FastNewObject,45,175 +block_count,FastNewObject,46,217 +block_count,FastNewObject,47,265 +block_count,FastNewObject,48,182 +block_count,FastNewObject,49,82 +block_count,FastNewObject,50,266 block_count,FastNewObject,51,0 block_count,FastNewObject,52,0 block_count,FastNewObject,53,0 @@ -7736,23 +7725,23 @@ block_count,FastNewClosure,11,0 block_count,FastNewClosure,12,0 block_count,FastNewClosure,13,187 -block_count,FastNewClosure,14,68 -block_count,FastNewClosure,15,119 -block_count,FastNewClosure,16,119 +block_count,FastNewClosure,14,67 +block_count,FastNewClosure,15,120 +block_count,FastNewClosure,16,120 block_count,FastNewClosure,17,0 block_count,FastNewClosure,18,0 block_count,FastNewClosure,19,0 block_count,FastNewClosure,20,0 -block_count,FastNewClosure,21,119 +block_count,FastNewClosure,21,120 block_count,FastNewClosure,22,0 -block_count,FastNewClosure,23,119 +block_count,FastNewClosure,23,120 block_count,FastNewClosure,24,187 -block_count,FastNewClosure,25,68 -block_count,FastNewClosure,26,119 -block_count,StringEqual,0,748 -block_count,StringEqual,1,761 +block_count,FastNewClosure,25,67 +block_count,FastNewClosure,26,120 +block_count,StringEqual,0,749 +block_count,StringEqual,1,762 block_count,StringEqual,2,304 -block_count,StringEqual,3,18 +block_count,StringEqual,3,19 block_count,StringEqual,4,15 block_count,StringEqual,5,10 block_count,StringEqual,6,3 @@ -7763,12 +7752,12 @@ block_count,StringEqual,11,4 block_count,StringEqual,12,4 block_count,StringEqual,13,0 -block_count,StringEqual,14,4 +block_count,StringEqual,14,3 block_count,StringEqual,15,4 block_count,StringEqual,16,0 block_count,StringEqual,17,4 block_count,StringEqual,18,3 -block_count,StringEqual,19,9 +block_count,StringEqual,19,10 block_count,StringEqual,20,9 block_count,StringEqual,21,3 block_count,StringEqual,22,0 @@ -7801,7 +7790,7 @@ block_count,StringEqual,49,78 block_count,StringEqual,50,194 block_count,StringEqual,51,217 -block_count,StringEqual,52,91 +block_count,StringEqual,52,92 block_count,StringEqual,53,90 block_count,StringEqual,54,22 block_count,StringEqual,55,67 @@ -8161,24 +8150,24 @@ block_count,StringCompare,52,0 block_count,StringCompare,53,0 block_count,StringCompare,54,0 -block_count,StringSubstring,0,554 -block_count,StringSubstring,1,542 -block_count,StringSubstring,2,542 -block_count,StringSubstring,3,439 -block_count,StringSubstring,4,628 -block_count,StringSubstring,5,188 -block_count,StringSubstring,6,188 +block_count,StringSubstring,0,555 +block_count,StringSubstring,1,543 +block_count,StringSubstring,2,543 +block_count,StringSubstring,3,440 +block_count,StringSubstring,4,630 +block_count,StringSubstring,5,189 +block_count,StringSubstring,6,189 block_count,StringSubstring,7,181 block_count,StringSubstring,8,6 -block_count,StringSubstring,9,174 +block_count,StringSubstring,9,175 block_count,StringSubstring,10,7 block_count,StringSubstring,11,7 block_count,StringSubstring,12,0 -block_count,StringSubstring,13,188 +block_count,StringSubstring,13,189 block_count,StringSubstring,14,0 -block_count,StringSubstring,15,439 -block_count,StringSubstring,16,439 -block_count,StringSubstring,17,194 +block_count,StringSubstring,15,440 +block_count,StringSubstring,16,440 +block_count,StringSubstring,17,195 block_count,StringSubstring,18,4 block_count,StringSubstring,19,0 block_count,StringSubstring,20,4 @@ -8523,7 +8512,7 @@ block_count,GrowFastDoubleElements,21,379 block_count,GrowFastDoubleElements,22,162 block_count,GrowFastDoubleElements,23,4834 -block_count,GrowFastDoubleElements,24,4832 +block_count,GrowFastDoubleElements,24,4833 block_count,GrowFastDoubleElements,25,1 block_count,GrowFastDoubleElements,26,4834 block_count,GrowFastDoubleElements,27,4671 @@ -8547,16 +8536,16 @@ block_count,GrowFastSmiOrObjectElements,11,350 block_count,GrowFastSmiOrObjectElements,12,0 block_count,GrowFastSmiOrObjectElements,13,350 -block_count,GrowFastSmiOrObjectElements,14,4607 -block_count,GrowFastSmiOrObjectElements,15,4256 +block_count,GrowFastSmiOrObjectElements,14,4606 +block_count,GrowFastSmiOrObjectElements,15,4255 block_count,GrowFastSmiOrObjectElements,16,350 block_count,GrowFastSmiOrObjectElements,17,350 block_count,GrowFastSmiOrObjectElements,18,18 block_count,GrowFastSmiOrObjectElements,19,332 block_count,GrowFastSmiOrObjectElements,20,350 block_count,GrowFastSmiOrObjectElements,21,47 -block_count,GrowFastSmiOrObjectElements,22,7049 -block_count,GrowFastSmiOrObjectElements,23,7001 +block_count,GrowFastSmiOrObjectElements,22,7047 +block_count,GrowFastSmiOrObjectElements,23,6999 block_count,GrowFastSmiOrObjectElements,24,47 block_count,GrowFastSmiOrObjectElements,25,302 block_count,GrowFastSmiOrObjectElements,26,0 @@ -8609,7 +8598,7 @@ block_count,ToNumber_Baseline,22,0 block_count,ToNumber_Baseline,23,0 block_count,ToNumber_Baseline,24,0 -block_count,ToNumeric_Baseline,0,28 +block_count,ToNumeric_Baseline,0,30 block_count,ToNumeric_Baseline,1,0 block_count,ToNumeric_Baseline,2,0 block_count,ToNumeric_Baseline,3,0 @@ -8637,10 +8626,10 @@ block_count,ToNumeric_Baseline,25,0 block_count,ToNumeric_Baseline,26,0 block_count,ToNumeric_Baseline,27,0 -block_count,ToNumeric_Baseline,28,28 -block_count,ToNumeric_Baseline,29,28 +block_count,ToNumeric_Baseline,28,30 +block_count,ToNumeric_Baseline,29,30 block_count,ToNumeric_Baseline,30,0 -block_count,ToNumeric_Baseline,31,28 +block_count,ToNumeric_Baseline,31,30 block_count,ToNumberConvertBigInt,0,2 block_count,ToNumberConvertBigInt,1,2 block_count,ToNumberConvertBigInt,2,0 @@ -8748,7 +8737,7 @@ block_count,KeyedLoadIC_PolymorphicName,1,0 block_count,KeyedLoadIC_PolymorphicName,2,0 block_count,KeyedLoadIC_PolymorphicName,3,0 -block_count,KeyedLoadIC_PolymorphicName,4,0 +block_count,KeyedLoadIC_PolymorphicName,4,1 block_count,KeyedLoadIC_PolymorphicName,5,0 block_count,KeyedLoadIC_PolymorphicName,6,0 block_count,KeyedLoadIC_PolymorphicName,7,0 @@ -9053,12 +9042,12 @@ block_count,KeyedStoreIC_Megamorphic,16,300 block_count,KeyedStoreIC_Megamorphic,17,252 block_count,KeyedStoreIC_Megamorphic,18,252 -block_count,KeyedStoreIC_Megamorphic,19,236 +block_count,KeyedStoreIC_Megamorphic,19,237 block_count,KeyedStoreIC_Megamorphic,20,0 block_count,KeyedStoreIC_Megamorphic,21,0 block_count,KeyedStoreIC_Megamorphic,22,0 -block_count,KeyedStoreIC_Megamorphic,23,236 -block_count,KeyedStoreIC_Megamorphic,24,185 +block_count,KeyedStoreIC_Megamorphic,23,237 +block_count,KeyedStoreIC_Megamorphic,24,186 block_count,KeyedStoreIC_Megamorphic,25,50 block_count,KeyedStoreIC_Megamorphic,26,3 block_count,KeyedStoreIC_Megamorphic,27,3 @@ -9066,7 +9055,7 @@ block_count,KeyedStoreIC_Megamorphic,29,0 block_count,KeyedStoreIC_Megamorphic,30,0 block_count,KeyedStoreIC_Megamorphic,31,47 -block_count,KeyedStoreIC_Megamorphic,32,16 +block_count,KeyedStoreIC_Megamorphic,32,15 block_count,KeyedStoreIC_Megamorphic,33,0 block_count,KeyedStoreIC_Megamorphic,34,47 block_count,KeyedStoreIC_Megamorphic,35,0 @@ -9138,7 +9127,7 @@ block_count,KeyedStoreIC_Megamorphic,101,0 block_count,KeyedStoreIC_Megamorphic,102,0 block_count,KeyedStoreIC_Megamorphic,103,101 -block_count,KeyedStoreIC_Megamorphic,104,100 +block_count,KeyedStoreIC_Megamorphic,104,101 block_count,KeyedStoreIC_Megamorphic,105,53 block_count,KeyedStoreIC_Megamorphic,106,0 block_count,KeyedStoreIC_Megamorphic,107,0 @@ -9219,10 +9208,10 @@ block_count,KeyedStoreIC_Megamorphic,182,98 block_count,KeyedStoreIC_Megamorphic,183,0 block_count,KeyedStoreIC_Megamorphic,184,98 -block_count,KeyedStoreIC_Megamorphic,185,49 -block_count,KeyedStoreIC_Megamorphic,186,49 +block_count,KeyedStoreIC_Megamorphic,185,50 +block_count,KeyedStoreIC_Megamorphic,186,47 block_count,KeyedStoreIC_Megamorphic,187,98 -block_count,KeyedStoreIC_Megamorphic,188,87 +block_count,KeyedStoreIC_Megamorphic,188,86 block_count,KeyedStoreIC_Megamorphic,189,11 block_count,KeyedStoreIC_Megamorphic,190,11 block_count,KeyedStoreIC_Megamorphic,191,11 @@ -9243,7 +9232,7 @@ block_count,KeyedStoreIC_Megamorphic,206,9 block_count,KeyedStoreIC_Megamorphic,207,36 block_count,KeyedStoreIC_Megamorphic,208,31 -block_count,KeyedStoreIC_Megamorphic,209,28 +block_count,KeyedStoreIC_Megamorphic,209,29 block_count,KeyedStoreIC_Megamorphic,210,27 block_count,KeyedStoreIC_Megamorphic,211,1 block_count,KeyedStoreIC_Megamorphic,212,2 @@ -9355,8 +9344,8 @@ block_count,KeyedStoreIC_Megamorphic,318,0 block_count,KeyedStoreIC_Megamorphic,319,0 block_count,KeyedStoreIC_Megamorphic,320,2 -block_count,KeyedStoreIC_Megamorphic,321,2 -block_count,KeyedStoreIC_Megamorphic,322,2 +block_count,KeyedStoreIC_Megamorphic,321,3 +block_count,KeyedStoreIC_Megamorphic,322,3 block_count,KeyedStoreIC_Megamorphic,323,0 block_count,KeyedStoreIC_Megamorphic,324,0 block_count,KeyedStoreIC_Megamorphic,325,0 @@ -11639,7 +11628,7 @@ block_count,LoadIC_StringWrapperLength,0,0 block_count,LoadIC_NoFeedback,0,45 block_count,LoadIC_NoFeedback,1,45 -block_count,LoadIC_NoFeedback,2,45 +block_count,LoadIC_NoFeedback,2,44 block_count,LoadIC_NoFeedback,3,39 block_count,LoadIC_NoFeedback,4,5 block_count,LoadIC_NoFeedback,5,5 @@ -11656,27 +11645,27 @@ block_count,LoadIC_NoFeedback,16,0 block_count,LoadIC_NoFeedback,17,0 block_count,LoadIC_NoFeedback,18,44 -block_count,LoadIC_NoFeedback,19,32 +block_count,LoadIC_NoFeedback,19,31 block_count,LoadIC_NoFeedback,20,30 block_count,LoadIC_NoFeedback,21,29 -block_count,LoadIC_NoFeedback,22,6 -block_count,LoadIC_NoFeedback,23,6 +block_count,LoadIC_NoFeedback,22,5 +block_count,LoadIC_NoFeedback,23,5 block_count,LoadIC_NoFeedback,24,0 -block_count,LoadIC_NoFeedback,25,6 +block_count,LoadIC_NoFeedback,25,5 block_count,LoadIC_NoFeedback,26,38 block_count,LoadIC_NoFeedback,27,38 block_count,LoadIC_NoFeedback,28,0 block_count,LoadIC_NoFeedback,29,38 block_count,LoadIC_NoFeedback,30,18 -block_count,LoadIC_NoFeedback,31,20 +block_count,LoadIC_NoFeedback,31,19 block_count,LoadIC_NoFeedback,32,38 block_count,LoadIC_NoFeedback,33,32 -block_count,LoadIC_NoFeedback,34,6 -block_count,LoadIC_NoFeedback,35,6 -block_count,LoadIC_NoFeedback,36,6 -block_count,LoadIC_NoFeedback,37,6 +block_count,LoadIC_NoFeedback,34,5 +block_count,LoadIC_NoFeedback,35,5 +block_count,LoadIC_NoFeedback,36,5 +block_count,LoadIC_NoFeedback,37,5 block_count,LoadIC_NoFeedback,38,0 -block_count,LoadIC_NoFeedback,39,6 +block_count,LoadIC_NoFeedback,39,5 block_count,LoadIC_NoFeedback,40,5 block_count,LoadIC_NoFeedback,41,0 block_count,LoadIC_NoFeedback,42,5 @@ -11687,10 +11676,10 @@ block_count,LoadIC_NoFeedback,47,23 block_count,LoadIC_NoFeedback,48,0 block_count,LoadIC_NoFeedback,49,23 -block_count,LoadIC_NoFeedback,50,4 +block_count,LoadIC_NoFeedback,50,3 block_count,LoadIC_NoFeedback,51,19 -block_count,LoadIC_NoFeedback,52,54 -block_count,LoadIC_NoFeedback,53,49 +block_count,LoadIC_NoFeedback,52,53 +block_count,LoadIC_NoFeedback,53,48 block_count,LoadIC_NoFeedback,54,44 block_count,LoadIC_NoFeedback,55,34 block_count,LoadIC_NoFeedback,56,10 @@ -11721,9 +11710,9 @@ block_count,LoadIC_NoFeedback,81,0 block_count,LoadIC_NoFeedback,82,1 block_count,LoadIC_NoFeedback,83,1 -block_count,LoadIC_NoFeedback,84,3 +block_count,LoadIC_NoFeedback,84,2 block_count,LoadIC_NoFeedback,85,2 -block_count,LoadIC_NoFeedback,86,1 +block_count,LoadIC_NoFeedback,86,0 block_count,LoadIC_NoFeedback,87,1 block_count,LoadIC_NoFeedback,88,0 block_count,LoadIC_NoFeedback,89,0 @@ -11732,7 +11721,7 @@ block_count,LoadIC_NoFeedback,92,1 block_count,LoadIC_NoFeedback,93,0 block_count,LoadIC_NoFeedback,94,1 -block_count,LoadIC_NoFeedback,95,18 +block_count,LoadIC_NoFeedback,95,17 block_count,LoadIC_NoFeedback,96,0 block_count,LoadIC_NoFeedback,97,0 block_count,LoadIC_NoFeedback,98,0 @@ -11781,24 +11770,24 @@ block_count,LoadIC_NoFeedback,141,0 block_count,LoadIC_NoFeedback,142,14 block_count,LoadIC_NoFeedback,143,14 -block_count,LoadIC_NoFeedback,144,20 -block_count,LoadIC_NoFeedback,145,20 +block_count,LoadIC_NoFeedback,144,19 +block_count,LoadIC_NoFeedback,145,19 block_count,LoadIC_NoFeedback,146,19 block_count,LoadIC_NoFeedback,147,19 -block_count,LoadIC_NoFeedback,148,19 -block_count,LoadIC_NoFeedback,149,19 +block_count,LoadIC_NoFeedback,148,18 +block_count,LoadIC_NoFeedback,149,18 block_count,LoadIC_NoFeedback,150,4 block_count,LoadIC_NoFeedback,151,4 block_count,LoadIC_NoFeedback,152,0 block_count,LoadIC_NoFeedback,153,4 -block_count,LoadIC_NoFeedback,154,25 -block_count,LoadIC_NoFeedback,155,25 +block_count,LoadIC_NoFeedback,154,24 +block_count,LoadIC_NoFeedback,155,24 block_count,LoadIC_NoFeedback,156,0 -block_count,LoadIC_NoFeedback,157,25 +block_count,LoadIC_NoFeedback,157,24 block_count,LoadIC_NoFeedback,158,11 block_count,LoadIC_NoFeedback,159,13 -block_count,LoadIC_NoFeedback,160,25 -block_count,LoadIC_NoFeedback,161,21 +block_count,LoadIC_NoFeedback,160,24 +block_count,LoadIC_NoFeedback,161,20 block_count,LoadIC_NoFeedback,162,4 block_count,LoadIC_NoFeedback,163,4 block_count,LoadIC_NoFeedback,164,4 @@ -11817,8 +11806,8 @@ block_count,LoadIC_NoFeedback,177,14 block_count,LoadIC_NoFeedback,178,0 block_count,LoadIC_NoFeedback,179,14 -block_count,LoadIC_NoFeedback,180,58 -block_count,LoadIC_NoFeedback,181,54 +block_count,LoadIC_NoFeedback,180,57 +block_count,LoadIC_NoFeedback,181,53 block_count,LoadIC_NoFeedback,182,48 block_count,LoadIC_NoFeedback,183,43 block_count,LoadIC_NoFeedback,184,5 @@ -11832,9 +11821,9 @@ block_count,LoadIC_NoFeedback,192,13 block_count,LoadIC_NoFeedback,193,4 block_count,LoadIC_NoFeedback,194,8 -block_count,LoadIC_NoFeedback,195,7 +block_count,LoadIC_NoFeedback,195,6 block_count,LoadIC_NoFeedback,196,0 -block_count,LoadIC_NoFeedback,197,7 +block_count,LoadIC_NoFeedback,197,6 block_count,LoadIC_NoFeedback,198,1 block_count,LoadIC_NoFeedback,199,0 block_count,LoadIC_NoFeedback,200,1 @@ -12014,7 +12003,7 @@ block_count,StoreIC_NoFeedback,68,0 block_count,StoreIC_NoFeedback,69,1 block_count,StoreIC_NoFeedback,70,1 -block_count,StoreIC_NoFeedback,71,1 +block_count,StoreIC_NoFeedback,71,0 block_count,StoreIC_NoFeedback,72,0 block_count,StoreIC_NoFeedback,73,0 block_count,StoreIC_NoFeedback,74,0 @@ -12760,10 +12749,10 @@ block_count,KeyedLoadIC_SloppyArguments,20,0 block_count,KeyedLoadIC_SloppyArguments,21,0 block_count,KeyedLoadIC_SloppyArguments,22,0 -block_count,StoreFastElementIC_InBounds,0,200 +block_count,StoreFastElementIC_InBounds,0,202 block_count,StoreFastElementIC_InBounds,1,0 -block_count,StoreFastElementIC_InBounds,2,2 -block_count,StoreFastElementIC_InBounds,3,2 +block_count,StoreFastElementIC_InBounds,2,3 +block_count,StoreFastElementIC_InBounds,3,3 block_count,StoreFastElementIC_InBounds,4,0 block_count,StoreFastElementIC_InBounds,5,0 block_count,StoreFastElementIC_InBounds,6,0 @@ -12771,17 +12760,17 @@ block_count,StoreFastElementIC_InBounds,8,0 block_count,StoreFastElementIC_InBounds,9,0 block_count,StoreFastElementIC_InBounds,10,0 -block_count,StoreFastElementIC_InBounds,11,2 -block_count,StoreFastElementIC_InBounds,12,2 +block_count,StoreFastElementIC_InBounds,11,3 +block_count,StoreFastElementIC_InBounds,12,3 block_count,StoreFastElementIC_InBounds,13,0 -block_count,StoreFastElementIC_InBounds,14,2 +block_count,StoreFastElementIC_InBounds,14,3 block_count,StoreFastElementIC_InBounds,15,0 -block_count,StoreFastElementIC_InBounds,16,2 -block_count,StoreFastElementIC_InBounds,17,2 +block_count,StoreFastElementIC_InBounds,16,3 +block_count,StoreFastElementIC_InBounds,17,3 block_count,StoreFastElementIC_InBounds,18,0 -block_count,StoreFastElementIC_InBounds,19,2 +block_count,StoreFastElementIC_InBounds,19,3 block_count,StoreFastElementIC_InBounds,20,0 -block_count,StoreFastElementIC_InBounds,21,2 +block_count,StoreFastElementIC_InBounds,21,3 block_count,StoreFastElementIC_InBounds,22,0 block_count,StoreFastElementIC_InBounds,23,2 block_count,StoreFastElementIC_InBounds,24,2 @@ -13000,7 +12989,7 @@ block_count,StoreFastElementIC_InBounds,237,3 block_count,StoreFastElementIC_InBounds,238,0 block_count,StoreFastElementIC_InBounds,239,3 -block_count,StoreFastElementIC_InBounds,240,14 +block_count,StoreFastElementIC_InBounds,240,15 block_count,StoreFastElementIC_InBounds,241,0 block_count,StoreFastElementIC_InBounds,242,0 block_count,StoreFastElementIC_InBounds,243,0 @@ -13008,20 +12997,20 @@ block_count,StoreFastElementIC_InBounds,245,0 block_count,StoreFastElementIC_InBounds,246,0 block_count,StoreFastElementIC_InBounds,247,0 -block_count,StoreFastElementIC_InBounds,248,14 -block_count,StoreFastElementIC_InBounds,249,14 -block_count,StoreFastElementIC_InBounds,250,14 +block_count,StoreFastElementIC_InBounds,248,15 +block_count,StoreFastElementIC_InBounds,249,15 +block_count,StoreFastElementIC_InBounds,250,15 block_count,StoreFastElementIC_InBounds,251,0 block_count,StoreFastElementIC_InBounds,252,0 block_count,StoreFastElementIC_InBounds,253,0 block_count,StoreFastElementIC_InBounds,254,0 block_count,StoreFastElementIC_InBounds,255,0 block_count,StoreFastElementIC_InBounds,256,0 -block_count,StoreFastElementIC_InBounds,257,14 -block_count,StoreFastElementIC_InBounds,258,14 -block_count,StoreFastElementIC_InBounds,259,14 +block_count,StoreFastElementIC_InBounds,257,15 +block_count,StoreFastElementIC_InBounds,258,15 +block_count,StoreFastElementIC_InBounds,259,15 block_count,StoreFastElementIC_InBounds,260,0 -block_count,StoreFastElementIC_InBounds,261,14 +block_count,StoreFastElementIC_InBounds,261,15 block_count,StoreFastElementIC_InBounds,262,0 block_count,StoreFastElementIC_InBounds,263,0 block_count,StoreFastElementIC_InBounds,264,3 @@ -13206,7 +13195,7 @@ block_count,StoreFastElementIC_InBounds,443,0 block_count,StoreFastElementIC_InBounds,444,0 block_count,StoreFastElementIC_InBounds,445,0 -block_count,StoreFastElementIC_InBounds,446,25 +block_count,StoreFastElementIC_InBounds,446,26 block_count,StoreFastElementIC_InBounds,447,0 block_count,StoreFastElementIC_InBounds,448,0 block_count,StoreFastElementIC_InBounds,449,0 @@ -13214,20 +13203,20 @@ block_count,StoreFastElementIC_InBounds,451,0 block_count,StoreFastElementIC_InBounds,452,0 block_count,StoreFastElementIC_InBounds,453,0 -block_count,StoreFastElementIC_InBounds,454,25 -block_count,StoreFastElementIC_InBounds,455,25 -block_count,StoreFastElementIC_InBounds,456,25 -block_count,StoreFastElementIC_InBounds,457,19 -block_count,StoreFastElementIC_InBounds,458,19 +block_count,StoreFastElementIC_InBounds,454,26 +block_count,StoreFastElementIC_InBounds,455,26 +block_count,StoreFastElementIC_InBounds,456,26 +block_count,StoreFastElementIC_InBounds,457,21 +block_count,StoreFastElementIC_InBounds,458,21 block_count,StoreFastElementIC_InBounds,459,0 block_count,StoreFastElementIC_InBounds,460,0 block_count,StoreFastElementIC_InBounds,461,0 -block_count,StoreFastElementIC_InBounds,462,19 +block_count,StoreFastElementIC_InBounds,462,21 block_count,StoreFastElementIC_InBounds,463,5 -block_count,StoreFastElementIC_InBounds,464,25 -block_count,StoreFastElementIC_InBounds,465,25 +block_count,StoreFastElementIC_InBounds,464,26 +block_count,StoreFastElementIC_InBounds,465,26 block_count,StoreFastElementIC_InBounds,466,0 -block_count,StoreFastElementIC_InBounds,467,25 +block_count,StoreFastElementIC_InBounds,467,26 block_count,StoreFastElementIC_InBounds,468,0 block_count,StoreFastElementIC_InBounds,469,0 block_count,StoreFastElementIC_InBounds,470,0 @@ -14109,7 +14098,7 @@ block_count,StoreFastElementIC_InBounds,1346,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,19 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,1,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,3,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,4,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,5,0 @@ -14117,17 +14106,17 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,7,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,8,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,9,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,10,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,11,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,10,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,11,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,12,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,13,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,13,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,14,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,15,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,16,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,15,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,16,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,17,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,18,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,19,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,20,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,20,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,21,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,22,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,23,0 @@ -14143,15 +14132,15 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,33,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,34,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,35,2 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,36,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,36,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,37,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,38,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,39,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,40,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,41,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,42,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,43,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,44,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,43,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,44,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,45,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,46,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,47,0 @@ -14170,11 +14159,11 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,60,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,61,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,62,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,63,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,63,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,64,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,65,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,66,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,67,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,65,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,66,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,67,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,68,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,69,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,70,0 @@ -14203,9 +14192,9 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,93,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,94,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,95,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,96,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,96,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,97,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,98,0 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,98,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,99,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,100,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,101,0 @@ -14361,7 +14350,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,251,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,252,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,253,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,254,11 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,254,12 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,255,13 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,256,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,257,13 @@ -19656,9 +19645,9 @@ block_count,ArrayConstructor,2,2 block_count,ArrayConstructor,3,3 block_count,ArrayConstructorImpl,0,229 -block_count,ArrayConstructorImpl,1,117 -block_count,ArrayConstructorImpl,2,6 -block_count,ArrayConstructorImpl,3,5 +block_count,ArrayConstructorImpl,1,118 +block_count,ArrayConstructorImpl,2,7 +block_count,ArrayConstructorImpl,3,6 block_count,ArrayConstructorImpl,4,1 block_count,ArrayConstructorImpl,5,4 block_count,ArrayConstructorImpl,6,0 @@ -19675,7 +19664,7 @@ block_count,ArrayConstructorImpl,17,0 block_count,ArrayConstructorImpl,18,2 block_count,ArrayConstructorImpl,19,0 -block_count,ArrayConstructorImpl,20,1 +block_count,ArrayConstructorImpl,20,2 block_count,ArrayConstructorImpl,21,0 block_count,ArrayConstructorImpl,22,0 block_count,ArrayConstructorImpl,23,0 @@ -19692,7 +19681,7 @@ block_count,ArrayConstructorImpl,34,0 block_count,ArrayConstructorImpl,35,0 block_count,ArrayConstructorImpl,36,0 -block_count,ArrayConstructorImpl,37,110 +block_count,ArrayConstructorImpl,37,111 block_count,ArrayConstructorImpl,38,110 block_count,ArrayConstructorImpl,39,0 block_count,ArrayConstructorImpl,40,110 @@ -19821,10 +19810,10 @@ block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,37,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,38,57 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,39,57 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,40,52 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,40,53 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,41,0 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,42,52 -block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,43,52 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,42,53 +block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,43,53 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,44,0 block_count,ArraySingleArgumentConstructor_HoleySmi_DisableAllocationSites,45,0 block_count,ArraySingleArgumentConstructor_Holey_DisableAllocationSites,0,2 @@ -19873,13 +19862,13 @@ block_count,ArraySingleArgumentConstructor_Holey_DisableAllocationSites,43,0 block_count,ArraySingleArgumentConstructor_Holey_DisableAllocationSites,44,0 block_count,ArraySingleArgumentConstructor_Holey_DisableAllocationSites,45,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,0,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,0,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,1,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,2,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,2,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,3,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,4,1 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,5,1 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,6,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,4,2 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,5,2 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,6,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,7,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,8,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,9,0 @@ -19895,25 +19884,25 @@ block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,19,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,20,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,21,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,22,1 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,23,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,22,2 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,23,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,24,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,25,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,25,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,26,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,27,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,28,1 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,29,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,28,2 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,29,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,30,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,31,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,31,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,32,0 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,33,1 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,34,2 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,35,0 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,35,1 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,36,1 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,37,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,37,2 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,38,1 block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,39,0 -block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,40,1 +block_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,40,2 block_count,ArrayIncludesSmi,0,0 block_count,ArrayIncludesSmi,1,0 block_count,ArrayIncludesSmi,2,0 @@ -20797,7 +20786,7 @@ block_count,ArrayPrototypePush,47,0 block_count,ArrayPrototypePush,48,6 block_count,ArrayPrototypePush,49,6 -block_count,ArrayPrototypePush,50,7 +block_count,ArrayPrototypePush,50,6 block_count,ArrayPrototypePush,51,6 block_count,ArrayPrototypePush,52,6 block_count,ArrayPrototypePush,53,0 @@ -20890,16 +20879,16 @@ block_count,ArrayPrototypePush,140,21 block_count,ArrayPrototypePush,141,0 block_count,ArrayPrototypePush,142,21 -block_count,ArrayPrototypePush,143,241 -block_count,ArrayPrototypePush,144,219 +block_count,ArrayPrototypePush,143,242 +block_count,ArrayPrototypePush,144,220 block_count,ArrayPrototypePush,145,21 block_count,ArrayPrototypePush,146,21 block_count,ArrayPrototypePush,147,0 block_count,ArrayPrototypePush,148,20 block_count,ArrayPrototypePush,149,21 block_count,ArrayPrototypePush,150,1 -block_count,ArrayPrototypePush,151,255 -block_count,ArrayPrototypePush,152,254 +block_count,ArrayPrototypePush,151,257 +block_count,ArrayPrototypePush,152,255 block_count,ArrayPrototypePush,153,1 block_count,ArrayPrototypePush,154,20 block_count,ArrayPrototypePush,155,21 @@ -20909,7 +20898,7 @@ block_count,ArrayPrototypePush,159,190 block_count,ArrayPrototypePush,160,205 block_count,ArrayPrototypePush,161,205 -block_count,ArrayPrototypePush,162,15 +block_count,ArrayPrototypePush,162,14 block_count,ArrayPrototypePush,163,190 block_count,ArrayPrototypePush,164,0 block_count,ArrayPrototypePush,165,0 @@ -21215,14 +21204,14 @@ block_count,ExtractFastJSArray,23,0 block_count,ExtractFastJSArray,24,0 block_count,ExtractFastJSArray,25,115 -block_count,ExtractFastJSArray,26,114 +block_count,ExtractFastJSArray,26,115 block_count,ExtractFastJSArray,27,0 block_count,ExtractFastJSArray,28,0 block_count,ExtractFastJSArray,29,0 block_count,ExtractFastJSArray,30,0 block_count,ExtractFastJSArray,31,0 -block_count,ExtractFastJSArray,32,4 -block_count,ExtractFastJSArray,33,4 +block_count,ExtractFastJSArray,32,3 +block_count,ExtractFastJSArray,33,3 block_count,ExtractFastJSArray,34,0 block_count,ExtractFastJSArray,35,0 block_count,ExtractFastJSArray,36,0 @@ -21551,8 +21540,8 @@ block_count,CreateObjectFromSlowBoilerplateHelper,146,49 block_count,CreateObjectFromSlowBoilerplateHelper,147,49 block_count,CreateObjectFromSlowBoilerplateHelper,148,48 -block_count,CreateObjectFromSlowBoilerplateHelper,149,1 -block_count,CreateObjectFromSlowBoilerplateHelper,150,1 +block_count,CreateObjectFromSlowBoilerplateHelper,149,0 +block_count,CreateObjectFromSlowBoilerplateHelper,150,0 block_count,CreateObjectFromSlowBoilerplateHelper,151,0 block_count,CreateObjectFromSlowBoilerplateHelper,152,0 block_count,CreateObjectFromSlowBoilerplateHelper,153,0 @@ -21563,7 +21552,7 @@ block_count,CreateObjectFromSlowBoilerplateHelper,158,0 block_count,CreateObjectFromSlowBoilerplateHelper,159,0 block_count,CreateObjectFromSlowBoilerplateHelper,160,0 -block_count,CreateObjectFromSlowBoilerplateHelper,161,1 +block_count,CreateObjectFromSlowBoilerplateHelper,161,0 block_count,CreateObjectFromSlowBoilerplateHelper,162,49 block_count,CreateObjectFromSlowBoilerplateHelper,163,0 block_count,CreateObjectFromSlowBoilerplateHelper,164,0 @@ -21885,7 +21874,7 @@ block_count,ArrayIteratorPrototypeNext,208,0 block_count,ArrayIteratorPrototypeNext,209,0 block_count,ArrayIteratorPrototypeNext,210,0 -block_count,ArrayIteratorPrototypeNext,211,64 +block_count,ArrayIteratorPrototypeNext,211,63 block_count,ArrayIteratorPrototypeNext,212,0 block_count,ArrayIteratorPrototypeNext,213,0 block_count,ArrayIteratorPrototypeNext,214,0 @@ -22348,14 +22337,14 @@ block_count,GlobalIsNaN,8,0 block_count,GlobalIsNaN,9,0 block_count,GlobalIsNaN,10,0 -block_count,LoadIC,0,2442 -block_count,LoadIC,1,2441 +block_count,LoadIC,0,2482 +block_count,LoadIC,1,2481 block_count,LoadIC,2,0 -block_count,LoadIC,3,2442 -block_count,LoadIC,4,2442 -block_count,LoadIC,5,756 +block_count,LoadIC,3,2482 +block_count,LoadIC,4,2482 +block_count,LoadIC,5,767 block_count,LoadIC,6,0 -block_count,LoadIC,7,755 +block_count,LoadIC,7,767 block_count,LoadIC,8,129 block_count,LoadIC,9,1 block_count,LoadIC,10,1 @@ -22374,31 +22363,31 @@ block_count,LoadIC,23,128 block_count,LoadIC,24,0 block_count,LoadIC,25,128 -block_count,LoadIC,26,109 -block_count,LoadIC,27,108 +block_count,LoadIC,26,108 +block_count,LoadIC,27,107 block_count,LoadIC,28,0 -block_count,LoadIC,29,18 -block_count,LoadIC,30,19 -block_count,LoadIC,31,17 -block_count,LoadIC,32,17 +block_count,LoadIC,29,19 +block_count,LoadIC,30,20 +block_count,LoadIC,31,19 +block_count,LoadIC,32,19 block_count,LoadIC,33,0 block_count,LoadIC,34,1 -block_count,LoadIC,35,625 -block_count,LoadIC,36,984 -block_count,LoadIC,37,359 -block_count,LoadIC,38,358 +block_count,LoadIC,35,637 +block_count,LoadIC,36,992 +block_count,LoadIC,37,355 +block_count,LoadIC,38,354 block_count,LoadIC,39,0 -block_count,LoadIC,40,625 -block_count,LoadIC,41,1685 -block_count,LoadIC,42,2438 -block_count,LoadIC,43,855 -block_count,LoadIC,44,850 -block_count,LoadIC,45,617 -block_count,LoadIC,46,617 +block_count,LoadIC,40,636 +block_count,LoadIC,41,1714 +block_count,LoadIC,42,2478 +block_count,LoadIC,43,858 +block_count,LoadIC,44,853 +block_count,LoadIC,45,620 +block_count,LoadIC,46,620 block_count,LoadIC,47,0 -block_count,LoadIC,48,617 +block_count,LoadIC,48,620 block_count,LoadIC,49,0 -block_count,LoadIC,50,617 +block_count,LoadIC,50,620 block_count,LoadIC,51,78 block_count,LoadIC,52,36 block_count,LoadIC,53,36 @@ -22471,25 +22460,25 @@ block_count,LoadIC,120,0 block_count,LoadIC,121,41 block_count,LoadIC,122,0 -block_count,LoadIC,123,539 -block_count,LoadIC,124,615 -block_count,LoadIC,125,615 -block_count,LoadIC,126,567 -block_count,LoadIC,127,567 +block_count,LoadIC,123,541 +block_count,LoadIC,124,618 +block_count,LoadIC,125,618 +block_count,LoadIC,126,570 +block_count,LoadIC,127,570 block_count,LoadIC,128,0 block_count,LoadIC,129,47 -block_count,LoadIC,130,615 +block_count,LoadIC,130,618 block_count,LoadIC,131,0 block_count,LoadIC,132,232 block_count,LoadIC,133,4 block_count,LoadIC,134,4 block_count,LoadIC,135,0 -block_count,LoadIC,136,1582 -block_count,LoadIC,137,2198 -block_count,LoadIC,138,882 -block_count,LoadIC,139,404 -block_count,LoadIC,140,356 -block_count,LoadIC,141,117 +block_count,LoadIC,136,1620 +block_count,LoadIC,137,2238 +block_count,LoadIC,138,885 +block_count,LoadIC,139,405 +block_count,LoadIC,140,357 +block_count,LoadIC,141,118 block_count,LoadIC,142,28 block_count,LoadIC,143,2 block_count,LoadIC,144,2 @@ -22567,7 +22556,7 @@ block_count,LoadIC,216,238 block_count,LoadIC,217,339 block_count,LoadIC,218,339 -block_count,LoadIC,219,100 +block_count,LoadIC,219,101 block_count,LoadIC,220,238 block_count,LoadIC,221,0 block_count,LoadIC,222,0 @@ -22617,19 +22606,19 @@ block_count,LoadIC,266,0 block_count,LoadIC,267,238 block_count,LoadIC,268,47 -block_count,LoadIC,269,477 -block_count,LoadIC,270,1316 -block_count,LoadIC,271,1316 -block_count,LoadIC,272,337 -block_count,LoadIC,273,978 -block_count,LoadIC,274,1316 -block_count,LoadIC,275,1271 -block_count,LoadIC,276,44 -block_count,LoadIC,277,44 -block_count,LoadIC,278,44 +block_count,LoadIC,269,480 +block_count,LoadIC,270,1353 +block_count,LoadIC,271,1353 +block_count,LoadIC,272,358 +block_count,LoadIC,273,994 +block_count,LoadIC,274,1353 +block_count,LoadIC,275,1307 +block_count,LoadIC,276,45 +block_count,LoadIC,277,45 +block_count,LoadIC,278,45 block_count,LoadIC,279,0 -block_count,LoadIC,280,44 -block_count,LoadIC,281,44 +block_count,LoadIC,280,45 +block_count,LoadIC,281,45 block_count,LoadIC,282,0 block_count,LoadIC,283,0 block_count,LoadIC,284,0 @@ -22671,7 +22660,7 @@ block_count,LoadIC,320,0 block_count,LoadIC,321,0 block_count,LoadIC,322,0 -block_count,LoadIC,323,3 +block_count,LoadIC,323,4 block_count,LoadIC_Megamorphic,0,10000 block_count,LoadIC_Megamorphic,1,9998 block_count,LoadIC_Megamorphic,2,1 @@ -22679,15 +22668,15 @@ block_count,LoadIC_Megamorphic,4,10000 block_count,LoadIC_Megamorphic,5,0 block_count,LoadIC_Megamorphic,6,10000 -block_count,LoadIC_Megamorphic,7,8495 -block_count,LoadIC_Megamorphic,8,8345 -block_count,LoadIC_Megamorphic,9,150 -block_count,LoadIC_Megamorphic,10,1504 -block_count,LoadIC_Megamorphic,11,1654 -block_count,LoadIC_Megamorphic,12,1645 -block_count,LoadIC_Megamorphic,13,1644 +block_count,LoadIC_Megamorphic,7,8298 +block_count,LoadIC_Megamorphic,8,8201 +block_count,LoadIC_Megamorphic,9,96 +block_count,LoadIC_Megamorphic,10,1701 +block_count,LoadIC_Megamorphic,11,1798 +block_count,LoadIC_Megamorphic,12,1789 +block_count,LoadIC_Megamorphic,13,1787 block_count,LoadIC_Megamorphic,14,1 -block_count,LoadIC_Megamorphic,15,9 +block_count,LoadIC_Megamorphic,15,8 block_count,LoadIC_Megamorphic,16,9989 block_count,LoadIC_Megamorphic,17,3650 block_count,LoadIC_Megamorphic,18,3650 @@ -22769,7 +22758,7 @@ block_count,LoadIC_Megamorphic,94,0 block_count,LoadIC_Megamorphic,95,3 block_count,LoadIC_Megamorphic,96,0 -block_count,LoadIC_Megamorphic,97,3630 +block_count,LoadIC_Megamorphic,97,3629 block_count,LoadIC_Megamorphic,98,3638 block_count,LoadIC_Megamorphic,99,3636 block_count,LoadIC_Megamorphic,100,2859 @@ -22782,7 +22771,7 @@ block_count,LoadIC_Megamorphic,107,0 block_count,LoadIC_Megamorphic,108,0 block_count,LoadIC_Megamorphic,109,0 -block_count,LoadIC_Megamorphic,110,6338 +block_count,LoadIC_Megamorphic,110,6339 block_count,LoadIC_Megamorphic,111,9975 block_count,LoadIC_Megamorphic,112,4340 block_count,LoadIC_Megamorphic,113,2279 @@ -22857,7 +22846,7 @@ block_count,LoadIC_Megamorphic,182,0 block_count,LoadIC_Megamorphic,183,0 block_count,LoadIC_Megamorphic,184,690 -block_count,LoadIC_Megamorphic,185,796 +block_count,LoadIC_Megamorphic,185,795 block_count,LoadIC_Megamorphic,186,6 block_count,LoadIC_Megamorphic,187,6 block_count,LoadIC_Megamorphic,188,0 @@ -22916,11 +22905,11 @@ block_count,LoadIC_Megamorphic,241,6 block_count,LoadIC_Megamorphic,242,777 block_count,LoadIC_Megamorphic,243,2060 -block_count,LoadIC_Megamorphic,244,5634 -block_count,LoadIC_Megamorphic,245,5634 +block_count,LoadIC_Megamorphic,244,5635 +block_count,LoadIC_Megamorphic,245,5635 block_count,LoadIC_Megamorphic,246,298 block_count,LoadIC_Megamorphic,247,5336 -block_count,LoadIC_Megamorphic,248,5634 +block_count,LoadIC_Megamorphic,248,5635 block_count,LoadIC_Megamorphic,249,5613 block_count,LoadIC_Megamorphic,250,21 block_count,LoadIC_Megamorphic,251,21 @@ -22970,10 +22959,10 @@ block_count,LoadIC_Megamorphic,295,0 block_count,LoadIC_Megamorphic,296,0 block_count,LoadIC_Megamorphic,297,10 -block_count,LoadIC_Noninlined,0,3 +block_count,LoadIC_Noninlined,0,2 block_count,LoadIC_Noninlined,1,2 block_count,LoadIC_Noninlined,2,0 -block_count,LoadIC_Noninlined,3,3 +block_count,LoadIC_Noninlined,3,2 block_count,LoadIC_Noninlined,4,1 block_count,LoadIC_Noninlined,5,1 block_count,LoadIC_Noninlined,6,0 @@ -23282,15 +23271,15 @@ block_count,LoadIC_Noninlined,309,0 block_count,LoadIC_Noninlined,310,0 block_count,LoadIC_Noninlined,311,1 -block_count,LoadICTrampoline,0,305 -block_count,LoadICTrampoline,1,305 +block_count,LoadICTrampoline,0,308 +block_count,LoadICTrampoline,1,308 block_count,LoadICTrampoline,2,0 -block_count,LoadICTrampoline,3,305 -block_count,LoadICBaseline,0,1802 -block_count,LoadICTrampoline_Megamorphic,0,5824 -block_count,LoadICTrampoline_Megamorphic,1,5824 +block_count,LoadICTrampoline,3,308 +block_count,LoadICBaseline,0,1840 +block_count,LoadICTrampoline_Megamorphic,0,5826 +block_count,LoadICTrampoline_Megamorphic,1,5826 block_count,LoadICTrampoline_Megamorphic,2,0 -block_count,LoadICTrampoline_Megamorphic,3,5824 +block_count,LoadICTrampoline_Megamorphic,3,5826 block_count,LoadSuperIC,0,2 block_count,LoadSuperIC,1,2 block_count,LoadSuperIC,2,2 @@ -23887,16 +23876,16 @@ block_count,LoadSuperIC,593,0 block_count,LoadSuperIC,594,0 block_count,LoadSuperICBaseline,0,2 -block_count,KeyedLoadIC,0,332 -block_count,KeyedLoadIC,1,332 +block_count,KeyedLoadIC,0,339 +block_count,KeyedLoadIC,1,339 block_count,KeyedLoadIC,2,0 -block_count,KeyedLoadIC,3,332 -block_count,KeyedLoadIC,4,332 -block_count,KeyedLoadIC,5,329 -block_count,KeyedLoadIC,6,36 +block_count,KeyedLoadIC,3,339 +block_count,KeyedLoadIC,4,339 +block_count,KeyedLoadIC,5,336 +block_count,KeyedLoadIC,6,37 block_count,KeyedLoadIC,7,0 block_count,KeyedLoadIC,8,36 -block_count,KeyedLoadIC,9,20 +block_count,KeyedLoadIC,9,21 block_count,KeyedLoadIC,10,1 block_count,KeyedLoadIC,11,0 block_count,KeyedLoadIC,12,0 @@ -23936,15 +23925,15 @@ block_count,KeyedLoadIC,46,0 block_count,KeyedLoadIC,47,0 block_count,KeyedLoadIC,48,0 -block_count,KeyedLoadIC,49,19 +block_count,KeyedLoadIC,49,20 block_count,KeyedLoadIC,50,15 block_count,KeyedLoadIC,51,24 block_count,KeyedLoadIC,52,9 block_count,KeyedLoadIC,53,9 block_count,KeyedLoadIC,54,0 block_count,KeyedLoadIC,55,15 -block_count,KeyedLoadIC,56,293 -block_count,KeyedLoadIC,57,309 +block_count,KeyedLoadIC,56,299 +block_count,KeyedLoadIC,57,315 block_count,KeyedLoadIC,58,2 block_count,KeyedLoadIC,59,2 block_count,KeyedLoadIC,60,0 @@ -24038,8 +24027,8 @@ block_count,KeyedLoadIC,148,0 block_count,KeyedLoadIC,149,0 block_count,KeyedLoadIC,150,0 -block_count,KeyedLoadIC,151,306 -block_count,KeyedLoadIC,152,306 +block_count,KeyedLoadIC,151,313 +block_count,KeyedLoadIC,152,313 block_count,KeyedLoadIC,153,3 block_count,KeyedLoadIC,154,0 block_count,KeyedLoadIC,155,0 @@ -24274,8 +24263,8 @@ block_count,KeyedLoadIC,384,0 block_count,KeyedLoadIC,385,0 block_count,KeyedLoadIC,386,0 -block_count,KeyedLoadIC,387,1 -block_count,KeyedLoadIC,388,1 +block_count,KeyedLoadIC,387,2 +block_count,KeyedLoadIC,388,2 block_count,KeyedLoadIC,389,0 block_count,KeyedLoadIC,390,2 block_count,KeyedLoadIC,391,0 @@ -24293,7 +24282,7 @@ block_count,KeyedLoadIC,403,3 block_count,KeyedLoadIC,404,3 block_count,KeyedLoadIC,405,0 -block_count,KeyedLoadIC,406,2 +block_count,KeyedLoadIC,406,3 block_count,KeyedLoadIC,407,3 block_count,KeyedLoadIC,408,0 block_count,KeyedLoadIC,409,0 @@ -24307,7 +24296,7 @@ block_count,KeyedLoadIC,417,0 block_count,KeyedLoadIC,418,0 block_count,KeyedLoadIC,419,0 -block_count,KeyedLoadIC,420,303 +block_count,KeyedLoadIC,420,310 block_count,KeyedLoadIC,421,0 block_count,KeyedLoadIC,422,0 block_count,KeyedLoadIC,423,0 @@ -24320,30 +24309,30 @@ block_count,KeyedLoadIC,430,0 block_count,KeyedLoadIC,431,0 block_count,KeyedLoadIC,432,0 -block_count,KeyedLoadIC,433,303 -block_count,KeyedLoadIC,434,303 -block_count,KeyedLoadIC,435,303 -block_count,KeyedLoadIC,436,171 +block_count,KeyedLoadIC,433,309 +block_count,KeyedLoadIC,434,309 +block_count,KeyedLoadIC,435,310 +block_count,KeyedLoadIC,436,176 block_count,KeyedLoadIC,437,5 -block_count,KeyedLoadIC,438,166 -block_count,KeyedLoadIC,439,171 +block_count,KeyedLoadIC,438,171 +block_count,KeyedLoadIC,439,176 block_count,KeyedLoadIC,440,0 -block_count,KeyedLoadIC,441,171 +block_count,KeyedLoadIC,441,175 block_count,KeyedLoadIC,442,0 -block_count,KeyedLoadIC,443,10 +block_count,KeyedLoadIC,443,14 block_count,KeyedLoadIC,444,99 block_count,KeyedLoadIC,445,0 block_count,KeyedLoadIC,446,0 block_count,KeyedLoadIC,447,0 block_count,KeyedLoadIC,448,0 -block_count,KeyedLoadIC,449,110 +block_count,KeyedLoadIC,449,114 block_count,KeyedLoadIC,450,6 -block_count,KeyedLoadIC,451,29 +block_count,KeyedLoadIC,451,30 block_count,KeyedLoadIC,452,0 block_count,KeyedLoadIC,453,0 block_count,KeyedLoadIC,454,0 block_count,KeyedLoadIC,455,36 -block_count,KeyedLoadIC,456,34 +block_count,KeyedLoadIC,456,35 block_count,KeyedLoadIC,457,1 block_count,KeyedLoadIC,458,11 block_count,KeyedLoadIC,459,0 @@ -24355,8 +24344,8 @@ block_count,KeyedLoadIC,465,13 block_count,KeyedLoadIC,466,13 block_count,KeyedLoadIC,467,0 -block_count,KeyedLoadIC,468,132 -block_count,KeyedLoadIC,469,132 +block_count,KeyedLoadIC,468,133 +block_count,KeyedLoadIC,469,133 block_count,KeyedLoadIC,470,0 block_count,KeyedLoadIC,471,0 block_count,KeyedLoadIC,472,0 @@ -24379,18 +24368,18 @@ block_count,KeyedLoadIC,489,0 block_count,KeyedLoadIC,490,0 block_count,KeyedLoadIC,491,0 -block_count,KeyedLoadIC,492,132 -block_count,KeyedLoadIC,493,132 +block_count,KeyedLoadIC,492,133 +block_count,KeyedLoadIC,493,133 block_count,KeyedLoadIC,494,0 -block_count,KeyedLoadIC,495,132 +block_count,KeyedLoadIC,495,133 block_count,KeyedLoadIC,496,0 -block_count,KeyedLoadIC,497,14 +block_count,KeyedLoadIC,497,15 block_count,KeyedLoadIC,498,0 block_count,KeyedLoadIC,499,0 block_count,KeyedLoadIC,500,3 block_count,KeyedLoadIC,501,0 block_count,KeyedLoadIC,502,0 -block_count,KeyedLoadIC,503,92 +block_count,KeyedLoadIC,503,93 block_count,KeyedLoadIC,504,19 block_count,KeyedLoadIC,505,0 block_count,KeyedLoadIC,506,0 @@ -24450,8 +24439,8 @@ block_count,KeyedLoadIC,560,0 block_count,KeyedLoadIC,561,0 block_count,KeyedLoadIC,562,0 -block_count,KeyedLoadIC,563,92 -block_count,KeyedLoadIC,564,91 +block_count,KeyedLoadIC,563,93 +block_count,KeyedLoadIC,564,92 block_count,KeyedLoadIC,565,0 block_count,KeyedLoadIC,566,0 block_count,KeyedLoadIC,567,0 @@ -25196,22 +25185,22 @@ block_count,KeyedLoadIC_Megamorphic,8,0 block_count,KeyedLoadIC_Megamorphic,9,3 block_count,KeyedLoadIC_Megamorphic,10,2063 -block_count,KeyedLoadIC_Megamorphic,11,2061 +block_count,KeyedLoadIC_Megamorphic,11,2062 block_count,KeyedLoadIC_Megamorphic,12,47 block_count,KeyedLoadIC_Megamorphic,13,42 block_count,KeyedLoadIC_Megamorphic,14,5 -block_count,KeyedLoadIC_Megamorphic,15,2013 -block_count,KeyedLoadIC_Megamorphic,16,2013 +block_count,KeyedLoadIC_Megamorphic,15,2014 +block_count,KeyedLoadIC_Megamorphic,16,2014 block_count,KeyedLoadIC_Megamorphic,17,1917 block_count,KeyedLoadIC_Megamorphic,18,1917 -block_count,KeyedLoadIC_Megamorphic,19,1809 +block_count,KeyedLoadIC_Megamorphic,19,1813 block_count,KeyedLoadIC_Megamorphic,20,0 block_count,KeyedLoadIC_Megamorphic,21,0 block_count,KeyedLoadIC_Megamorphic,22,0 -block_count,KeyedLoadIC_Megamorphic,23,1809 -block_count,KeyedLoadIC_Megamorphic,24,972 +block_count,KeyedLoadIC_Megamorphic,23,1813 +block_count,KeyedLoadIC_Megamorphic,24,975 block_count,KeyedLoadIC_Megamorphic,25,837 -block_count,KeyedLoadIC_Megamorphic,26,107 +block_count,KeyedLoadIC_Megamorphic,26,104 block_count,KeyedLoadIC_Megamorphic,27,0 block_count,KeyedLoadIC_Megamorphic,28,96 block_count,KeyedLoadIC_Megamorphic,29,42 @@ -25410,7 +25399,7 @@ block_count,KeyedLoadIC_Megamorphic,222,776 block_count,KeyedLoadIC_Megamorphic,223,0 block_count,KeyedLoadIC_Megamorphic,224,776 -block_count,KeyedLoadIC_Megamorphic,225,30 +block_count,KeyedLoadIC_Megamorphic,225,29 block_count,KeyedLoadIC_Megamorphic,226,746 block_count,KeyedLoadIC_Megamorphic,227,3030 block_count,KeyedLoadIC_Megamorphic,228,2960 @@ -25571,14 +25560,14 @@ block_count,KeyedLoadIC_Megamorphic,383,381 block_count,KeyedLoadIC_Megamorphic,384,9 block_count,KeyedLoadIC_Megamorphic,385,371 -block_count,KeyedLoadIC_Megamorphic,386,1003 -block_count,KeyedLoadIC_Megamorphic,387,860 -block_count,KeyedLoadIC_Megamorphic,388,723 +block_count,KeyedLoadIC_Megamorphic,386,1004 +block_count,KeyedLoadIC_Megamorphic,387,861 +block_count,KeyedLoadIC_Megamorphic,388,724 block_count,KeyedLoadIC_Megamorphic,389,632 block_count,KeyedLoadIC_Megamorphic,390,91 block_count,KeyedLoadIC_Megamorphic,391,136 block_count,KeyedLoadIC_Megamorphic,392,143 -block_count,KeyedLoadIC_Megamorphic,393,100 +block_count,KeyedLoadIC_Megamorphic,393,101 block_count,KeyedLoadIC_Megamorphic,394,68 block_count,KeyedLoadIC_Megamorphic,395,32 block_count,KeyedLoadIC_Megamorphic,396,19 @@ -25603,13 +25592,13 @@ block_count,KeyedLoadIC_Megamorphic,415,111 block_count,KeyedLoadIC_Megamorphic,416,0 block_count,KeyedLoadIC_Megamorphic,417,111 -block_count,KeyedLoadIC_Megamorphic,418,80 -block_count,KeyedLoadIC_Megamorphic,419,80 +block_count,KeyedLoadIC_Megamorphic,418,83 +block_count,KeyedLoadIC_Megamorphic,419,83 block_count,KeyedLoadIC_Megamorphic,420,0 -block_count,KeyedLoadIC_Megamorphic,421,30 -block_count,KeyedLoadIC_Megamorphic,422,30 -block_count,KeyedLoadIC_Megamorphic,423,14 -block_count,KeyedLoadIC_Megamorphic,424,14 +block_count,KeyedLoadIC_Megamorphic,421,28 +block_count,KeyedLoadIC_Megamorphic,422,28 +block_count,KeyedLoadIC_Megamorphic,423,12 +block_count,KeyedLoadIC_Megamorphic,424,12 block_count,KeyedLoadIC_Megamorphic,425,0 block_count,KeyedLoadIC_Megamorphic,426,15 block_count,KeyedLoadIC_Megamorphic,427,95 @@ -26123,9 +26112,9 @@ block_count,KeyedLoadIC_Megamorphic,935,0 block_count,KeyedLoadIC_Megamorphic,936,0 block_count,KeyedLoadIC_Megamorphic,937,320 -block_count,KeyedLoadIC_Megamorphic,938,323 +block_count,KeyedLoadIC_Megamorphic,938,324 block_count,KeyedLoadIC_Megamorphic,939,420 -block_count,KeyedLoadIC_Megamorphic,940,410 +block_count,KeyedLoadIC_Megamorphic,940,411 block_count,KeyedLoadIC_Megamorphic,941,399 block_count,KeyedLoadIC_Megamorphic,942,75 block_count,KeyedLoadIC_Megamorphic,943,324 @@ -26139,7 +26128,7 @@ block_count,KeyedLoadIC_Megamorphic,951,0 block_count,KeyedLoadIC_Megamorphic,952,0 block_count,KeyedLoadIC_Megamorphic,953,0 -block_count,KeyedLoadIC_Megamorphic,954,317 +block_count,KeyedLoadIC_Megamorphic,954,318 block_count,KeyedLoadIC_Megamorphic,955,0 block_count,KeyedLoadIC_Megamorphic,956,71 block_count,KeyedLoadIC_Megamorphic,957,0 @@ -26327,18 +26316,18 @@ block_count,KeyedLoadICTrampoline,1,1 block_count,KeyedLoadICTrampoline,2,0 block_count,KeyedLoadICTrampoline,3,1 -block_count,KeyedLoadICBaseline,0,309 +block_count,KeyedLoadICBaseline,0,317 block_count,EnumeratedKeyedLoadICBaseline,0,3 block_count,KeyedLoadICTrampoline_Megamorphic,0,1091 block_count,KeyedLoadICTrampoline_Megamorphic,1,1091 block_count,KeyedLoadICTrampoline_Megamorphic,2,0 block_count,KeyedLoadICTrampoline_Megamorphic,3,1091 -block_count,StoreGlobalIC,0,680 -block_count,StoreGlobalIC,1,680 -block_count,StoreGlobalIC,2,680 -block_count,StoreGlobalIC,3,680 -block_count,StoreGlobalIC,4,680 -block_count,StoreGlobalIC,5,680 +block_count,StoreGlobalIC,0,379 +block_count,StoreGlobalIC,1,379 +block_count,StoreGlobalIC,2,379 +block_count,StoreGlobalIC,3,379 +block_count,StoreGlobalIC,4,379 +block_count,StoreGlobalIC,5,379 block_count,StoreGlobalIC,6,1 block_count,StoreGlobalIC,7,0 block_count,StoreGlobalIC,8,0 @@ -26348,7 +26337,7 @@ block_count,StoreGlobalIC,12,1 block_count,StoreGlobalIC,13,0 block_count,StoreGlobalIC,14,1 -block_count,StoreGlobalIC,15,678 +block_count,StoreGlobalIC,15,377 block_count,StoreGlobalIC,16,0 block_count,StoreGlobalIC,17,0 block_count,StoreGlobalIC,18,0 @@ -26855,44 +26844,44 @@ block_count,StoreGlobalIC,519,0 block_count,StoreGlobalIC,520,0 block_count,StoreGlobalIC,521,0 -block_count,StoreGlobalICTrampoline,0,186 -block_count,StoreGlobalICTrampoline,1,186 +block_count,StoreGlobalICTrampoline,0,0 +block_count,StoreGlobalICTrampoline,1,0 block_count,StoreGlobalICTrampoline,2,0 -block_count,StoreGlobalICTrampoline,3,186 +block_count,StoreGlobalICTrampoline,3,0 block_count,StoreGlobalICBaseline,0,1 -block_count,StoreIC,0,267 -block_count,StoreIC,1,267 +block_count,StoreIC,0,271 +block_count,StoreIC,1,271 block_count,StoreIC,2,0 -block_count,StoreIC,3,267 -block_count,StoreIC,4,267 -block_count,StoreIC,5,260 -block_count,StoreIC,6,98 +block_count,StoreIC,3,271 +block_count,StoreIC,4,271 +block_count,StoreIC,5,265 +block_count,StoreIC,6,101 block_count,StoreIC,7,0 -block_count,StoreIC,8,98 -block_count,StoreIC,9,24 +block_count,StoreIC,8,101 +block_count,StoreIC,9,25 block_count,StoreIC,10,0 -block_count,StoreIC,11,23 -block_count,StoreIC,12,23 +block_count,StoreIC,11,24 +block_count,StoreIC,12,24 block_count,StoreIC,13,0 -block_count,StoreIC,14,23 -block_count,StoreIC,15,21 -block_count,StoreIC,16,21 +block_count,StoreIC,14,24 +block_count,StoreIC,15,23 +block_count,StoreIC,16,23 block_count,StoreIC,17,0 block_count,StoreIC,18,1 -block_count,StoreIC,19,2 -block_count,StoreIC,20,2 -block_count,StoreIC,21,2 +block_count,StoreIC,19,1 +block_count,StoreIC,20,1 +block_count,StoreIC,21,1 block_count,StoreIC,22,0 block_count,StoreIC,23,0 -block_count,StoreIC,24,73 +block_count,StoreIC,24,76 block_count,StoreIC,25,118 -block_count,StoreIC,26,44 -block_count,StoreIC,27,44 +block_count,StoreIC,26,42 +block_count,StoreIC,27,42 block_count,StoreIC,28,0 -block_count,StoreIC,29,73 -block_count,StoreIC,30,162 -block_count,StoreIC,31,259 -block_count,StoreIC,32,93 +block_count,StoreIC,29,76 +block_count,StoreIC,30,163 +block_count,StoreIC,31,264 +block_count,StoreIC,32,92 block_count,StoreIC,33,5 block_count,StoreIC,34,5 block_count,StoreIC,35,5 @@ -26935,7 +26924,7 @@ block_count,StoreIC,72,0 block_count,StoreIC,73,0 block_count,StoreIC,74,1 -block_count,StoreIC,75,2 +block_count,StoreIC,75,1 block_count,StoreIC,76,1 block_count,StoreIC,77,1 block_count,StoreIC,78,1 @@ -27039,21 +27028,21 @@ block_count,StoreIC,176,76 block_count,StoreIC,177,76 block_count,StoreIC,178,0 -block_count,StoreIC,179,76 +block_count,StoreIC,179,75 block_count,StoreIC,180,0 -block_count,StoreIC,181,76 -block_count,StoreIC,182,76 +block_count,StoreIC,181,75 +block_count,StoreIC,182,75 block_count,StoreIC,183,0 block_count,StoreIC,184,0 block_count,StoreIC,185,0 -block_count,StoreIC,186,76 +block_count,StoreIC,186,75 block_count,StoreIC,187,66 block_count,StoreIC,188,64 block_count,StoreIC,189,1 block_count,StoreIC,190,1 block_count,StoreIC,191,0 -block_count,StoreIC,192,63 -block_count,StoreIC,193,63 +block_count,StoreIC,192,62 +block_count,StoreIC,193,62 block_count,StoreIC,194,12 block_count,StoreIC,195,0 block_count,StoreIC,196,12 @@ -27067,8 +27056,8 @@ block_count,StoreIC,204,9 block_count,StoreIC,205,0 block_count,StoreIC,206,9 -block_count,StoreIC,207,76 -block_count,StoreIC,208,15 +block_count,StoreIC,207,75 +block_count,StoreIC,208,16 block_count,StoreIC,209,0 block_count,StoreIC,210,0 block_count,StoreIC,211,0 @@ -27076,11 +27065,11 @@ block_count,StoreIC,213,0 block_count,StoreIC,214,0 block_count,StoreIC,215,0 -block_count,StoreIC,216,15 -block_count,StoreIC,217,15 -block_count,StoreIC,218,15 +block_count,StoreIC,216,16 +block_count,StoreIC,217,16 +block_count,StoreIC,218,16 block_count,StoreIC,219,0 -block_count,StoreIC,220,15 +block_count,StoreIC,220,16 block_count,StoreIC,221,7 block_count,StoreIC,222,7 block_count,StoreIC,223,0 @@ -27099,7 +27088,7 @@ block_count,StoreIC,236,0 block_count,StoreIC,237,7 block_count,StoreIC,238,7 -block_count,StoreIC,239,4 +block_count,StoreIC,239,5 block_count,StoreIC,240,2 block_count,StoreIC,241,0 block_count,StoreIC,242,2 @@ -27111,9 +27100,9 @@ block_count,StoreIC,248,1 block_count,StoreIC,249,7 block_count,StoreIC,250,8 -block_count,StoreIC,251,15 -block_count,StoreIC,252,60 -block_count,StoreIC,253,58 +block_count,StoreIC,251,16 +block_count,StoreIC,252,59 +block_count,StoreIC,253,57 block_count,StoreIC,254,1 block_count,StoreIC,255,1 block_count,StoreIC,256,0 @@ -27141,7 +27130,7 @@ block_count,StoreIC,278,0 block_count,StoreIC,279,0 block_count,StoreIC,280,0 -block_count,StoreIC,281,166 +block_count,StoreIC,281,171 block_count,StoreIC,282,13 block_count,StoreIC,283,13 block_count,StoreIC,284,13 @@ -27166,9 +27155,9 @@ block_count,StoreIC,303,0 block_count,StoreIC,304,0 block_count,StoreIC,305,0 -block_count,StoreIC,306,152 -block_count,StoreIC,307,133 -block_count,StoreIC,308,133 +block_count,StoreIC,306,157 +block_count,StoreIC,307,138 +block_count,StoreIC,308,138 block_count,StoreIC,309,10 block_count,StoreIC,310,9 block_count,StoreIC,311,9 @@ -27178,7 +27167,7 @@ block_count,StoreIC,315,0 block_count,StoreIC,316,10 block_count,StoreIC,317,1 -block_count,StoreIC,318,8 +block_count,StoreIC,318,9 block_count,StoreIC,319,10 block_count,StoreIC,320,10 block_count,StoreIC,321,0 @@ -27194,30 +27183,30 @@ block_count,StoreIC,331,0 block_count,StoreIC,332,0 block_count,StoreIC,333,0 -block_count,StoreIC,334,66 -block_count,StoreIC,335,66 -block_count,StoreIC,336,66 +block_count,StoreIC,334,67 +block_count,StoreIC,335,67 +block_count,StoreIC,336,67 block_count,StoreIC,337,3 block_count,StoreIC,338,0 block_count,StoreIC,339,3 -block_count,StoreIC,340,63 +block_count,StoreIC,340,64 block_count,StoreIC,341,0 -block_count,StoreIC,342,66 -block_count,StoreIC,343,15 -block_count,StoreIC,344,50 -block_count,StoreIC,345,66 -block_count,StoreIC,346,66 +block_count,StoreIC,342,67 +block_count,StoreIC,343,16 +block_count,StoreIC,344,51 +block_count,StoreIC,345,67 +block_count,StoreIC,346,67 block_count,StoreIC,347,0 block_count,StoreIC,348,0 block_count,StoreIC,349,0 block_count,StoreIC,350,0 -block_count,StoreIC,351,54 +block_count,StoreIC,351,58 block_count,StoreIC,352,0 -block_count,StoreIC,353,54 +block_count,StoreIC,353,58 block_count,StoreIC,354,8 -block_count,StoreIC,355,45 -block_count,StoreIC,356,54 -block_count,StoreIC,357,54 +block_count,StoreIC,355,49 +block_count,StoreIC,356,58 +block_count,StoreIC,357,58 block_count,StoreIC,358,0 block_count,StoreIC,359,0 block_count,StoreIC,360,0 @@ -27251,17 +27240,17 @@ block_count,StoreIC_Megamorphic,4,1372 block_count,StoreIC_Megamorphic,5,0 block_count,StoreIC_Megamorphic,6,1372 -block_count,StoreIC_Megamorphic,7,1210 -block_count,StoreIC_Megamorphic,8,1163 -block_count,StoreIC_Megamorphic,9,46 -block_count,StoreIC_Megamorphic,10,161 -block_count,StoreIC_Megamorphic,11,208 -block_count,StoreIC_Megamorphic,12,207 -block_count,StoreIC_Megamorphic,13,205 +block_count,StoreIC_Megamorphic,7,1287 +block_count,StoreIC_Megamorphic,8,1173 +block_count,StoreIC_Megamorphic,9,113 +block_count,StoreIC_Megamorphic,10,85 +block_count,StoreIC_Megamorphic,11,199 +block_count,StoreIC_Megamorphic,12,198 +block_count,StoreIC_Megamorphic,13,196 block_count,StoreIC_Megamorphic,14,1 block_count,StoreIC_Megamorphic,15,0 -block_count,StoreIC_Megamorphic,16,1369 -block_count,StoreIC_Megamorphic,17,588 +block_count,StoreIC_Megamorphic,16,1370 +block_count,StoreIC_Megamorphic,17,589 block_count,StoreIC_Megamorphic,18,1 block_count,StoreIC_Megamorphic,19,1 block_count,StoreIC_Megamorphic,20,1 @@ -27402,41 +27391,41 @@ block_count,StoreIC_Megamorphic,155,0 block_count,StoreIC_Megamorphic,156,0 block_count,StoreIC_Megamorphic,157,0 -block_count,StoreIC_Megamorphic,158,586 -block_count,StoreIC_Megamorphic,159,586 -block_count,StoreIC_Megamorphic,160,392 -block_count,StoreIC_Megamorphic,161,392 -block_count,StoreIC_Megamorphic,162,392 +block_count,StoreIC_Megamorphic,158,587 +block_count,StoreIC_Megamorphic,159,587 +block_count,StoreIC_Megamorphic,160,394 +block_count,StoreIC_Megamorphic,161,394 +block_count,StoreIC_Megamorphic,162,394 block_count,StoreIC_Megamorphic,163,0 -block_count,StoreIC_Megamorphic,164,392 +block_count,StoreIC_Megamorphic,164,394 block_count,StoreIC_Megamorphic,165,0 -block_count,StoreIC_Megamorphic,166,392 -block_count,StoreIC_Megamorphic,167,392 +block_count,StoreIC_Megamorphic,166,394 +block_count,StoreIC_Megamorphic,167,394 block_count,StoreIC_Megamorphic,168,0 block_count,StoreIC_Megamorphic,169,0 block_count,StoreIC_Megamorphic,170,0 -block_count,StoreIC_Megamorphic,171,392 -block_count,StoreIC_Megamorphic,172,241 -block_count,StoreIC_Megamorphic,173,241 +block_count,StoreIC_Megamorphic,171,394 +block_count,StoreIC_Megamorphic,172,242 +block_count,StoreIC_Megamorphic,173,242 block_count,StoreIC_Megamorphic,174,0 block_count,StoreIC_Megamorphic,175,0 block_count,StoreIC_Megamorphic,176,0 -block_count,StoreIC_Megamorphic,177,241 -block_count,StoreIC_Megamorphic,178,241 +block_count,StoreIC_Megamorphic,177,242 +block_count,StoreIC_Megamorphic,178,242 block_count,StoreIC_Megamorphic,179,65 block_count,StoreIC_Megamorphic,180,0 block_count,StoreIC_Megamorphic,181,65 -block_count,StoreIC_Megamorphic,182,175 +block_count,StoreIC_Megamorphic,182,176 block_count,StoreIC_Megamorphic,183,0 block_count,StoreIC_Megamorphic,184,0 block_count,StoreIC_Megamorphic,185,0 block_count,StoreIC_Megamorphic,186,0 block_count,StoreIC_Megamorphic,187,0 block_count,StoreIC_Megamorphic,188,0 -block_count,StoreIC_Megamorphic,189,151 +block_count,StoreIC_Megamorphic,189,152 block_count,StoreIC_Megamorphic,190,0 -block_count,StoreIC_Megamorphic,191,151 -block_count,StoreIC_Megamorphic,192,392 +block_count,StoreIC_Megamorphic,191,152 +block_count,StoreIC_Megamorphic,192,394 block_count,StoreIC_Megamorphic,193,31 block_count,StoreIC_Megamorphic,194,0 block_count,StoreIC_Megamorphic,195,0 @@ -27481,8 +27470,8 @@ block_count,StoreIC_Megamorphic,234,13 block_count,StoreIC_Megamorphic,235,17 block_count,StoreIC_Megamorphic,236,31 -block_count,StoreIC_Megamorphic,237,361 -block_count,StoreIC_Megamorphic,238,361 +block_count,StoreIC_Megamorphic,237,362 +block_count,StoreIC_Megamorphic,238,362 block_count,StoreIC_Megamorphic,239,0 block_count,StoreIC_Megamorphic,240,0 block_count,StoreIC_Megamorphic,241,0 @@ -27510,7 +27499,7 @@ block_count,StoreIC_Megamorphic,263,0 block_count,StoreIC_Megamorphic,264,0 block_count,StoreIC_Megamorphic,265,0 -block_count,StoreIC_Megamorphic,266,781 +block_count,StoreIC_Megamorphic,266,780 block_count,StoreIC_Megamorphic,267,0 block_count,StoreIC_Megamorphic,268,0 block_count,StoreIC_Megamorphic,269,0 @@ -27535,9 +27524,9 @@ block_count,StoreIC_Megamorphic,288,0 block_count,StoreIC_Megamorphic,289,0 block_count,StoreIC_Megamorphic,290,0 -block_count,StoreIC_Megamorphic,291,781 -block_count,StoreIC_Megamorphic,292,781 -block_count,StoreIC_Megamorphic,293,781 +block_count,StoreIC_Megamorphic,291,779 +block_count,StoreIC_Megamorphic,292,779 +block_count,StoreIC_Megamorphic,293,779 block_count,StoreIC_Megamorphic,294,6 block_count,StoreIC_Megamorphic,295,6 block_count,StoreIC_Megamorphic,296,6 @@ -27580,13 +27569,13 @@ block_count,StoreIC_Megamorphic,333,0 block_count,StoreIC_Megamorphic,334,0 block_count,StoreIC_Megamorphic,335,0 -block_count,StoreIC_Megamorphic,336,330 +block_count,StoreIC_Megamorphic,336,329 block_count,StoreIC_Megamorphic,337,0 -block_count,StoreIC_Megamorphic,338,330 +block_count,StoreIC_Megamorphic,338,329 block_count,StoreIC_Megamorphic,339,2 -block_count,StoreIC_Megamorphic,340,328 -block_count,StoreIC_Megamorphic,341,330 -block_count,StoreIC_Megamorphic,342,330 +block_count,StoreIC_Megamorphic,340,327 +block_count,StoreIC_Megamorphic,341,329 +block_count,StoreIC_Megamorphic,342,329 block_count,StoreIC_Megamorphic,343,0 block_count,StoreIC_Megamorphic,344,0 block_count,StoreIC_Megamorphic,345,0 @@ -27619,13 +27608,13 @@ block_count,StoreICTrampoline_Megamorphic,1,638 block_count,StoreICTrampoline_Megamorphic,2,0 block_count,StoreICTrampoline_Megamorphic,3,638 -block_count,StoreICBaseline,0,204 -block_count,DefineNamedOwnIC,0,36 -block_count,DefineNamedOwnIC,1,36 +block_count,StoreICBaseline,0,210 +block_count,DefineNamedOwnIC,0,39 +block_count,DefineNamedOwnIC,1,39 block_count,DefineNamedOwnIC,2,0 -block_count,DefineNamedOwnIC,3,36 -block_count,DefineNamedOwnIC,4,36 -block_count,DefineNamedOwnIC,5,32 +block_count,DefineNamedOwnIC,3,39 +block_count,DefineNamedOwnIC,4,39 +block_count,DefineNamedOwnIC,5,34 block_count,DefineNamedOwnIC,6,0 block_count,DefineNamedOwnIC,7,0 block_count,DefineNamedOwnIC,8,0 @@ -27650,8 +27639,8 @@ block_count,DefineNamedOwnIC,27,0 block_count,DefineNamedOwnIC,28,0 block_count,DefineNamedOwnIC,29,0 -block_count,DefineNamedOwnIC,30,32 -block_count,DefineNamedOwnIC,31,32 +block_count,DefineNamedOwnIC,30,34 +block_count,DefineNamedOwnIC,31,34 block_count,DefineNamedOwnIC,32,0 block_count,DefineNamedOwnIC,33,0 block_count,DefineNamedOwnIC,34,0 @@ -27896,7 +27885,7 @@ block_count,DefineNamedOwnIC,273,0 block_count,DefineNamedOwnIC,274,0 block_count,DefineNamedOwnIC,275,0 -block_count,DefineNamedOwnIC,276,32 +block_count,DefineNamedOwnIC,276,34 block_count,DefineNamedOwnIC,277,0 block_count,DefineNamedOwnIC,278,0 block_count,DefineNamedOwnIC,279,0 @@ -27916,9 +27905,9 @@ block_count,DefineNamedOwnIC,293,0 block_count,DefineNamedOwnIC,294,0 block_count,DefineNamedOwnIC,295,0 -block_count,DefineNamedOwnIC,296,32 -block_count,DefineNamedOwnIC,297,32 -block_count,DefineNamedOwnIC,298,32 +block_count,DefineNamedOwnIC,296,34 +block_count,DefineNamedOwnIC,297,34 +block_count,DefineNamedOwnIC,298,34 block_count,DefineNamedOwnIC,299,0 block_count,DefineNamedOwnIC,300,0 block_count,DefineNamedOwnIC,301,0 @@ -27944,30 +27933,30 @@ block_count,DefineNamedOwnIC,321,0 block_count,DefineNamedOwnIC,322,0 block_count,DefineNamedOwnIC,323,0 -block_count,DefineNamedOwnIC,324,26 -block_count,DefineNamedOwnIC,325,26 -block_count,DefineNamedOwnIC,326,26 +block_count,DefineNamedOwnIC,324,27 +block_count,DefineNamedOwnIC,325,27 +block_count,DefineNamedOwnIC,326,27 block_count,DefineNamedOwnIC,327,3 block_count,DefineNamedOwnIC,328,0 block_count,DefineNamedOwnIC,329,3 block_count,DefineNamedOwnIC,330,23 block_count,DefineNamedOwnIC,331,0 -block_count,DefineNamedOwnIC,332,26 +block_count,DefineNamedOwnIC,332,27 block_count,DefineNamedOwnIC,333,0 -block_count,DefineNamedOwnIC,334,26 -block_count,DefineNamedOwnIC,335,26 -block_count,DefineNamedOwnIC,336,26 +block_count,DefineNamedOwnIC,334,27 +block_count,DefineNamedOwnIC,335,27 +block_count,DefineNamedOwnIC,336,27 block_count,DefineNamedOwnIC,337,0 block_count,DefineNamedOwnIC,338,0 block_count,DefineNamedOwnIC,339,0 block_count,DefineNamedOwnIC,340,0 -block_count,DefineNamedOwnIC,341,3 +block_count,DefineNamedOwnIC,341,5 block_count,DefineNamedOwnIC,342,0 -block_count,DefineNamedOwnIC,343,3 +block_count,DefineNamedOwnIC,343,5 block_count,DefineNamedOwnIC,344,0 -block_count,DefineNamedOwnIC,345,3 -block_count,DefineNamedOwnIC,346,3 -block_count,DefineNamedOwnIC,347,3 +block_count,DefineNamedOwnIC,345,5 +block_count,DefineNamedOwnIC,346,5 +block_count,DefineNamedOwnIC,347,5 block_count,DefineNamedOwnIC,348,0 block_count,DefineNamedOwnIC,349,0 block_count,DefineNamedOwnIC,350,0 @@ -27994,13 +27983,13 @@ block_count,DefineNamedOwnIC,371,4 block_count,DefineNamedOwnIC,372,0 block_count,DefineNamedOwnIC,373,0 -block_count,DefineNamedOwnICBaseline,0,31 -block_count,KeyedStoreIC,0,219 -block_count,KeyedStoreIC,1,219 +block_count,DefineNamedOwnICBaseline,0,34 +block_count,KeyedStoreIC,0,222 +block_count,KeyedStoreIC,1,222 block_count,KeyedStoreIC,2,0 -block_count,KeyedStoreIC,3,219 -block_count,KeyedStoreIC,4,219 -block_count,KeyedStoreIC,5,217 +block_count,KeyedStoreIC,3,222 +block_count,KeyedStoreIC,4,222 +block_count,KeyedStoreIC,5,220 block_count,KeyedStoreIC,6,19 block_count,KeyedStoreIC,7,0 block_count,KeyedStoreIC,8,19 @@ -28016,14 +28005,14 @@ block_count,KeyedStoreIC,18,10 block_count,KeyedStoreIC,19,7 block_count,KeyedStoreIC,20,13 -block_count,KeyedStoreIC,21,5 -block_count,KeyedStoreIC,22,5 +block_count,KeyedStoreIC,21,6 +block_count,KeyedStoreIC,22,6 block_count,KeyedStoreIC,23,0 block_count,KeyedStoreIC,24,7 -block_count,KeyedStoreIC,25,198 -block_count,KeyedStoreIC,26,206 -block_count,KeyedStoreIC,27,204 -block_count,KeyedStoreIC,28,204 +block_count,KeyedStoreIC,25,200 +block_count,KeyedStoreIC,26,209 +block_count,KeyedStoreIC,27,207 +block_count,KeyedStoreIC,28,207 block_count,KeyedStoreIC,29,30 block_count,KeyedStoreIC,30,30 block_count,KeyedStoreIC,31,0 @@ -28199,7 +28188,7 @@ block_count,KeyedStoreIC,201,0 block_count,KeyedStoreIC,202,0 block_count,KeyedStoreIC,203,0 -block_count,KeyedStoreIC,204,173 +block_count,KeyedStoreIC,204,176 block_count,KeyedStoreIC,205,0 block_count,KeyedStoreIC,206,0 block_count,KeyedStoreIC,207,0 @@ -28449,7 +28438,7 @@ block_count,KeyedStoreICTrampoline_Megamorphic,1,332 block_count,KeyedStoreICTrampoline_Megamorphic,2,0 block_count,KeyedStoreICTrampoline_Megamorphic,3,332 -block_count,KeyedStoreICBaseline,0,204 +block_count,KeyedStoreICBaseline,0,207 block_count,DefineKeyedOwnIC,0,2 block_count,DefineKeyedOwnIC,1,2 block_count,DefineKeyedOwnIC,2,0 @@ -28911,24 +28900,24 @@ block_count,StoreInArrayLiteralIC,16,0 block_count,StoreInArrayLiteralIC,17,1 block_count,StoreInArrayLiteralIC,18,14 -block_count,StoreInArrayLiteralIC,19,15 -block_count,StoreInArrayLiteralIC,20,15 +block_count,StoreInArrayLiteralIC,19,16 +block_count,StoreInArrayLiteralIC,20,16 block_count,StoreInArrayLiteralIC,21,0 block_count,StoreInArrayLiteralIC,22,0 block_count,StoreInArrayLiteralIC,23,0 block_count,StoreInArrayLiteralIC,24,0 block_count,StoreInArrayLiteralIC,25,0 -block_count,StoreInArrayLiteralIC,26,15 +block_count,StoreInArrayLiteralIC,26,16 block_count,StoreInArrayLiteralIC,27,0 block_count,StoreInArrayLiteralIC,28,1 block_count,StoreInArrayLiteralIC,29,0 block_count,StoreInArrayLiteralIC,30,0 -block_count,StoreInArrayLiteralICBaseline,0,14 -block_count,LoadGlobalIC,0,1419 -block_count,LoadGlobalIC,1,1419 -block_count,LoadGlobalIC,2,1352 -block_count,LoadGlobalIC,3,1352 -block_count,LoadGlobalIC,4,1352 +block_count,StoreInArrayLiteralICBaseline,0,15 +block_count,LoadGlobalIC,0,1197 +block_count,LoadGlobalIC,1,1197 +block_count,LoadGlobalIC,2,1130 +block_count,LoadGlobalIC,3,1130 +block_count,LoadGlobalIC,4,1130 block_count,LoadGlobalIC,5,0 block_count,LoadGlobalIC,6,0 block_count,LoadGlobalIC,7,0 @@ -29355,11 +29344,11 @@ block_count,LoadGlobalICInsideTypeof,210,0 block_count,LoadGlobalICInsideTypeof,211,0 block_count,LoadGlobalICInsideTypeof,212,0 -block_count,LoadGlobalICTrampoline,0,939 -block_count,LoadGlobalICTrampoline,1,939 +block_count,LoadGlobalICTrampoline,0,731 +block_count,LoadGlobalICTrampoline,1,731 block_count,LoadGlobalICTrampoline,2,0 -block_count,LoadGlobalICTrampoline,3,939 -block_count,LoadGlobalICBaseline,0,397 +block_count,LoadGlobalICTrampoline,3,731 +block_count,LoadGlobalICBaseline,0,403 block_count,LoadGlobalICInsideTypeofBaseline,0,0 block_count,LookupGlobalICBaseline,0,0 block_count,LookupGlobalICBaseline,1,0 @@ -29713,7 +29702,7 @@ block_count,KeyedHasIC_Megamorphic,42,4274 block_count,KeyedHasIC_Megamorphic,43,0 block_count,KeyedHasIC_Megamorphic,44,4274 -block_count,KeyedHasIC_Megamorphic,45,1404 +block_count,KeyedHasIC_Megamorphic,45,1405 block_count,KeyedHasIC_Megamorphic,46,2869 block_count,KeyedHasIC_Megamorphic,47,4274 block_count,KeyedHasIC_Megamorphic,48,3562 @@ -29735,17 +29724,17 @@ block_count,KeyedHasIC_Megamorphic,64,1992 block_count,KeyedHasIC_Megamorphic,65,484 block_count,KeyedHasIC_Megamorphic,66,1507 -block_count,KeyedHasIC_Megamorphic,67,7473 +block_count,KeyedHasIC_Megamorphic,67,7474 block_count,KeyedHasIC_Megamorphic,68,7471 -block_count,KeyedHasIC_Megamorphic,69,7468 +block_count,KeyedHasIC_Megamorphic,69,7469 block_count,KeyedHasIC_Megamorphic,70,5966 block_count,KeyedHasIC_Megamorphic,71,1502 block_count,KeyedHasIC_Megamorphic,72,2 block_count,KeyedHasIC_Megamorphic,73,2 block_count,KeyedHasIC_Megamorphic,74,1987 block_count,KeyedHasIC_Megamorphic,75,997 -block_count,KeyedHasIC_Megamorphic,76,989 -block_count,KeyedHasIC_Megamorphic,77,989 +block_count,KeyedHasIC_Megamorphic,76,990 +block_count,KeyedHasIC_Megamorphic,77,990 block_count,KeyedHasIC_Megamorphic,78,0 block_count,KeyedHasIC_Megamorphic,79,119 block_count,KeyedHasIC_Megamorphic,80,3 @@ -29786,8 +29775,8 @@ block_count,KeyedHasIC_Megamorphic,115,0 block_count,KeyedHasIC_Megamorphic,116,0 block_count,KeyedHasIC_Megamorphic,117,0 -block_count,KeyedHasIC_Megamorphic,118,2819 -block_count,KeyedHasIC_Megamorphic,119,2819 +block_count,KeyedHasIC_Megamorphic,118,2820 +block_count,KeyedHasIC_Megamorphic,119,2820 block_count,KeyedHasIC_Megamorphic,120,0 block_count,KeyedHasIC_Megamorphic,121,0 block_count,KeyedHasIC_Megamorphic,122,0 @@ -29826,12 +29815,12 @@ block_count,KeyedHasIC_Megamorphic,155,0 block_count,KeyedHasIC_Megamorphic,156,0 block_count,KeyedHasIC_Megamorphic,157,0 -block_count,KeyedHasIC_Megamorphic,158,2819 +block_count,KeyedHasIC_Megamorphic,158,2820 block_count,KeyedHasIC_Megamorphic,159,4 block_count,KeyedHasIC_Megamorphic,160,4 block_count,KeyedHasIC_Megamorphic,161,0 block_count,KeyedHasIC_Megamorphic,162,2815 -block_count,KeyedHasIC_Megamorphic,163,2819 +block_count,KeyedHasIC_Megamorphic,163,2820 block_count,KeyedHasIC_Megamorphic,164,2112 block_count,KeyedHasIC_Megamorphic,165,707 block_count,KeyedHasIC_Megamorphic,166,1 @@ -30218,9 +30207,9 @@ block_count,FindOrderedHashMapEntry,14,56 block_count,FindOrderedHashMapEntry,15,62 block_count,FindOrderedHashMapEntry,16,129 -block_count,FindOrderedHashMapEntry,17,304 -block_count,FindOrderedHashMapEntry,18,198 -block_count,FindOrderedHashMapEntry,19,174 +block_count,FindOrderedHashMapEntry,17,173 +block_count,FindOrderedHashMapEntry,18,67 +block_count,FindOrderedHashMapEntry,19,43 block_count,FindOrderedHashMapEntry,20,23 block_count,FindOrderedHashMapEntry,21,106 block_count,FindOrderedHashMapEntry,22,0 @@ -30269,7 +30258,7 @@ block_count,FindOrderedHashMapEntry,65,154 block_count,FindOrderedHashMapEntry,66,214 block_count,FindOrderedHashMapEntry,67,0 -block_count,FindOrderedHashMapEntry,68,67 +block_count,FindOrderedHashMapEntry,68,66 block_count,FindOrderedHashMapEntry,69,41 block_count,FindOrderedHashMapEntry,70,5 block_count,FindOrderedHashMapEntry,71,13 @@ -30692,9 +30681,9 @@ block_count,MapPrototypeSet,27,42 block_count,MapPrototypeSet,28,45 block_count,MapPrototypeSet,29,45 -block_count,MapPrototypeSet,30,76 -block_count,MapPrototypeSet,31,41 -block_count,MapPrototypeSet,32,30 +block_count,MapPrototypeSet,30,77 +block_count,MapPrototypeSet,31,43 +block_count,MapPrototypeSet,32,32 block_count,MapPrototypeSet,33,11 block_count,MapPrototypeSet,34,34 block_count,MapPrototypeSet,35,0 @@ -31060,26 +31049,26 @@ block_count,MapIteratorToList,54,0 block_count,MapIteratorToList,55,0 block_count,MapIteratorToList,56,0 -block_count,Add_Baseline,0,190 -block_count,Add_Baseline,1,120 +block_count,Add_Baseline,0,199 +block_count,Add_Baseline,1,122 block_count,Add_Baseline,2,1 block_count,Add_Baseline,3,1 block_count,Add_Baseline,4,0 -block_count,Add_Baseline,5,119 -block_count,Add_Baseline,6,119 +block_count,Add_Baseline,5,121 +block_count,Add_Baseline,6,120 block_count,Add_Baseline,7,0 -block_count,Add_Baseline,8,119 -block_count,Add_Baseline,9,119 +block_count,Add_Baseline,8,120 +block_count,Add_Baseline,9,120 block_count,Add_Baseline,10,0 -block_count,Add_Baseline,11,70 -block_count,Add_Baseline,12,38 -block_count,Add_Baseline,13,33 -block_count,Add_Baseline,14,33 +block_count,Add_Baseline,11,77 +block_count,Add_Baseline,12,41 +block_count,Add_Baseline,13,36 +block_count,Add_Baseline,14,36 block_count,Add_Baseline,15,0 block_count,Add_Baseline,16,4 -block_count,Add_Baseline,17,31 -block_count,Add_Baseline,18,31 -block_count,Add_Baseline,19,29 +block_count,Add_Baseline,17,36 +block_count,Add_Baseline,18,36 +block_count,Add_Baseline,19,34 block_count,Add_Baseline,20,0 block_count,Add_Baseline,21,0 block_count,Add_Baseline,22,0 @@ -31134,7 +31123,7 @@ block_count,Add_Baseline,71,0 block_count,Add_Baseline,72,0 block_count,Add_Baseline,73,0 -block_count,Add_Baseline,74,29 +block_count,Add_Baseline,74,33 block_count,Add_Baseline,75,2 block_count,Add_Baseline,76,2 block_count,Add_Baseline,77,0 @@ -31143,10 +31132,10 @@ block_count,Add_Baseline,80,0 block_count,Add_Baseline,81,0 block_count,Add_Baseline,82,0 -block_count,Add_Baseline,83,27 +block_count,Add_Baseline,83,31 block_count,Add_Baseline,84,0 -block_count,Add_Baseline,85,27 -block_count,Add_Baseline,86,27 +block_count,Add_Baseline,85,31 +block_count,Add_Baseline,86,31 block_count,Add_Baseline,87,1 block_count,Add_Baseline,88,0 block_count,Add_Baseline,89,0 @@ -31162,19 +31151,19 @@ block_count,Add_Baseline,99,0 block_count,Add_Baseline,100,4 block_count,Add_Baseline,101,4 -block_count,Add_Baseline,102,39 +block_count,Add_Baseline,102,42 block_count,Add_Baseline,103,0 -block_count,Add_Baseline,104,39 -block_count,Add_Baseline,105,39 +block_count,Add_Baseline,104,42 +block_count,Add_Baseline,105,42 block_count,Add_Baseline,106,0 -block_count,Add_Baseline,107,39 -block_count,Add_Baseline,108,39 -block_count,AddSmi_Baseline,0,241 -block_count,AddSmi_Baseline,1,241 -block_count,AddSmi_Baseline,2,241 +block_count,Add_Baseline,107,42 +block_count,Add_Baseline,108,42 +block_count,AddSmi_Baseline,0,244 +block_count,AddSmi_Baseline,1,243 +block_count,AddSmi_Baseline,2,243 block_count,AddSmi_Baseline,3,0 -block_count,AddSmi_Baseline,4,241 -block_count,AddSmi_Baseline,5,241 +block_count,AddSmi_Baseline,4,243 +block_count,AddSmi_Baseline,5,243 block_count,AddSmi_Baseline,6,0 block_count,AddSmi_Baseline,7,0 block_count,AddSmi_Baseline,8,0 @@ -31274,16 +31263,16 @@ block_count,Subtract_Baseline,2,1 block_count,Subtract_Baseline,3,1 block_count,Subtract_Baseline,4,0 -block_count,Subtract_Baseline,5,33 -block_count,Subtract_Baseline,6,33 +block_count,Subtract_Baseline,5,32 +block_count,Subtract_Baseline,6,32 block_count,Subtract_Baseline,7,0 block_count,Subtract_Baseline,8,0 block_count,Subtract_Baseline,9,0 block_count,Subtract_Baseline,10,0 -block_count,Subtract_Baseline,11,33 +block_count,Subtract_Baseline,11,32 block_count,Subtract_Baseline,12,0 -block_count,Subtract_Baseline,13,33 -block_count,Subtract_Baseline,14,33 +block_count,Subtract_Baseline,13,32 +block_count,Subtract_Baseline,14,32 block_count,Subtract_Baseline,15,13 block_count,Subtract_Baseline,16,13 block_count,Subtract_Baseline,17,12 @@ -31386,12 +31375,12 @@ block_count,SubtractSmi_Baseline,16,0 block_count,SubtractSmi_Baseline,17,3 block_count,SubtractSmi_Baseline,18,3 -block_count,Multiply_Baseline,0,50 -block_count,Multiply_Baseline,1,12 -block_count,Multiply_Baseline,2,7 -block_count,Multiply_Baseline,3,7 +block_count,Multiply_Baseline,0,55 +block_count,Multiply_Baseline,1,15 +block_count,Multiply_Baseline,2,10 +block_count,Multiply_Baseline,3,10 block_count,Multiply_Baseline,4,0 -block_count,Multiply_Baseline,5,4 +block_count,Multiply_Baseline,5,5 block_count,Multiply_Baseline,6,4 block_count,Multiply_Baseline,7,3 block_count,Multiply_Baseline,8,3 @@ -31407,17 +31396,17 @@ block_count,Multiply_Baseline,18,0 block_count,Multiply_Baseline,19,0 block_count,Multiply_Baseline,20,0 -block_count,Multiply_Baseline,21,4 +block_count,Multiply_Baseline,21,5 block_count,Multiply_Baseline,22,0 block_count,Multiply_Baseline,23,4 -block_count,Multiply_Baseline,24,4 +block_count,Multiply_Baseline,24,5 block_count,Multiply_Baseline,25,0 -block_count,Multiply_Baseline,26,4 -block_count,Multiply_Baseline,27,4 -block_count,Multiply_Baseline,28,38 -block_count,Multiply_Baseline,29,38 -block_count,Multiply_Baseline,30,36 -block_count,Multiply_Baseline,31,36 +block_count,Multiply_Baseline,26,5 +block_count,Multiply_Baseline,27,5 +block_count,Multiply_Baseline,28,40 +block_count,Multiply_Baseline,29,40 +block_count,Multiply_Baseline,30,38 +block_count,Multiply_Baseline,31,38 block_count,Multiply_Baseline,32,0 block_count,Multiply_Baseline,33,1 block_count,Multiply_Baseline,34,0 @@ -31492,13 +31481,13 @@ block_count,Multiply_Baseline,103,0 block_count,Multiply_Baseline,104,0 block_count,Multiply_Baseline,105,0 -block_count,Multiply_Baseline,106,45 +block_count,Multiply_Baseline,106,50 block_count,Multiply_Baseline,107,0 -block_count,Multiply_Baseline,108,45 -block_count,Multiply_Baseline,109,45 +block_count,Multiply_Baseline,108,50 +block_count,Multiply_Baseline,109,50 block_count,Multiply_Baseline,110,0 -block_count,Multiply_Baseline,111,45 -block_count,Multiply_Baseline,112,45 +block_count,Multiply_Baseline,111,50 +block_count,Multiply_Baseline,112,50 block_count,MultiplySmi_Baseline,0,5 block_count,MultiplySmi_Baseline,1,4 block_count,MultiplySmi_Baseline,2,4 @@ -31602,7 +31591,7 @@ block_count,MultiplySmi_Baseline,100,0 block_count,MultiplySmi_Baseline,101,0 block_count,MultiplySmi_Baseline,102,0 -block_count,Divide_Baseline,0,3 +block_count,Divide_Baseline,0,4 block_count,Divide_Baseline,1,2 block_count,Divide_Baseline,2,1 block_count,Divide_Baseline,3,1 @@ -32015,8 +32004,8 @@ block_count,Exponentiate_Baseline,46,0 block_count,Exponentiate_Baseline,47,0 block_count,Exponentiate_Baseline,48,0 -block_count,BitwiseAnd_Baseline,0,9 -block_count,BitwiseAnd_Baseline,1,8 +block_count,BitwiseAnd_Baseline,0,8 +block_count,BitwiseAnd_Baseline,1,7 block_count,BitwiseAnd_Baseline,2,1 block_count,BitwiseAnd_Baseline,3,1 block_count,BitwiseAnd_Baseline,4,0 @@ -32111,7 +32100,7 @@ block_count,BitwiseAnd_Baseline,93,0 block_count,BitwiseAnd_Baseline,94,0 block_count,BitwiseAnd_Baseline,95,1 -block_count,BitwiseAnd_Baseline,96,9 +block_count,BitwiseAnd_Baseline,96,8 block_count,BitwiseAnd_Baseline,97,7 block_count,BitwiseAnd_Baseline,98,1 block_count,BitwiseAnd_Baseline,99,1 @@ -32133,20 +32122,20 @@ block_count,BitwiseAnd_Baseline,115,0 block_count,BitwiseAnd_Baseline,116,0 block_count,BitwiseAnd_Baseline,117,1 -block_count,BitwiseAnd_Baseline,118,9 +block_count,BitwiseAnd_Baseline,118,8 block_count,BitwiseAnd_Baseline,119,8 block_count,BitwiseAnd_Baseline,120,0 block_count,BitwiseAnd_Baseline,121,0 block_count,BitwiseAnd_Baseline,122,0 block_count,BitwiseAnd_Baseline,123,0 -block_count,BitwiseAnd_Baseline,124,9 +block_count,BitwiseAnd_Baseline,124,8 block_count,BitwiseAnd_Baseline,125,0 block_count,BitwiseAnd_Baseline,126,8 -block_count,BitwiseAnd_Baseline,127,9 +block_count,BitwiseAnd_Baseline,127,8 block_count,BitwiseAnd_Baseline,128,0 -block_count,BitwiseAnd_Baseline,129,9 -block_count,BitwiseAnd_Baseline,130,9 -block_count,BitwiseAndSmi_Baseline,0,31 +block_count,BitwiseAnd_Baseline,129,8 +block_count,BitwiseAnd_Baseline,130,8 +block_count,BitwiseAndSmi_Baseline,0,33 block_count,BitwiseAndSmi_Baseline,1,1 block_count,BitwiseAndSmi_Baseline,2,1 block_count,BitwiseAndSmi_Baseline,3,0 @@ -32166,7 +32155,7 @@ block_count,BitwiseAndSmi_Baseline,17,0 block_count,BitwiseAndSmi_Baseline,18,0 block_count,BitwiseAndSmi_Baseline,19,0 -block_count,BitwiseAndSmi_Baseline,20,1 +block_count,BitwiseAndSmi_Baseline,20,0 block_count,BitwiseAndSmi_Baseline,21,1 block_count,BitwiseAndSmi_Baseline,22,1 block_count,BitwiseAndSmi_Baseline,23,0 @@ -32177,14 +32166,14 @@ block_count,BitwiseAndSmi_Baseline,28,0 block_count,BitwiseAndSmi_Baseline,29,1 block_count,BitwiseAndSmi_Baseline,30,1 -block_count,BitwiseAndSmi_Baseline,31,29 -block_count,BitwiseAndSmi_Baseline,32,31 +block_count,BitwiseAndSmi_Baseline,31,32 +block_count,BitwiseAndSmi_Baseline,32,33 block_count,BitwiseAndSmi_Baseline,33,0 -block_count,BitwiseAndSmi_Baseline,34,31 -block_count,BitwiseOr_Baseline,0,19 +block_count,BitwiseAndSmi_Baseline,34,33 +block_count,BitwiseOr_Baseline,0,20 block_count,BitwiseOr_Baseline,1,18 -block_count,BitwiseOr_Baseline,2,1 -block_count,BitwiseOr_Baseline,3,1 +block_count,BitwiseOr_Baseline,2,2 +block_count,BitwiseOr_Baseline,3,2 block_count,BitwiseOr_Baseline,4,0 block_count,BitwiseOr_Baseline,5,0 block_count,BitwiseOr_Baseline,6,0 @@ -32276,9 +32265,9 @@ block_count,BitwiseOr_Baseline,92,0 block_count,BitwiseOr_Baseline,93,0 block_count,BitwiseOr_Baseline,94,0 -block_count,BitwiseOr_Baseline,95,1 -block_count,BitwiseOr_Baseline,96,19 -block_count,BitwiseOr_Baseline,97,18 +block_count,BitwiseOr_Baseline,95,2 +block_count,BitwiseOr_Baseline,96,20 +block_count,BitwiseOr_Baseline,97,19 block_count,BitwiseOr_Baseline,98,1 block_count,BitwiseOr_Baseline,99,1 block_count,BitwiseOr_Baseline,100,0 @@ -32299,19 +32288,19 @@ block_count,BitwiseOr_Baseline,115,0 block_count,BitwiseOr_Baseline,116,0 block_count,BitwiseOr_Baseline,117,1 -block_count,BitwiseOr_Baseline,118,19 +block_count,BitwiseOr_Baseline,118,20 block_count,BitwiseOr_Baseline,119,17 block_count,BitwiseOr_Baseline,120,2 block_count,BitwiseOr_Baseline,121,0 block_count,BitwiseOr_Baseline,122,2 block_count,BitwiseOr_Baseline,123,2 -block_count,BitwiseOr_Baseline,124,19 +block_count,BitwiseOr_Baseline,124,20 block_count,BitwiseOr_Baseline,125,2 block_count,BitwiseOr_Baseline,126,17 -block_count,BitwiseOr_Baseline,127,19 +block_count,BitwiseOr_Baseline,127,20 block_count,BitwiseOr_Baseline,128,0 -block_count,BitwiseOr_Baseline,129,19 -block_count,BitwiseOr_Baseline,130,19 +block_count,BitwiseOr_Baseline,129,20 +block_count,BitwiseOr_Baseline,130,20 block_count,BitwiseOrSmi_Baseline,0,181 block_count,BitwiseOrSmi_Baseline,1,1 block_count,BitwiseOrSmi_Baseline,2,1 @@ -32614,30 +32603,30 @@ block_count,ShiftLeftSmi_Baseline,19,0 block_count,ShiftLeftSmi_Baseline,20,1 block_count,ShiftLeftSmi_Baseline,21,1 -block_count,ShiftLeftSmi_Baseline,22,1 +block_count,ShiftLeftSmi_Baseline,22,0 block_count,ShiftLeftSmi_Baseline,23,0 block_count,ShiftLeftSmi_Baseline,24,0 block_count,ShiftLeftSmi_Baseline,25,0 block_count,ShiftLeftSmi_Baseline,26,0 block_count,ShiftLeftSmi_Baseline,27,1 block_count,ShiftLeftSmi_Baseline,28,0 -block_count,ShiftLeftSmi_Baseline,29,1 +block_count,ShiftLeftSmi_Baseline,29,0 block_count,ShiftLeftSmi_Baseline,30,1 block_count,ShiftLeftSmi_Baseline,31,29 -block_count,ShiftLeftSmi_Baseline,32,28 +block_count,ShiftLeftSmi_Baseline,32,29 block_count,ShiftLeftSmi_Baseline,33,0 block_count,ShiftLeftSmi_Baseline,34,0 block_count,ShiftLeftSmi_Baseline,35,0 block_count,ShiftLeftSmi_Baseline,36,0 block_count,ShiftLeftSmi_Baseline,37,29 block_count,ShiftLeftSmi_Baseline,38,0 -block_count,ShiftLeftSmi_Baseline,39,28 +block_count,ShiftLeftSmi_Baseline,39,29 block_count,ShiftLeftSmi_Baseline,40,29 block_count,ShiftLeftSmi_Baseline,41,30 block_count,ShiftLeftSmi_Baseline,42,0 block_count,ShiftLeftSmi_Baseline,43,30 -block_count,ShiftRight_Baseline,0,1 -block_count,ShiftRight_Baseline,1,1 +block_count,ShiftRight_Baseline,0,2 +block_count,ShiftRight_Baseline,1,2 block_count,ShiftRight_Baseline,2,0 block_count,ShiftRight_Baseline,3,0 block_count,ShiftRight_Baseline,4,0 @@ -32680,8 +32669,8 @@ block_count,ShiftRight_Baseline,41,0 block_count,ShiftRight_Baseline,42,0 block_count,ShiftRight_Baseline,43,0 -block_count,ShiftRight_Baseline,44,1 -block_count,ShiftRight_Baseline,45,1 +block_count,ShiftRight_Baseline,44,2 +block_count,ShiftRight_Baseline,45,2 block_count,ShiftRight_Baseline,46,0 block_count,ShiftRight_Baseline,47,0 block_count,ShiftRight_Baseline,48,0 @@ -32702,20 +32691,20 @@ block_count,ShiftRight_Baseline,63,0 block_count,ShiftRight_Baseline,64,0 block_count,ShiftRight_Baseline,65,0 -block_count,ShiftRight_Baseline,66,1 -block_count,ShiftRight_Baseline,67,1 +block_count,ShiftRight_Baseline,66,2 +block_count,ShiftRight_Baseline,67,2 block_count,ShiftRight_Baseline,68,0 block_count,ShiftRight_Baseline,69,0 block_count,ShiftRight_Baseline,70,0 block_count,ShiftRight_Baseline,71,0 -block_count,ShiftRight_Baseline,72,1 +block_count,ShiftRight_Baseline,72,2 block_count,ShiftRight_Baseline,73,0 -block_count,ShiftRight_Baseline,74,1 -block_count,ShiftRight_Baseline,75,1 +block_count,ShiftRight_Baseline,74,2 +block_count,ShiftRight_Baseline,75,2 block_count,ShiftRight_Baseline,76,0 -block_count,ShiftRight_Baseline,77,1 -block_count,ShiftRight_Baseline,78,1 -block_count,ShiftRightSmi_Baseline,0,115 +block_count,ShiftRight_Baseline,77,2 +block_count,ShiftRight_Baseline,78,2 +block_count,ShiftRightSmi_Baseline,0,116 block_count,ShiftRightSmi_Baseline,1,1 block_count,ShiftRightSmi_Baseline,2,1 block_count,ShiftRightSmi_Baseline,3,0 @@ -32746,10 +32735,10 @@ block_count,ShiftRightSmi_Baseline,28,0 block_count,ShiftRightSmi_Baseline,29,1 block_count,ShiftRightSmi_Baseline,30,1 -block_count,ShiftRightSmi_Baseline,31,113 -block_count,ShiftRightSmi_Baseline,32,115 +block_count,ShiftRightSmi_Baseline,31,115 +block_count,ShiftRightSmi_Baseline,32,116 block_count,ShiftRightSmi_Baseline,33,0 -block_count,ShiftRightSmi_Baseline,34,115 +block_count,ShiftRightSmi_Baseline,34,116 block_count,ShiftRightLogical_Baseline,0,0 block_count,ShiftRightLogical_Baseline,1,0 block_count,ShiftRightLogical_Baseline,2,0 @@ -32858,14 +32847,14 @@ block_count,ShiftRightLogicalSmi_Baseline,29,1 block_count,ShiftRightLogicalSmi_Baseline,30,1 block_count,ShiftRightLogicalSmi_Baseline,31,2 -block_count,ShiftRightLogicalSmi_Baseline,32,2 +block_count,ShiftRightLogicalSmi_Baseline,32,1 block_count,ShiftRightLogicalSmi_Baseline,33,0 block_count,ShiftRightLogicalSmi_Baseline,34,0 block_count,ShiftRightLogicalSmi_Baseline,35,0 block_count,ShiftRightLogicalSmi_Baseline,36,0 block_count,ShiftRightLogicalSmi_Baseline,37,2 block_count,ShiftRightLogicalSmi_Baseline,38,0 -block_count,ShiftRightLogicalSmi_Baseline,39,2 +block_count,ShiftRightLogicalSmi_Baseline,39,1 block_count,ShiftRightLogicalSmi_Baseline,40,2 block_count,ShiftRightLogicalSmi_Baseline,41,3 block_count,ShiftRightLogicalSmi_Baseline,42,0 @@ -32944,7 +32933,7 @@ block_count,Add_WithFeedback,71,0 block_count,Add_WithFeedback,72,0 block_count,Add_WithFeedback,73,0 -block_count,Add_WithFeedback,74,31 +block_count,Add_WithFeedback,74,32 block_count,Add_WithFeedback,75,30 block_count,Add_WithFeedback,76,30 block_count,Add_WithFeedback,77,0 @@ -33409,14 +33398,14 @@ block_count,BitwiseOr_WithFeedback,128,0 block_count,BitwiseOr_WithFeedback,129,0 block_count,BitwiseOr_WithFeedback,130,0 -block_count,Equal_Baseline,0,151 -block_count,Equal_Baseline,1,152 -block_count,Equal_Baseline,2,125 +block_count,Equal_Baseline,0,154 +block_count,Equal_Baseline,1,155 +block_count,Equal_Baseline,2,126 block_count,Equal_Baseline,3,22 -block_count,Equal_Baseline,4,21 +block_count,Equal_Baseline,4,22 block_count,Equal_Baseline,5,9 -block_count,Equal_Baseline,6,9 -block_count,Equal_Baseline,7,9 +block_count,Equal_Baseline,6,8 +block_count,Equal_Baseline,7,8 block_count,Equal_Baseline,8,6 block_count,Equal_Baseline,9,6 block_count,Equal_Baseline,10,0 @@ -33476,9 +33465,9 @@ block_count,Equal_Baseline,64,0 block_count,Equal_Baseline,65,0 block_count,Equal_Baseline,66,2 -block_count,Equal_Baseline,67,2 +block_count,Equal_Baseline,67,1 block_count,Equal_Baseline,68,0 -block_count,Equal_Baseline,69,2 +block_count,Equal_Baseline,69,1 block_count,Equal_Baseline,70,0 block_count,Equal_Baseline,71,0 block_count,Equal_Baseline,72,0 @@ -33506,21 +33495,21 @@ block_count,Equal_Baseline,94,0 block_count,Equal_Baseline,95,0 block_count,Equal_Baseline,96,0 -block_count,Equal_Baseline,97,11 +block_count,Equal_Baseline,97,12 block_count,Equal_Baseline,98,0 -block_count,Equal_Baseline,99,11 -block_count,Equal_Baseline,100,8 +block_count,Equal_Baseline,99,12 +block_count,Equal_Baseline,100,9 block_count,Equal_Baseline,101,3 block_count,Equal_Baseline,102,3 block_count,Equal_Baseline,103,3 block_count,Equal_Baseline,104,0 -block_count,Equal_Baseline,105,11 -block_count,Equal_Baseline,106,1 -block_count,Equal_Baseline,107,9 -block_count,Equal_Baseline,108,11 +block_count,Equal_Baseline,105,12 +block_count,Equal_Baseline,106,2 +block_count,Equal_Baseline,107,10 +block_count,Equal_Baseline,108,12 block_count,Equal_Baseline,109,0 -block_count,Equal_Baseline,110,11 -block_count,Equal_Baseline,111,11 +block_count,Equal_Baseline,110,12 +block_count,Equal_Baseline,111,12 block_count,Equal_Baseline,112,0 block_count,Equal_Baseline,113,0 block_count,Equal_Baseline,114,103 @@ -33559,10 +33548,10 @@ block_count,Equal_Baseline,147,1 block_count,Equal_Baseline,148,1 block_count,Equal_Baseline,149,0 -block_count,Equal_Baseline,150,27 -block_count,Equal_Baseline,151,5 +block_count,Equal_Baseline,150,28 +block_count,Equal_Baseline,151,6 block_count,Equal_Baseline,152,5 -block_count,Equal_Baseline,153,4 +block_count,Equal_Baseline,153,3 block_count,Equal_Baseline,154,1 block_count,Equal_Baseline,155,0 block_count,Equal_Baseline,156,0 @@ -33586,36 +33575,36 @@ block_count,Equal_Baseline,174,0 block_count,Equal_Baseline,175,0 block_count,Equal_Baseline,176,0 -block_count,Equal_Baseline,177,21 -block_count,Equal_Baseline,178,27 -block_count,Equal_Baseline,179,112 -block_count,Equal_Baseline,180,151 +block_count,Equal_Baseline,177,22 +block_count,Equal_Baseline,178,29 +block_count,Equal_Baseline,179,111 +block_count,Equal_Baseline,180,154 block_count,Equal_Baseline,181,0 -block_count,Equal_Baseline,182,151 -block_count,StrictEqual_Baseline,0,190 -block_count,StrictEqual_Baseline,1,160 -block_count,StrictEqual_Baseline,2,115 -block_count,StrictEqual_Baseline,3,115 -block_count,StrictEqual_Baseline,4,115 -block_count,StrictEqual_Baseline,5,56 -block_count,StrictEqual_Baseline,6,56 -block_count,StrictEqual_Baseline,7,25 -block_count,StrictEqual_Baseline,8,24 -block_count,StrictEqual_Baseline,9,19 +block_count,Equal_Baseline,182,154 +block_count,StrictEqual_Baseline,0,210 +block_count,StrictEqual_Baseline,1,179 +block_count,StrictEqual_Baseline,2,128 +block_count,StrictEqual_Baseline,3,127 +block_count,StrictEqual_Baseline,4,127 +block_count,StrictEqual_Baseline,5,57 +block_count,StrictEqual_Baseline,6,57 +block_count,StrictEqual_Baseline,7,26 +block_count,StrictEqual_Baseline,8,25 +block_count,StrictEqual_Baseline,9,20 block_count,StrictEqual_Baseline,10,0 -block_count,StrictEqual_Baseline,11,19 +block_count,StrictEqual_Baseline,11,20 block_count,StrictEqual_Baseline,12,0 -block_count,StrictEqual_Baseline,13,19 +block_count,StrictEqual_Baseline,13,20 block_count,StrictEqual_Baseline,14,4 block_count,StrictEqual_Baseline,15,2 block_count,StrictEqual_Baseline,16,2 block_count,StrictEqual_Baseline,17,1 -block_count,StrictEqual_Baseline,18,31 -block_count,StrictEqual_Baseline,19,31 +block_count,StrictEqual_Baseline,18,30 +block_count,StrictEqual_Baseline,19,30 block_count,StrictEqual_Baseline,20,0 block_count,StrictEqual_Baseline,21,0 block_count,StrictEqual_Baseline,22,0 -block_count,StrictEqual_Baseline,23,30 +block_count,StrictEqual_Baseline,23,29 block_count,StrictEqual_Baseline,24,0 block_count,StrictEqual_Baseline,25,0 block_count,StrictEqual_Baseline,26,0 @@ -33647,17 +33636,17 @@ block_count,StrictEqual_Baseline,52,0 block_count,StrictEqual_Baseline,53,0 block_count,StrictEqual_Baseline,54,0 -block_count,StrictEqual_Baseline,55,58 +block_count,StrictEqual_Baseline,55,70 block_count,StrictEqual_Baseline,56,0 -block_count,StrictEqual_Baseline,57,58 -block_count,StrictEqual_Baseline,58,16 -block_count,StrictEqual_Baseline,59,41 -block_count,StrictEqual_Baseline,60,58 +block_count,StrictEqual_Baseline,57,70 +block_count,StrictEqual_Baseline,58,25 +block_count,StrictEqual_Baseline,59,44 +block_count,StrictEqual_Baseline,60,70 block_count,StrictEqual_Baseline,61,0 -block_count,StrictEqual_Baseline,62,58 -block_count,StrictEqual_Baseline,63,58 -block_count,StrictEqual_Baseline,64,42 -block_count,StrictEqual_Baseline,65,15 +block_count,StrictEqual_Baseline,62,69 +block_count,StrictEqual_Baseline,63,70 +block_count,StrictEqual_Baseline,64,53 +block_count,StrictEqual_Baseline,65,16 block_count,StrictEqual_Baseline,66,0 block_count,StrictEqual_Baseline,67,0 block_count,StrictEqual_Baseline,68,0 @@ -33668,13 +33657,13 @@ block_count,StrictEqual_Baseline,73,0 block_count,StrictEqual_Baseline,74,0 block_count,StrictEqual_Baseline,75,0 -block_count,StrictEqual_Baseline,76,44 +block_count,StrictEqual_Baseline,76,51 block_count,StrictEqual_Baseline,77,0 block_count,StrictEqual_Baseline,78,0 block_count,StrictEqual_Baseline,79,0 block_count,StrictEqual_Baseline,80,0 block_count,StrictEqual_Baseline,81,0 -block_count,StrictEqual_Baseline,82,43 +block_count,StrictEqual_Baseline,82,50 block_count,StrictEqual_Baseline,83,5 block_count,StrictEqual_Baseline,84,30 block_count,StrictEqual_Baseline,85,15 @@ -33704,13 +33693,13 @@ block_count,StrictEqual_Baseline,109,0 block_count,StrictEqual_Baseline,110,0 block_count,StrictEqual_Baseline,111,15 -block_count,StrictEqual_Baseline,112,101 +block_count,StrictEqual_Baseline,112,109 block_count,StrictEqual_Baseline,113,30 -block_count,StrictEqual_Baseline,114,190 +block_count,StrictEqual_Baseline,114,210 block_count,StrictEqual_Baseline,115,0 -block_count,StrictEqual_Baseline,116,190 -block_count,LessThan_Baseline,0,147 -block_count,LessThan_Baseline,1,147 +block_count,StrictEqual_Baseline,116,210 +block_count,LessThan_Baseline,0,153 +block_count,LessThan_Baseline,1,153 block_count,LessThan_Baseline,2,9 block_count,LessThan_Baseline,3,3 block_count,LessThan_Baseline,4,0 @@ -33804,7 +33793,7 @@ block_count,LessThan_Baseline,92,0 block_count,LessThan_Baseline,93,0 block_count,LessThan_Baseline,94,0 -block_count,LessThan_Baseline,95,2 +block_count,LessThan_Baseline,95,3 block_count,LessThan_Baseline,96,0 block_count,LessThan_Baseline,97,0 block_count,LessThan_Baseline,98,0 @@ -33814,7 +33803,7 @@ block_count,LessThan_Baseline,102,0 block_count,LessThan_Baseline,103,0 block_count,LessThan_Baseline,104,0 -block_count,LessThan_Baseline,105,2 +block_count,LessThan_Baseline,105,3 block_count,LessThan_Baseline,106,6 block_count,LessThan_Baseline,107,0 block_count,LessThan_Baseline,108,0 @@ -33826,7 +33815,7 @@ block_count,LessThan_Baseline,114,0 block_count,LessThan_Baseline,115,0 block_count,LessThan_Baseline,116,6 -block_count,LessThan_Baseline,117,138 +block_count,LessThan_Baseline,117,143 block_count,LessThan_Baseline,118,0 block_count,LessThan_Baseline,119,0 block_count,LessThan_Baseline,120,0 @@ -33838,9 +33827,9 @@ block_count,LessThan_Baseline,126,0 block_count,LessThan_Baseline,127,0 block_count,LessThan_Baseline,128,0 -block_count,LessThan_Baseline,129,137 +block_count,LessThan_Baseline,129,143 block_count,LessThan_Baseline,130,42 -block_count,LessThan_Baseline,131,95 +block_count,LessThan_Baseline,131,101 block_count,LessThan_Baseline,132,0 block_count,LessThan_Baseline,133,0 block_count,LessThan_Baseline,134,0 @@ -33850,12 +33839,12 @@ block_count,LessThan_Baseline,138,7 block_count,LessThan_Baseline,139,2 block_count,LessThan_Baseline,140,49 -block_count,LessThan_Baseline,141,97 -block_count,LessThan_Baseline,142,147 +block_count,LessThan_Baseline,141,103 +block_count,LessThan_Baseline,142,153 block_count,LessThan_Baseline,143,0 -block_count,LessThan_Baseline,144,147 +block_count,LessThan_Baseline,144,153 block_count,GreaterThan_Baseline,0,44 -block_count,GreaterThan_Baseline,1,45 +block_count,GreaterThan_Baseline,1,44 block_count,GreaterThan_Baseline,2,3 block_count,GreaterThan_Baseline,3,2 block_count,GreaterThan_Baseline,4,0 @@ -33984,8 +33973,8 @@ block_count,GreaterThan_Baseline,127,0 block_count,GreaterThan_Baseline,128,0 block_count,GreaterThan_Baseline,129,41 -block_count,GreaterThan_Baseline,130,23 -block_count,GreaterThan_Baseline,131,17 +block_count,GreaterThan_Baseline,130,24 +block_count,GreaterThan_Baseline,131,16 block_count,GreaterThan_Baseline,132,0 block_count,GreaterThan_Baseline,133,0 block_count,GreaterThan_Baseline,134,0 @@ -33994,13 +33983,13 @@ block_count,GreaterThan_Baseline,137,3 block_count,GreaterThan_Baseline,138,2 block_count,GreaterThan_Baseline,139,1 -block_count,GreaterThan_Baseline,140,25 +block_count,GreaterThan_Baseline,140,26 block_count,GreaterThan_Baseline,141,18 block_count,GreaterThan_Baseline,142,44 block_count,GreaterThan_Baseline,143,0 block_count,GreaterThan_Baseline,144,44 -block_count,LessThanOrEqual_Baseline,0,20 -block_count,LessThanOrEqual_Baseline,1,20 +block_count,LessThanOrEqual_Baseline,0,21 +block_count,LessThanOrEqual_Baseline,1,21 block_count,LessThanOrEqual_Baseline,2,1 block_count,LessThanOrEqual_Baseline,3,0 block_count,LessThanOrEqual_Baseline,4,0 @@ -34128,7 +34117,7 @@ block_count,LessThanOrEqual_Baseline,126,0 block_count,LessThanOrEqual_Baseline,127,0 block_count,LessThanOrEqual_Baseline,128,0 -block_count,LessThanOrEqual_Baseline,129,18 +block_count,LessThanOrEqual_Baseline,129,19 block_count,LessThanOrEqual_Baseline,130,1 block_count,LessThanOrEqual_Baseline,131,17 block_count,LessThanOrEqual_Baseline,132,0 @@ -34141,11 +34130,11 @@ block_count,LessThanOrEqual_Baseline,139,1 block_count,LessThanOrEqual_Baseline,140,2 block_count,LessThanOrEqual_Baseline,141,18 -block_count,LessThanOrEqual_Baseline,142,20 +block_count,LessThanOrEqual_Baseline,142,21 block_count,LessThanOrEqual_Baseline,143,0 -block_count,LessThanOrEqual_Baseline,144,20 -block_count,GreaterThanOrEqual_Baseline,0,38 -block_count,GreaterThanOrEqual_Baseline,1,38 +block_count,LessThanOrEqual_Baseline,144,21 +block_count,GreaterThanOrEqual_Baseline,0,40 +block_count,GreaterThanOrEqual_Baseline,1,40 block_count,GreaterThanOrEqual_Baseline,2,3 block_count,GreaterThanOrEqual_Baseline,3,2 block_count,GreaterThanOrEqual_Baseline,4,0 @@ -34261,7 +34250,7 @@ block_count,GreaterThanOrEqual_Baseline,114,0 block_count,GreaterThanOrEqual_Baseline,115,0 block_count,GreaterThanOrEqual_Baseline,116,1 -block_count,GreaterThanOrEqual_Baseline,117,35 +block_count,GreaterThanOrEqual_Baseline,117,36 block_count,GreaterThanOrEqual_Baseline,118,0 block_count,GreaterThanOrEqual_Baseline,119,0 block_count,GreaterThanOrEqual_Baseline,120,0 @@ -34273,8 +34262,8 @@ block_count,GreaterThanOrEqual_Baseline,126,0 block_count,GreaterThanOrEqual_Baseline,127,0 block_count,GreaterThanOrEqual_Baseline,128,0 -block_count,GreaterThanOrEqual_Baseline,129,35 -block_count,GreaterThanOrEqual_Baseline,130,20 +block_count,GreaterThanOrEqual_Baseline,129,36 +block_count,GreaterThanOrEqual_Baseline,130,21 block_count,GreaterThanOrEqual_Baseline,131,14 block_count,GreaterThanOrEqual_Baseline,132,0 block_count,GreaterThanOrEqual_Baseline,133,0 @@ -34284,11 +34273,11 @@ block_count,GreaterThanOrEqual_Baseline,137,3 block_count,GreaterThanOrEqual_Baseline,138,1 block_count,GreaterThanOrEqual_Baseline,139,1 -block_count,GreaterThanOrEqual_Baseline,140,22 +block_count,GreaterThanOrEqual_Baseline,140,23 block_count,GreaterThanOrEqual_Baseline,141,16 -block_count,GreaterThanOrEqual_Baseline,142,38 +block_count,GreaterThanOrEqual_Baseline,142,40 block_count,GreaterThanOrEqual_Baseline,143,0 -block_count,GreaterThanOrEqual_Baseline,144,38 +block_count,GreaterThanOrEqual_Baseline,144,40 block_count,Equal_WithFeedback,0,10 block_count,Equal_WithFeedback,1,13 block_count,Equal_WithFeedback,2,9 @@ -34431,7 +34420,7 @@ block_count,Equal_WithFeedback,139,0 block_count,Equal_WithFeedback,140,0 block_count,Equal_WithFeedback,141,0 -block_count,Equal_WithFeedback,142,2 +block_count,Equal_WithFeedback,142,3 block_count,Equal_WithFeedback,143,0 block_count,Equal_WithFeedback,144,0 block_count,Equal_WithFeedback,145,0 @@ -34475,10 +34464,10 @@ block_count,StrictEqual_WithFeedback,0,122 block_count,StrictEqual_WithFeedback,1,107 block_count,StrictEqual_WithFeedback,2,98 -block_count,StrictEqual_WithFeedback,3,97 -block_count,StrictEqual_WithFeedback,4,95 -block_count,StrictEqual_WithFeedback,5,20 -block_count,StrictEqual_WithFeedback,6,20 +block_count,StrictEqual_WithFeedback,3,98 +block_count,StrictEqual_WithFeedback,4,96 +block_count,StrictEqual_WithFeedback,5,21 +block_count,StrictEqual_WithFeedback,6,21 block_count,StrictEqual_WithFeedback,7,17 block_count,StrictEqual_WithFeedback,8,16 block_count,StrictEqual_WithFeedback,9,1 @@ -34495,7 +34484,7 @@ block_count,StrictEqual_WithFeedback,20,0 block_count,StrictEqual_WithFeedback,21,0 block_count,StrictEqual_WithFeedback,22,0 -block_count,StrictEqual_WithFeedback,23,3 +block_count,StrictEqual_WithFeedback,23,2 block_count,StrictEqual_WithFeedback,24,0 block_count,StrictEqual_WithFeedback,25,0 block_count,StrictEqual_WithFeedback,26,0 @@ -34556,10 +34545,10 @@ block_count,StrictEqual_WithFeedback,81,0 block_count,StrictEqual_WithFeedback,82,8 block_count,StrictEqual_WithFeedback,83,11 -block_count,StrictEqual_WithFeedback,84,15 +block_count,StrictEqual_WithFeedback,84,14 block_count,StrictEqual_WithFeedback,85,13 block_count,StrictEqual_WithFeedback,86,13 -block_count,StrictEqual_WithFeedback,87,5 +block_count,StrictEqual_WithFeedback,87,4 block_count,StrictEqual_WithFeedback,88,1 block_count,StrictEqual_WithFeedback,89,0 block_count,StrictEqual_WithFeedback,90,0 @@ -34584,8 +34573,8 @@ block_count,StrictEqual_WithFeedback,109,0 block_count,StrictEqual_WithFeedback,110,0 block_count,StrictEqual_WithFeedback,111,1 -block_count,StrictEqual_WithFeedback,112,32 -block_count,StrictEqual_WithFeedback,113,15 +block_count,StrictEqual_WithFeedback,112,33 +block_count,StrictEqual_WithFeedback,113,14 block_count,StrictEqual_WithFeedback,114,122 block_count,StrictEqual_WithFeedback,115,0 block_count,StrictEqual_WithFeedback,116,122 @@ -35059,8 +35048,8 @@ block_count,BitwiseNot_Baseline,32,0 block_count,BitwiseNot_Baseline,33,1 block_count,BitwiseNot_Baseline,34,1 -block_count,Decrement_Baseline,0,18 -block_count,Decrement_Baseline,1,18 +block_count,Decrement_Baseline,0,17 +block_count,Decrement_Baseline,1,17 block_count,Decrement_Baseline,2,0 block_count,Decrement_Baseline,3,0 block_count,Decrement_Baseline,4,0 @@ -35075,18 +35064,18 @@ block_count,Decrement_Baseline,13,0 block_count,Decrement_Baseline,14,0 block_count,Decrement_Baseline,15,0 -block_count,Decrement_Baseline,16,18 -block_count,Decrement_Baseline,17,18 +block_count,Decrement_Baseline,16,17 +block_count,Decrement_Baseline,17,17 block_count,Decrement_Baseline,18,0 block_count,Decrement_Baseline,19,0 block_count,Decrement_Baseline,20,0 block_count,Decrement_Baseline,21,0 block_count,Decrement_Baseline,22,0 -block_count,Decrement_Baseline,23,18 +block_count,Decrement_Baseline,23,17 block_count,Decrement_Baseline,24,0 -block_count,Decrement_Baseline,25,18 -block_count,Increment_Baseline,0,101 -block_count,Increment_Baseline,1,101 +block_count,Decrement_Baseline,25,17 +block_count,Increment_Baseline,0,109 +block_count,Increment_Baseline,1,109 block_count,Increment_Baseline,2,0 block_count,Increment_Baseline,3,0 block_count,Increment_Baseline,4,0 @@ -35101,16 +35090,16 @@ block_count,Increment_Baseline,13,0 block_count,Increment_Baseline,14,0 block_count,Increment_Baseline,15,0 -block_count,Increment_Baseline,16,101 -block_count,Increment_Baseline,17,101 +block_count,Increment_Baseline,16,109 +block_count,Increment_Baseline,17,109 block_count,Increment_Baseline,18,0 block_count,Increment_Baseline,19,0 block_count,Increment_Baseline,20,0 block_count,Increment_Baseline,21,0 block_count,Increment_Baseline,22,0 -block_count,Increment_Baseline,23,101 +block_count,Increment_Baseline,23,109 block_count,Increment_Baseline,24,0 -block_count,Increment_Baseline,25,101 +block_count,Increment_Baseline,25,109 block_count,Negate_Baseline,0,3 block_count,Negate_Baseline,1,3 block_count,Negate_Baseline,2,2 @@ -36119,7 +36108,7 @@ block_count,ObjectPrototypeHasOwnProperty,71,146 block_count,ObjectPrototypeHasOwnProperty,72,0 block_count,ObjectPrototypeHasOwnProperty,73,146 -block_count,ObjectPrototypeHasOwnProperty,74,165 +block_count,ObjectPrototypeHasOwnProperty,74,166 block_count,ObjectPrototypeHasOwnProperty,75,117 block_count,ObjectPrototypeHasOwnProperty,76,68 block_count,ObjectPrototypeHasOwnProperty,77,19 @@ -36309,36 +36298,36 @@ block_count,ObjectToString,84,0 block_count,ObjectToString,85,172 block_count,ObjectToString,86,62 -block_count,OrdinaryHasInstance,0,109 -block_count,OrdinaryHasInstance,1,109 -block_count,OrdinaryHasInstance,2,109 +block_count,OrdinaryHasInstance,0,107 +block_count,OrdinaryHasInstance,1,107 +block_count,OrdinaryHasInstance,2,107 block_count,OrdinaryHasInstance,3,0 -block_count,OrdinaryHasInstance,4,109 +block_count,OrdinaryHasInstance,4,107 block_count,OrdinaryHasInstance,5,0 block_count,OrdinaryHasInstance,6,0 block_count,OrdinaryHasInstance,7,0 -block_count,OrdinaryHasInstance,8,109 -block_count,OrdinaryHasInstance,9,109 -block_count,OrdinaryHasInstance,10,109 +block_count,OrdinaryHasInstance,8,107 +block_count,OrdinaryHasInstance,9,107 +block_count,OrdinaryHasInstance,10,107 block_count,OrdinaryHasInstance,11,3 block_count,OrdinaryHasInstance,12,3 block_count,OrdinaryHasInstance,13,0 -block_count,OrdinaryHasInstance,14,105 -block_count,OrdinaryHasInstance,15,109 -block_count,OrdinaryHasInstance,16,343 -block_count,OrdinaryHasInstance,17,300 +block_count,OrdinaryHasInstance,14,103 +block_count,OrdinaryHasInstance,15,107 +block_count,OrdinaryHasInstance,16,334 +block_count,OrdinaryHasInstance,17,292 block_count,OrdinaryHasInstance,18,42 block_count,OrdinaryHasInstance,19,42 block_count,OrdinaryHasInstance,20,42 block_count,OrdinaryHasInstance,21,0 block_count,OrdinaryHasInstance,22,0 block_count,OrdinaryHasInstance,23,0 -block_count,OrdinaryHasInstance,24,343 -block_count,OrdinaryHasInstance,25,253 -block_count,OrdinaryHasInstance,26,234 +block_count,OrdinaryHasInstance,24,334 +block_count,OrdinaryHasInstance,25,246 +block_count,OrdinaryHasInstance,26,227 block_count,OrdinaryHasInstance,27,19 -block_count,OrdinaryHasInstance,28,89 -block_count,OrdinaryHasInstance,29,109 +block_count,OrdinaryHasInstance,28,87 +block_count,OrdinaryHasInstance,29,107 block_count,OrdinaryHasInstance,30,0 block_count,OrdinaryHasInstance,31,0 block_count,OrdinaryHasInstance,32,0 @@ -37610,9 +37599,9 @@ block_count,SetPrototypeAdd,27,49 block_count,SetPrototypeAdd,28,70 block_count,SetPrototypeAdd,29,70 -block_count,SetPrototypeAdd,30,98 +block_count,SetPrototypeAdd,30,99 block_count,SetPrototypeAdd,31,30 -block_count,SetPrototypeAdd,32,28 +block_count,SetPrototypeAdd,32,29 block_count,SetPrototypeAdd,33,1 block_count,SetPrototypeAdd,34,68 block_count,SetPrototypeAdd,35,0 @@ -37935,10 +37924,10 @@ block_count,SetOrSetIteratorToList,54,0 block_count,SetOrSetIteratorToList,55,0 block_count,SetOrSetIteratorToList,56,0 -block_count,StringFromCharCode,0,15 +block_count,StringFromCharCode,0,20 block_count,StringFromCharCode,1,0 -block_count,StringFromCharCode,2,15 -block_count,StringFromCharCode,3,15 +block_count,StringFromCharCode,2,20 +block_count,StringFromCharCode,3,20 block_count,StringFromCharCode,4,8 block_count,StringFromCharCode,5,8 block_count,StringFromCharCode,6,8 @@ -38009,8 +37998,8 @@ block_count,StringFromCharCode,71,0 block_count,StringFromCharCode,72,0 block_count,StringFromCharCode,73,0 -block_count,StringFromCharCode,74,7 -block_count,StringFromCharCode,75,4 +block_count,StringFromCharCode,74,11 +block_count,StringFromCharCode,75,9 block_count,StringFromCharCode,76,2 block_count,StringFromCharCode,77,2 block_count,StringFromCharCode,78,2 @@ -38020,12 +38009,12 @@ block_count,StringFromCharCode,82,0 block_count,StringFromCharCode,83,2 block_count,StringFromCharCode,84,0 -block_count,StringFromCharCode,85,7 +block_count,StringFromCharCode,85,11 block_count,StringFromCharCode,86,0 block_count,StringFromCharCode,87,0 block_count,StringFromCharCode,88,0 block_count,StringFromCharCode,89,0 -block_count,StringFromCharCode,90,7 +block_count,StringFromCharCode,90,11 block_count,StringPrototypeReplace,0,244 block_count,StringPrototypeReplace,1,0 block_count,StringPrototypeReplace,2,244 @@ -39143,9 +39132,9 @@ block_count,WeakMapLookupHashIndex,30,0 block_count,WeakMapLookupHashIndex,31,73 block_count,WeakMapLookupHashIndex,32,73 -block_count,WeakMapLookupHashIndex,33,107 -block_count,WeakMapLookupHashIndex,34,107 -block_count,WeakMapLookupHashIndex,35,34 +block_count,WeakMapLookupHashIndex,33,109 +block_count,WeakMapLookupHashIndex,34,109 +block_count,WeakMapLookupHashIndex,35,36 block_count,WeakMapLookupHashIndex,36,72 block_count,WeakMapLookupHashIndex,37,0 block_count,WeakMapGet,0,37 @@ -39682,8 +39671,8 @@ block_count,AsyncGeneratorYieldWithAwaitResolveClosure,5,8 block_count,StringAdd_CheckNone,0,8559 block_count,StringAdd_CheckNone,1,8142 -block_count,StringAdd_CheckNone,2,8094 -block_count,StringAdd_CheckNone,3,8094 +block_count,StringAdd_CheckNone,2,8095 +block_count,StringAdd_CheckNone,3,8095 block_count,StringAdd_CheckNone,4,6389 block_count,StringAdd_CheckNone,5,6360 block_count,StringAdd_CheckNone,6,28 @@ -39695,7 +39684,7 @@ block_count,StringAdd_CheckNone,12,6386 block_count,StringAdd_CheckNone,13,6389 block_count,StringAdd_CheckNone,14,0 -block_count,StringAdd_CheckNone,15,6388 +block_count,StringAdd_CheckNone,15,6389 block_count,StringAdd_CheckNone,16,6389 block_count,StringAdd_CheckNone,17,1705 block_count,StringAdd_CheckNone,18,1707 @@ -39793,15 +39782,15 @@ block_count,StringAdd_CheckNone,110,0 block_count,StringAdd_CheckNone,111,0 block_count,StringAdd_CheckNone,112,47 -block_count,StringAdd_CheckNone,113,416 +block_count,StringAdd_CheckNone,113,417 block_count,SubString,0,1649 block_count,SubString,1,1420 block_count,SubString,2,1308 -block_count,SubString,3,1039 +block_count,SubString,3,1040 block_count,SubString,4,1235 block_count,SubString,5,195 block_count,SubString,6,195 -block_count,SubString,7,129 +block_count,SubString,7,130 block_count,SubString,8,7 block_count,SubString,9,122 block_count,SubString,10,65 @@ -39809,8 +39798,8 @@ block_count,SubString,12,0 block_count,SubString,13,195 block_count,SubString,14,0 -block_count,SubString,15,1039 -block_count,SubString,16,1039 +block_count,SubString,15,1040 +block_count,SubString,16,1040 block_count,SubString,17,451 block_count,SubString,18,1 block_count,SubString,19,0 @@ -39893,10 +39882,10 @@ block_count,SubString,96,0 block_count,SubString,97,567 block_count,SubString,98,1368 -block_count,SubString,99,800 +block_count,SubString,99,801 block_count,SubString,100,567 block_count,SubString,101,567 -block_count,SubString,102,411 +block_count,SubString,102,412 block_count,SubString,103,155 block_count,SubString,104,567 block_count,SubString,105,0 @@ -39987,15 +39976,15 @@ block_count,SubString,190,0 block_count,SubString,191,268 block_count,SubString,192,403 -block_count,SubString,193,134 -block_count,SubString,194,134 +block_count,SubString,193,135 +block_count,SubString,194,135 block_count,SubString,195,133 block_count,SubString,196,0 block_count,SubString,197,132 block_count,SubString,198,1 block_count,SubString,199,1 block_count,SubString,200,0 -block_count,SubString,201,134 +block_count,SubString,201,135 block_count,SubString,202,0 block_count,SubString,203,0 block_count,SubString,204,0 @@ -40055,10 +40044,10 @@ block_count,GetProperty,30,0 block_count,GetProperty,31,88 block_count,GetProperty,32,707 -block_count,GetProperty,33,1761 -block_count,GetProperty,34,1761 +block_count,GetProperty,33,1762 +block_count,GetProperty,34,1762 block_count,GetProperty,35,1761 -block_count,GetProperty,36,1738 +block_count,GetProperty,36,1739 block_count,GetProperty,37,309 block_count,GetProperty,38,309 block_count,GetProperty,39,0 @@ -40089,15 +40078,15 @@ block_count,GetProperty,64,1429 block_count,GetProperty,65,322 block_count,GetProperty,66,1107 -block_count,GetProperty,67,2764 +block_count,GetProperty,67,2765 block_count,GetProperty,68,2446 block_count,GetProperty,69,2325 block_count,GetProperty,70,1657 -block_count,GetProperty,71,667 +block_count,GetProperty,71,668 block_count,GetProperty,72,120 block_count,GetProperty,73,318 block_count,GetProperty,74,990 -block_count,GetProperty,75,441 +block_count,GetProperty,75,442 block_count,GetProperty,76,548 block_count,GetProperty,77,539 block_count,GetProperty,78,9 @@ -40157,7 +40146,7 @@ block_count,GetProperty,132,0 block_count,GetProperty,133,0 block_count,GetProperty,134,0 -block_count,GetProperty,135,1064 +block_count,GetProperty,135,1065 block_count,GetProperty,136,1063 block_count,GetProperty,137,1 block_count,GetProperty,138,0 @@ -40197,8 +40186,8 @@ block_count,GetProperty,172,0 block_count,GetProperty,173,0 block_count,GetProperty,174,0 -block_count,GetProperty,175,1064 -block_count,GetProperty,176,1054 +block_count,GetProperty,175,1065 +block_count,GetProperty,176,1055 block_count,GetProperty,177,9 block_count,GetProperty,178,697 block_count,GetProperty,179,2 @@ -44034,7 +44023,7 @@ block_count,ArrayPrototypeJoin,195,834 block_count,ArrayPrototypeJoin,196,834 block_count,ArrayPrototypeJoin,197,180 -block_count,ArrayPrototypeJoin,198,653 +block_count,ArrayPrototypeJoin,198,654 block_count,ArrayPrototypeJoin,199,834 block_count,ArrayPrototypeJoin,200,834 block_count,ArrayPrototypeJoin,201,834 @@ -45296,19 +45285,19 @@ block_count,ArrayMapLoopContinuation,329,0 block_count,ArrayMapLoopContinuation,330,0 block_count,ArrayMapLoopContinuation,331,0 -block_count,ArrayMap,0,27 +block_count,ArrayMap,0,26 block_count,ArrayMap,1,0 -block_count,ArrayMap,2,27 -block_count,ArrayMap,3,27 -block_count,ArrayMap,4,27 -block_count,ArrayMap,5,27 +block_count,ArrayMap,2,26 +block_count,ArrayMap,3,26 +block_count,ArrayMap,4,26 +block_count,ArrayMap,5,26 block_count,ArrayMap,6,0 -block_count,ArrayMap,7,27 +block_count,ArrayMap,7,26 block_count,ArrayMap,8,0 block_count,ArrayMap,9,0 -block_count,ArrayMap,10,27 -block_count,ArrayMap,11,27 -block_count,ArrayMap,12,27 +block_count,ArrayMap,10,26 +block_count,ArrayMap,11,26 +block_count,ArrayMap,12,26 block_count,ArrayMap,13,0 block_count,ArrayMap,14,0 block_count,ArrayMap,15,0 @@ -45336,24 +45325,24 @@ block_count,ArrayMap,37,0 block_count,ArrayMap,38,0 block_count,ArrayMap,39,0 -block_count,ArrayMap,40,27 -block_count,ArrayMap,41,27 -block_count,ArrayMap,42,27 +block_count,ArrayMap,40,26 +block_count,ArrayMap,41,26 +block_count,ArrayMap,42,26 block_count,ArrayMap,43,0 -block_count,ArrayMap,44,27 +block_count,ArrayMap,44,26 block_count,ArrayMap,45,0 -block_count,ArrayMap,46,27 -block_count,ArrayMap,47,27 -block_count,ArrayMap,48,27 -block_count,ArrayMap,49,27 -block_count,ArrayMap,50,27 -block_count,ArrayMap,51,27 +block_count,ArrayMap,46,26 +block_count,ArrayMap,47,26 +block_count,ArrayMap,48,26 +block_count,ArrayMap,49,26 +block_count,ArrayMap,50,26 +block_count,ArrayMap,51,26 block_count,ArrayMap,52,0 -block_count,ArrayMap,53,27 -block_count,ArrayMap,54,27 -block_count,ArrayMap,55,27 -block_count,ArrayMap,56,27 -block_count,ArrayMap,57,9 +block_count,ArrayMap,53,26 +block_count,ArrayMap,54,26 +block_count,ArrayMap,55,26 +block_count,ArrayMap,56,26 +block_count,ArrayMap,57,8 block_count,ArrayMap,58,18 block_count,ArrayMap,59,18 block_count,ArrayMap,60,18 @@ -45374,7 +45363,7 @@ block_count,ArrayMap,75,15 block_count,ArrayMap,76,18 block_count,ArrayMap,77,0 -block_count,ArrayMap,78,27 +block_count,ArrayMap,78,26 block_count,ArrayMap,79,66 block_count,ArrayMap,80,39 block_count,ArrayMap,81,39 @@ -45498,7 +45487,7 @@ block_count,ArrayMap,199,0 block_count,ArrayMap,200,0 block_count,ArrayMap,201,0 -block_count,ArrayMap,202,27 +block_count,ArrayMap,202,26 block_count,ArrayMap,203,10 block_count,ArrayMap,204,16 block_count,ArrayMap,205,16 @@ -45507,9 +45496,9 @@ block_count,ArrayMap,208,16 block_count,ArrayMap,209,0 block_count,ArrayMap,210,16 -block_count,ArrayMap,211,27 -block_count,ArrayMap,212,27 -block_count,ArrayMap,213,27 +block_count,ArrayMap,211,26 +block_count,ArrayMap,212,26 +block_count,ArrayMap,213,26 block_count,ArrayMap,214,0 block_count,ArrayMap,215,0 block_count,ArrayMap,216,0 @@ -45518,9 +45507,9 @@ block_count,ArrayMap,219,0 block_count,ArrayMap,220,0 block_count,ArrayMap,221,0 -block_count,ArrayMap,222,27 +block_count,ArrayMap,222,26 block_count,ArrayMap,223,0 -block_count,ArrayMap,224,27 +block_count,ArrayMap,224,26 block_count,ArrayMap,225,26 block_count,ArrayMap,226,0 block_count,ArrayMap,227,26 @@ -45875,7 +45864,7 @@ block_count,ArrayPrototypeShift,42,0 block_count,ArrayPrototypeShift,43,194 block_count,ArrayPrototypeShift,44,194 -block_count,ArrayPrototypeShift,45,193 +block_count,ArrayPrototypeShift,45,194 block_count,ArrayPrototypeShift,46,193 block_count,ArrayPrototypeShift,47,190 block_count,ArrayPrototypeShift,48,190 @@ -46074,7 +46063,7 @@ block_count,ArrayPrototypeSlice,127,30 block_count,ArrayPrototypeSlice,128,27 block_count,ArrayPrototypeSlice,129,7 -block_count,ArrayPrototypeSlice,130,19 +block_count,ArrayPrototypeSlice,130,20 block_count,ArrayPrototypeSlice,131,3 block_count,ArrayPrototypeSlice,132,23 block_count,ArrayPrototypeSlice,133,18 @@ -47034,8 +47023,8 @@ block_count,ArrayPrototypeSplice,536,0 block_count,ArrayPrototypeSplice,537,0 block_count,ArrayPrototypeSplice,538,0 -block_count,ArrayPrototypeSplice,539,7 -block_count,ArrayPrototypeSplice,540,7 +block_count,ArrayPrototypeSplice,539,0 +block_count,ArrayPrototypeSplice,540,0 block_count,ArrayPrototypeSplice,541,0 block_count,ArrayPrototypeSplice,542,0 block_count,ArrayPrototypeSplice,543,0 @@ -47644,7 +47633,7 @@ block_count,ToString,108,0 block_count,ToString,109,19 block_count,ToString,110,19 -block_count,ToString,111,17 +block_count,ToString,111,18 block_count,ToString,112,17 block_count,ToString,113,0 block_count,ToString,114,0 @@ -47727,17 +47716,17 @@ block_count,StringPrototypeCharAt,12,0 block_count,StringPrototypeCharAt,13,127 block_count,StringPrototypeCharAt,14,127 -block_count,StringPrototypeCharAt,15,125 +block_count,StringPrototypeCharAt,15,124 block_count,StringPrototypeCharAt,16,195 -block_count,StringPrototypeCharAt,17,69 -block_count,StringPrototypeCharAt,18,69 +block_count,StringPrototypeCharAt,17,70 +block_count,StringPrototypeCharAt,18,70 block_count,StringPrototypeCharAt,19,66 block_count,StringPrototypeCharAt,20,0 block_count,StringPrototypeCharAt,21,65 -block_count,StringPrototypeCharAt,22,3 -block_count,StringPrototypeCharAt,23,3 +block_count,StringPrototypeCharAt,22,4 +block_count,StringPrototypeCharAt,23,4 block_count,StringPrototypeCharAt,24,0 -block_count,StringPrototypeCharAt,25,69 +block_count,StringPrototypeCharAt,25,70 block_count,StringPrototypeCharAt,26,0 block_count,StringPrototypeCharAt,27,0 block_count,StringPrototypeCharAt,28,0 @@ -47750,16 +47739,16 @@ block_count,StringPrototypeCharAt,35,0 block_count,StringPrototypeCharAt,36,0 block_count,StringPrototypeCharAt,37,0 -block_count,StringPrototypeCharAt,38,125 -block_count,StringPrototypeCharAt,39,125 +block_count,StringPrototypeCharAt,38,124 +block_count,StringPrototypeCharAt,39,124 block_count,StringPrototypeCharAt,40,15 block_count,StringPrototypeCharAt,41,109 -block_count,StringPrototypeCharAt,42,125 +block_count,StringPrototypeCharAt,42,124 block_count,StringPrototypeCharAt,43,0 block_count,StringPrototypeCharAt,44,0 block_count,StringPrototypeCharAt,45,0 block_count,StringPrototypeCharAt,46,0 -block_count,StringPrototypeCharAt,47,125 +block_count,StringPrototypeCharAt,47,124 block_count,StringPrototypeCharAt,48,2 block_count,StringPrototypeCharCodeAt,0,67 block_count,StringPrototypeCharCodeAt,1,0 @@ -47778,15 +47767,15 @@ block_count,StringPrototypeCharCodeAt,14,67 block_count,StringPrototypeCharCodeAt,15,67 block_count,StringPrototypeCharCodeAt,16,75 -block_count,StringPrototypeCharCodeAt,17,7 -block_count,StringPrototypeCharCodeAt,18,7 +block_count,StringPrototypeCharCodeAt,17,8 +block_count,StringPrototypeCharCodeAt,18,8 block_count,StringPrototypeCharCodeAt,19,0 block_count,StringPrototypeCharCodeAt,20,0 block_count,StringPrototypeCharCodeAt,21,0 block_count,StringPrototypeCharCodeAt,22,7 block_count,StringPrototypeCharCodeAt,23,7 block_count,StringPrototypeCharCodeAt,24,0 -block_count,StringPrototypeCharCodeAt,25,7 +block_count,StringPrototypeCharCodeAt,25,8 block_count,StringPrototypeCharCodeAt,26,0 block_count,StringPrototypeCharCodeAt,27,0 block_count,StringPrototypeCharCodeAt,28,0 @@ -48388,7 +48377,7 @@ block_count,StringCharAt,30,0 block_count,StringCharAt,31,0 block_count,StringCharAt,32,9 -block_count,FastNewClosureBaseline,0,32 +block_count,FastNewClosureBaseline,0,33 block_count,FastNewFunctionContextFunction,0,61 block_count,FastNewFunctionContextFunction,1,61 block_count,FastNewFunctionContextFunction,2,0 @@ -48402,21 +48391,21 @@ block_count,FastNewFunctionContextFunction,10,61 block_count,FastNewFunctionContextFunction,11,10 block_count,FastNewFunctionContextFunction,12,51 -block_count,FastNewFunctionContextFunction,13,872 +block_count,FastNewFunctionContextFunction,13,873 block_count,FastNewFunctionContextFunction,14,821 block_count,FastNewFunctionContextFunction,15,51 block_count,FastNewFunctionContextFunction,16,61 block_count,FastNewFunctionContextFunction,17,46 block_count,FastNewFunctionContextFunction,18,15 -block_count,CreateRegExpLiteral,0,11 -block_count,CreateRegExpLiteral,1,11 +block_count,CreateRegExpLiteral,0,12 +block_count,CreateRegExpLiteral,1,12 block_count,CreateRegExpLiteral,2,0 -block_count,CreateRegExpLiteral,3,11 +block_count,CreateRegExpLiteral,3,12 block_count,CreateRegExpLiteral,4,0 -block_count,CreateRegExpLiteral,5,11 -block_count,CreateRegExpLiteral,6,11 +block_count,CreateRegExpLiteral,5,12 +block_count,CreateRegExpLiteral,6,12 block_count,CreateRegExpLiteral,7,0 -block_count,CreateRegExpLiteral,8,11 +block_count,CreateRegExpLiteral,8,12 block_count,CreateRegExpLiteral,9,0 block_count,CreateRegExpLiteral,10,0 block_count,CreateShallowArrayLiteral,0,8 @@ -48508,14 +48497,14 @@ block_count,CreateShallowObjectLiteral,0,16 block_count,CreateShallowObjectLiteral,1,16 block_count,CreateShallowObjectLiteral,2,0 -block_count,CreateShallowObjectLiteral,3,15 -block_count,CreateShallowObjectLiteral,4,15 -block_count,CreateShallowObjectLiteral,5,15 -block_count,CreateShallowObjectLiteral,6,15 +block_count,CreateShallowObjectLiteral,3,16 +block_count,CreateShallowObjectLiteral,4,16 +block_count,CreateShallowObjectLiteral,5,16 +block_count,CreateShallowObjectLiteral,6,16 block_count,CreateShallowObjectLiteral,7,0 -block_count,CreateShallowObjectLiteral,8,15 +block_count,CreateShallowObjectLiteral,8,16 block_count,CreateShallowObjectLiteral,9,0 -block_count,CreateShallowObjectLiteral,10,15 +block_count,CreateShallowObjectLiteral,10,16 block_count,CreateShallowObjectLiteral,11,0 block_count,CreateShallowObjectLiteral,12,0 block_count,CreateShallowObjectLiteral,13,0 @@ -48557,7 +48546,7 @@ block_count,CreateShallowObjectLiteral,49,0 block_count,CreateShallowObjectLiteral,50,0 block_count,CreateShallowObjectLiteral,51,0 -block_count,CreateShallowObjectLiteral,52,15 +block_count,CreateShallowObjectLiteral,52,16 block_count,CreateShallowObjectLiteral,53,0 block_count,CreateShallowObjectLiteral,54,0 block_count,CreateShallowObjectLiteral,55,0 @@ -48619,17 +48608,17 @@ block_count,CreateShallowObjectLiteral,111,0 block_count,CreateShallowObjectLiteral,112,0 block_count,CreateShallowObjectLiteral,113,0 -block_count,CreateShallowObjectLiteral,114,15 -block_count,CreateShallowObjectLiteral,115,15 -block_count,CreateShallowObjectLiteral,116,15 +block_count,CreateShallowObjectLiteral,114,16 +block_count,CreateShallowObjectLiteral,115,16 +block_count,CreateShallowObjectLiteral,116,16 block_count,CreateShallowObjectLiteral,117,0 -block_count,CreateShallowObjectLiteral,118,15 +block_count,CreateShallowObjectLiteral,118,16 block_count,CreateShallowObjectLiteral,119,0 block_count,CreateShallowObjectLiteral,120,0 -block_count,CreateShallowObjectLiteral,121,15 -block_count,CreateShallowObjectLiteral,122,15 -block_count,CreateShallowObjectLiteral,123,41 -block_count,CreateShallowObjectLiteral,124,34 +block_count,CreateShallowObjectLiteral,121,16 +block_count,CreateShallowObjectLiteral,122,16 +block_count,CreateShallowObjectLiteral,123,44 +block_count,CreateShallowObjectLiteral,124,37 block_count,CreateShallowObjectLiteral,125,0 block_count,CreateShallowObjectLiteral,126,0 block_count,CreateShallowObjectLiteral,127,0 @@ -48656,11 +48645,11 @@ block_count,CreateShallowObjectLiteral,148,0 block_count,CreateShallowObjectLiteral,149,0 block_count,CreateShallowObjectLiteral,150,0 -block_count,CreateShallowObjectLiteral,151,34 +block_count,CreateShallowObjectLiteral,151,37 block_count,CreateShallowObjectLiteral,152,6 -block_count,CreateShallowObjectLiteral,153,40 -block_count,CreateShallowObjectLiteral,154,25 -block_count,CreateShallowObjectLiteral,155,15 +block_count,CreateShallowObjectLiteral,153,43 +block_count,CreateShallowObjectLiteral,154,27 +block_count,CreateShallowObjectLiteral,155,16 block_count,CreateShallowObjectLiteral,156,0 block_count,CreateShallowObjectLiteral,157,0 block_count,CreateShallowObjectLiteral,158,0 @@ -48890,8 +48879,8 @@ block_count,ToBoolean,16,0 block_count,ToBoolean,17,0 block_count,ToBoolean,18,0 -block_count,ToBooleanForBaselineJump,0,407 -block_count,ToBooleanForBaselineJump,1,377 +block_count,ToBooleanForBaselineJump,0,413 +block_count,ToBooleanForBaselineJump,1,383 block_count,ToBooleanForBaselineJump,2,153 block_count,ToBooleanForBaselineJump,3,67 block_count,ToBooleanForBaselineJump,4,67 @@ -48904,11 +48893,11 @@ block_count,ToBooleanForBaselineJump,11,0 block_count,ToBooleanForBaselineJump,12,0 block_count,ToBooleanForBaselineJump,13,0 -block_count,ToBooleanForBaselineJump,14,85 -block_count,ToBooleanForBaselineJump,15,224 +block_count,ToBooleanForBaselineJump,14,86 +block_count,ToBooleanForBaselineJump,15,229 block_count,ToBooleanForBaselineJump,16,29 block_count,ToBooleanForBaselineJump,17,17 -block_count,ToBooleanForBaselineJump,18,12 +block_count,ToBooleanForBaselineJump,18,11 block_count,ToLength,0,2 block_count,ToLength,1,2 block_count,ToLength,2,0 @@ -49663,21 +49652,21 @@ block_count,FunctionPrototypeHasInstance,1,0 block_count,FunctionPrototypeHasInstance,2,46 block_count,FunctionPrototypeHasInstance,3,46 -block_count,FunctionPrototypeHasInstance,4,46 -block_count,FunctionPrototypeHasInstance,5,46 +block_count,FunctionPrototypeHasInstance,4,45 +block_count,FunctionPrototypeHasInstance,5,45 block_count,FunctionPrototypeHasInstance,6,0 -block_count,FunctionPrototypeHasInstance,7,46 +block_count,FunctionPrototypeHasInstance,7,45 block_count,FunctionPrototypeHasInstance,8,0 block_count,FunctionPrototypeHasInstance,9,0 block_count,FunctionPrototypeHasInstance,10,0 -block_count,FunctionPrototypeHasInstance,11,46 -block_count,FunctionPrototypeHasInstance,12,46 -block_count,FunctionPrototypeHasInstance,13,46 +block_count,FunctionPrototypeHasInstance,11,45 +block_count,FunctionPrototypeHasInstance,12,45 +block_count,FunctionPrototypeHasInstance,13,45 block_count,FunctionPrototypeHasInstance,14,1 block_count,FunctionPrototypeHasInstance,15,1 block_count,FunctionPrototypeHasInstance,16,0 -block_count,FunctionPrototypeHasInstance,17,44 -block_count,FunctionPrototypeHasInstance,18,46 +block_count,FunctionPrototypeHasInstance,17,43 +block_count,FunctionPrototypeHasInstance,18,45 block_count,FunctionPrototypeHasInstance,19,145 block_count,FunctionPrototypeHasInstance,20,142 block_count,FunctionPrototypeHasInstance,21,2 @@ -49691,7 +49680,7 @@ block_count,FunctionPrototypeHasInstance,29,99 block_count,FunctionPrototypeHasInstance,30,19 block_count,FunctionPrototypeHasInstance,31,26 -block_count,FunctionPrototypeHasInstance,32,46 +block_count,FunctionPrototypeHasInstance,32,45 block_count,FunctionPrototypeHasInstance,33,0 block_count,FunctionPrototypeHasInstance,34,0 block_count,FunctionPrototypeHasInstance,35,0 @@ -49769,11 +49758,11 @@ block_count,ForInNext,3,11 block_count,ForInNext,4,0 block_count,ForInNext,5,11 -block_count,ForInNext,6,23 +block_count,ForInNext,6,22 block_count,GetIteratorWithFeedback,0,0 block_count,GetIteratorWithFeedback,1,0 block_count,GetIteratorWithFeedback,2,0 -block_count,GetIteratorBaseline,0,12 +block_count,GetIteratorBaseline,0,13 block_count,CallIteratorWithFeedback,0,13 block_count,CallIteratorWithFeedback,1,13 block_count,CallIteratorWithFeedback,2,0 @@ -50057,7 +50046,7 @@ block_count,MathMin,10,1 block_count,MathMin,11,1 block_count,MathMin,12,0 -block_count,MathMin,13,6 +block_count,MathMin,13,5 block_count,MathMin,14,7 block_count,MathMin,15,3 block_count,MathMin,16,0 @@ -50651,9 +50640,9 @@ block_count,ParseInt,28,6 block_count,ParseInt,29,4 block_count,ParseInt,30,71 -block_count,NumberParseInt,0,7 +block_count,NumberParseInt,0,6 block_count,NumberParseInt,1,0 -block_count,NumberParseInt,2,7 +block_count,NumberParseInt,2,6 block_count,Add,0,47 block_count,Add,1,48 block_count,Add,2,1 @@ -51076,7 +51065,7 @@ block_count,GreaterThan,51,467 block_count,GreaterThan,52,467 block_count,GreaterThan,53,0 -block_count,GreaterThan,54,538 +block_count,GreaterThan,54,539 block_count,GreaterThan,55,102 block_count,GreaterThan,56,0 block_count,GreaterThan,57,0 @@ -51339,7 +51328,7 @@ block_count,StrictEqual,55,0 block_count,StrictEqual,56,0 block_count,StrictEqual,57,0 -block_count,StrictEqual,58,26 +block_count,StrictEqual,58,27 block_count,StrictEqual,59,161 block_count,StrictEqual,60,159 block_count,StrictEqual,61,159 @@ -52884,8 +52873,8 @@ block_count,RegExpPrototypeExec,136,26 block_count,RegExpPrototypeExec,137,26 block_count,RegExpPrototypeExec,138,27 -block_count,RegExpPrototypeExec,139,0 -block_count,RegExpPrototypeExec,140,0 +block_count,RegExpPrototypeExec,139,1 +block_count,RegExpPrototypeExec,140,1 block_count,RegExpPrototypeExec,141,0 block_count,RegExpPrototypeExec,142,0 block_count,RegExpPrototypeExec,143,0 @@ -52908,7 +52897,7 @@ block_count,RegExpPrototypeExec,160,0 block_count,RegExpPrototypeExec,161,0 block_count,RegExpPrototypeExec,162,0 -block_count,RegExpPrototypeExec,163,0 +block_count,RegExpPrototypeExec,163,1 block_count,RegExpPrototypeExec,164,0 block_count,RegExpPrototypeExec,165,26 block_count,RegExpPrototypeExec,166,26 @@ -52986,11 +52975,11 @@ block_count,RegExpPrototypeExec,238,0 block_count,RegExpPrototypeExec,239,0 block_count,RegExpPrototypeExec,240,0 -block_count,RegExpPrototypeExec,241,169 -block_count,RegExpPrototypeExec,242,169 +block_count,RegExpPrototypeExec,241,170 +block_count,RegExpPrototypeExec,242,170 block_count,RegExpPrototypeExec,243,0 -block_count,RegExpPrototypeExec,244,169 -block_count,RegExpPrototypeExec,245,169 +block_count,RegExpPrototypeExec,244,170 +block_count,RegExpPrototypeExec,245,170 block_count,RegExpPrototypeExec,246,0 block_count,RegExpPrototypeExec,247,0 block_count,RegExpPrototypeExec,248,0 @@ -53005,18 +52994,18 @@ block_count,RegExpPrototypeExec,257,0 block_count,RegExpPrototypeExec,258,0 block_count,RegExpPrototypeExec,259,0 -block_count,RegExpPrototypeExec,260,169 +block_count,RegExpPrototypeExec,260,170 block_count,RegExpPrototypeExec,261,169 block_count,RegExpPrototypeExec,262,0 block_count,RegExpPrototypeExec,263,169 block_count,RegExpPrototypeExec,264,0 block_count,RegExpPrototypeExec,265,0 -block_count,RegExpPrototypeExec,266,169 +block_count,RegExpPrototypeExec,266,170 block_count,RegExpPrototypeExec,267,0 block_count,RegExpPrototypeExec,268,0 block_count,RegExpPrototypeExec,269,0 block_count,RegExpPrototypeExec,270,0 -block_count,RegExpPrototypeExec,271,169 +block_count,RegExpPrototypeExec,271,170 block_count,RegExpPrototypeExec,272,0 block_count,RegExpPrototypeExec,273,0 block_count,RegExpPrototypeExec,274,0 @@ -53047,24 +53036,24 @@ block_count,RegExpPrototypeExec,299,0 block_count,RegExpPrototypeExec,300,0 block_count,RegExpPrototypeExec,301,0 -block_count,RegExpPrototypeExec,302,169 +block_count,RegExpPrototypeExec,302,170 block_count,RegExpPrototypeExec,303,0 -block_count,RegExpPrototypeExec,304,169 -block_count,RegExpPrototypeExec,305,169 -block_count,RegExpPrototypeExec,306,169 +block_count,RegExpPrototypeExec,304,170 +block_count,RegExpPrototypeExec,305,170 +block_count,RegExpPrototypeExec,306,170 block_count,RegExpPrototypeExec,307,0 -block_count,RegExpPrototypeExec,308,169 +block_count,RegExpPrototypeExec,308,170 block_count,RegExpPrototypeExec,309,0 -block_count,RegExpPrototypeExec,310,169 +block_count,RegExpPrototypeExec,310,170 block_count,RegExpPrototypeExec,311,73 block_count,RegExpPrototypeExec,312,96 block_count,RegExpPrototypeExec,313,464 block_count,RegExpPrototypeExec,314,368 block_count,RegExpPrototypeExec,315,96 -block_count,RegExpPrototypeExec,316,169 +block_count,RegExpPrototypeExec,316,170 block_count,RegExpPrototypeExec,317,82 block_count,RegExpPrototypeExec,318,87 -block_count,RegExpPrototypeExec,319,169 +block_count,RegExpPrototypeExec,319,170 block_count,RegExpPrototypeExec,320,96 block_count,RegExpPrototypeExec,321,846 block_count,RegExpPrototypeExec,322,347 @@ -53180,10 +53169,10 @@ block_count,RegExpPrototypeExec,432,0 block_count,RegExpPrototypeExec,433,96 block_count,RegExpPrototypeExec,434,73 -block_count,RegExpPrototypeExec,435,169 -block_count,RegExpPrototypeExec,436,169 +block_count,RegExpPrototypeExec,435,170 +block_count,RegExpPrototypeExec,436,170 block_count,RegExpPrototypeExec,437,0 -block_count,RegExpPrototypeExec,438,169 +block_count,RegExpPrototypeExec,438,170 block_count,RegExpPrototypeExec,439,248 block_count,RegExpPrototypeExec,440,418 block_count,RegExpMatchFast,0,1235 @@ -54412,7 +54401,7 @@ block_count,RegExpReplace,339,0 block_count,RegExpReplace,340,1 block_count,RegExpReplace,341,2 -block_count,RegExpReplace,342,2 +block_count,RegExpReplace,342,1 block_count,RegExpReplace,343,0 block_count,RegExpReplace,344,0 block_count,RegExpReplace,345,0 @@ -55424,31 +55413,31 @@ block_count,RegExpSplit,520,0 block_count,RegExpSplit,521,13 block_count,RegExpSplit,522,13 -block_count,RegExpPrototypeTest,0,114 +block_count,RegExpPrototypeTest,0,115 block_count,RegExpPrototypeTest,1,0 -block_count,RegExpPrototypeTest,2,114 -block_count,RegExpPrototypeTest,3,114 -block_count,RegExpPrototypeTest,4,114 -block_count,RegExpPrototypeTest,5,114 -block_count,RegExpPrototypeTest,6,114 +block_count,RegExpPrototypeTest,2,115 +block_count,RegExpPrototypeTest,3,115 +block_count,RegExpPrototypeTest,4,115 +block_count,RegExpPrototypeTest,5,115 +block_count,RegExpPrototypeTest,6,115 block_count,RegExpPrototypeTest,7,38 -block_count,RegExpPrototypeTest,8,75 +block_count,RegExpPrototypeTest,8,76 block_count,RegExpPrototypeTest,9,0 block_count,RegExpPrototypeTest,10,38 -block_count,RegExpPrototypeTest,11,114 -block_count,RegExpPrototypeTest,12,114 +block_count,RegExpPrototypeTest,11,115 +block_count,RegExpPrototypeTest,12,115 block_count,RegExpPrototypeTest,13,0 -block_count,RegExpPrototypeTest,14,114 +block_count,RegExpPrototypeTest,14,115 block_count,RegExpPrototypeTest,15,0 -block_count,RegExpPrototypeTest,16,114 +block_count,RegExpPrototypeTest,16,115 block_count,RegExpPrototypeTest,17,0 -block_count,RegExpPrototypeTest,18,114 +block_count,RegExpPrototypeTest,18,115 block_count,RegExpPrototypeTest,19,0 -block_count,RegExpPrototypeTest,20,114 +block_count,RegExpPrototypeTest,20,115 block_count,RegExpPrototypeTest,21,0 -block_count,RegExpPrototypeTest,22,114 +block_count,RegExpPrototypeTest,22,115 block_count,RegExpPrototypeTest,23,0 -block_count,RegExpPrototypeTest,24,114 +block_count,RegExpPrototypeTest,24,115 block_count,RegExpPrototypeTest,25,0 block_count,RegExpPrototypeTest,26,0 block_count,RegExpPrototypeTest,27,0 @@ -55477,17 +55466,17 @@ block_count,RegExpPrototypeTest,50,0 block_count,RegExpPrototypeTest,51,0 block_count,RegExpPrototypeTest,52,0 -block_count,RegExpPrototypeTest,53,114 -block_count,RegExpPrototypeTest,54,114 +block_count,RegExpPrototypeTest,53,115 +block_count,RegExpPrototypeTest,54,115 block_count,RegExpPrototypeTest,55,113 block_count,RegExpPrototypeTest,56,1 -block_count,RegExpPrototypeTest,57,114 -block_count,RegExpPrototypeTest,58,114 -block_count,RegExpPrototypeTest,59,114 +block_count,RegExpPrototypeTest,57,115 +block_count,RegExpPrototypeTest,58,115 +block_count,RegExpPrototypeTest,59,115 block_count,RegExpPrototypeTest,60,0 block_count,RegExpPrototypeTest,61,0 block_count,RegExpPrototypeTest,62,0 -block_count,RegExpPrototypeTest,63,114 +block_count,RegExpPrototypeTest,63,115 block_count,RegExpPrototypeTest,64,132 block_count,RegExpPrototypeTest,65,56 block_count,RegExpPrototypeTest,66,56 @@ -55517,7 +55506,7 @@ block_count,RegExpPrototypeTest,90,0 block_count,RegExpPrototypeTest,91,76 block_count,RegExpPrototypeTest,92,76 -block_count,RegExpPrototypeTest,93,114 +block_count,RegExpPrototypeTest,93,115 block_count,RegExpPrototypeTest,94,0 block_count,RegExpPrototypeTest,95,113 block_count,RegExpPrototypeTest,96,1 @@ -55533,8 +55522,8 @@ block_count,RegExpPrototypeTest,106,0 block_count,RegExpPrototypeTest,107,0 block_count,RegExpPrototypeTest,108,0 -block_count,RegExpPrototypeTest,109,112 -block_count,RegExpPrototypeTest,110,112 +block_count,RegExpPrototypeTest,109,113 +block_count,RegExpPrototypeTest,110,113 block_count,RegExpPrototypeTest,111,0 block_count,RegExpPrototypeTest,112,113 block_count,RegExpPrototypeTest,113,0 @@ -55555,7 +55544,7 @@ block_count,RegExpPrototypeTest,128,0 block_count,RegExpPrototypeTest,129,0 block_count,RegExpPrototypeTest,130,0 -block_count,RegExpPrototypeTest,131,114 +block_count,RegExpPrototypeTest,131,115 block_count,RegExpPrototypeTest,132,15 block_count,RegExpPrototypeTest,133,0 block_count,RegExpPrototypeTest,134,15 @@ -55579,22 +55568,22 @@ block_count,RegExpPrototypeTest,152,15 block_count,RegExpPrototypeTest,153,0 block_count,RegExpPrototypeTest,154,15 -block_count,RegExpPrototypeTest,155,98 -block_count,RegExpPrototypeTest,156,98 +block_count,RegExpPrototypeTest,155,99 +block_count,RegExpPrototypeTest,156,99 block_count,RegExpPrototypeTest,157,0 -block_count,RegExpPrototypeTest,158,98 -block_count,RegExpPrototypeTestFast,0,427 -block_count,RegExpPrototypeTestFast,1,427 -block_count,RegExpPrototypeTestFast,2,422 +block_count,RegExpPrototypeTest,158,99 +block_count,RegExpPrototypeTestFast,0,426 +block_count,RegExpPrototypeTestFast,1,426 +block_count,RegExpPrototypeTestFast,2,421 block_count,RegExpPrototypeTestFast,3,4 -block_count,RegExpPrototypeTestFast,4,427 -block_count,RegExpPrototypeTestFast,5,427 -block_count,RegExpPrototypeTestFast,6,427 +block_count,RegExpPrototypeTestFast,4,426 +block_count,RegExpPrototypeTestFast,5,426 +block_count,RegExpPrototypeTestFast,6,426 block_count,RegExpPrototypeTestFast,7,0 block_count,RegExpPrototypeTestFast,8,0 block_count,RegExpPrototypeTestFast,9,0 -block_count,RegExpPrototypeTestFast,10,427 -block_count,RegExpPrototypeTestFast,11,547 +block_count,RegExpPrototypeTestFast,10,426 +block_count,RegExpPrototypeTestFast,11,546 block_count,RegExpPrototypeTestFast,12,120 block_count,RegExpPrototypeTestFast,13,120 block_count,RegExpPrototypeTestFast,14,120 @@ -55621,28 +55610,28 @@ block_count,RegExpPrototypeTestFast,35,0 block_count,RegExpPrototypeTestFast,36,120 block_count,RegExpPrototypeTestFast,37,0 -block_count,RegExpPrototypeTestFast,38,427 -block_count,RegExpPrototypeTestFast,39,427 -block_count,RegExpPrototypeTestFast,40,427 +block_count,RegExpPrototypeTestFast,38,426 +block_count,RegExpPrototypeTestFast,39,426 +block_count,RegExpPrototypeTestFast,40,426 block_count,RegExpPrototypeTestFast,41,0 -block_count,RegExpPrototypeTestFast,42,422 +block_count,RegExpPrototypeTestFast,42,421 block_count,RegExpPrototypeTestFast,43,4 block_count,RegExpPrototypeTestFast,44,0 -block_count,RegExpPrototypeTestFast,45,422 -block_count,RegExpPrototypeTestFast,46,422 +block_count,RegExpPrototypeTestFast,45,421 +block_count,RegExpPrototypeTestFast,46,421 block_count,RegExpPrototypeTestFast,47,0 block_count,RegExpPrototypeTestFast,48,0 block_count,RegExpPrototypeTestFast,49,0 block_count,RegExpPrototypeTestFast,50,0 block_count,RegExpPrototypeTestFast,51,0 -block_count,RegExpPrototypeTestFast,52,422 +block_count,RegExpPrototypeTestFast,52,421 block_count,RegExpPrototypeTestFast,53,0 block_count,RegExpPrototypeTestFast,54,0 block_count,RegExpPrototypeTestFast,55,0 -block_count,RegExpPrototypeTestFast,56,422 -block_count,RegExpPrototypeTestFast,57,422 +block_count,RegExpPrototypeTestFast,56,421 +block_count,RegExpPrototypeTestFast,57,421 block_count,RegExpPrototypeTestFast,58,0 -block_count,RegExpPrototypeTestFast,59,422 +block_count,RegExpPrototypeTestFast,59,421 block_count,RegExpPrototypeTestFast,60,0 block_count,RegExpPrototypeTestFast,61,0 block_count,RegExpPrototypeTestFast,62,0 @@ -55656,12 +55645,12 @@ block_count,RegExpPrototypeTestFast,70,0 block_count,RegExpPrototypeTestFast,71,0 block_count,RegExpPrototypeTestFast,72,0 -block_count,RegExpPrototypeTestFast,73,422 +block_count,RegExpPrototypeTestFast,73,421 block_count,RegExpPrototypeTestFast,74,0 block_count,RegExpPrototypeTestFast,75,0 block_count,RegExpPrototypeTestFast,76,0 block_count,RegExpPrototypeTestFast,77,0 -block_count,RegExpPrototypeTestFast,78,427 +block_count,RegExpPrototypeTestFast,78,426 block_count,RegExpPrototypeTestFast,79,129 block_count,RegExpPrototypeTestFast,80,0 block_count,RegExpPrototypeTestFast,81,129 @@ -55685,10 +55674,10 @@ block_count,RegExpPrototypeTestFast,99,129 block_count,RegExpPrototypeTestFast,100,0 block_count,RegExpPrototypeTestFast,101,129 -block_count,RegExpPrototypeTestFast,102,298 -block_count,RegExpPrototypeTestFast,103,298 +block_count,RegExpPrototypeTestFast,102,297 +block_count,RegExpPrototypeTestFast,103,297 block_count,RegExpPrototypeTestFast,104,0 -block_count,RegExpPrototypeTestFast,105,298 +block_count,RegExpPrototypeTestFast,105,297 block_count,RegExpPrototypeGlobalGetter,0,0 block_count,RegExpPrototypeGlobalGetter,1,0 block_count,RegExpPrototypeGlobalGetter,2,0 @@ -56435,30 +56424,30 @@ block_count,StringPrototypeIncludes,73,0 block_count,StringPrototypeIncludes,74,0 block_count,StringPrototypeIncludes,75,0 -block_count,StringPrototypeIndexOf,0,12 +block_count,StringPrototypeIndexOf,0,11 block_count,StringPrototypeIndexOf,1,0 -block_count,StringPrototypeIndexOf,2,12 -block_count,StringPrototypeIndexOf,3,12 -block_count,StringPrototypeIndexOf,4,12 +block_count,StringPrototypeIndexOf,2,11 +block_count,StringPrototypeIndexOf,3,11 +block_count,StringPrototypeIndexOf,4,11 block_count,StringPrototypeIndexOf,5,0 -block_count,StringPrototypeIndexOf,6,12 +block_count,StringPrototypeIndexOf,6,11 block_count,StringPrototypeIndexOf,7,1 -block_count,StringPrototypeIndexOf,8,11 -block_count,StringPrototypeIndexOf,9,12 -block_count,StringPrototypeIndexOf,10,12 +block_count,StringPrototypeIndexOf,8,10 +block_count,StringPrototypeIndexOf,9,11 +block_count,StringPrototypeIndexOf,10,11 block_count,StringPrototypeIndexOf,11,0 block_count,StringPrototypeIndexOf,12,0 block_count,StringPrototypeIndexOf,13,0 -block_count,StringPrototypeIndexOf,14,12 +block_count,StringPrototypeIndexOf,14,11 block_count,StringPrototypeIndexOf,15,0 -block_count,StringPrototypeIndexOf,16,12 -block_count,StringPrototypeIndexOf,17,12 +block_count,StringPrototypeIndexOf,16,11 +block_count,StringPrototypeIndexOf,17,11 block_count,StringPrototypeIndexOf,18,0 -block_count,StringPrototypeIndexOf,19,12 +block_count,StringPrototypeIndexOf,19,11 block_count,StringPrototypeIndexOf,20,0 block_count,StringPrototypeIndexOf,21,0 -block_count,StringPrototypeIndexOf,22,12 -block_count,StringPrototypeIndexOf,23,11 +block_count,StringPrototypeIndexOf,22,11 +block_count,StringPrototypeIndexOf,23,10 block_count,StringPrototypeIndexOf,24,1 block_count,StringPrototypeIndexOf,25,1 block_count,StringPrototypeIndexOf,26,0 @@ -56652,7 +56641,7 @@ block_count,StringPrototypeSlice,19,23 block_count,StringPrototypeSlice,20,22 block_count,StringPrototypeSlice,21,0 -block_count,StringPrototypeSlice,22,22 +block_count,StringPrototypeSlice,22,21 block_count,StringPrototypeSlice,23,1 block_count,StringPrototypeSlice,24,0 block_count,StringPrototypeSlice,25,1 @@ -56696,22 +56685,22 @@ block_count,StringPrototypeSlice,63,16 block_count,StringPrototypeSlice,64,23 block_count,StringPrototypeSlice,65,21 -block_count,StringPrototypeSlice,66,21 -block_count,StringPrototypeSlice,67,21 -block_count,StringPrototypeSlice,68,15 -block_count,StringPrototypeSlice,69,23 -block_count,StringPrototypeSlice,70,8 -block_count,StringPrototypeSlice,71,8 -block_count,StringPrototypeSlice,72,6 +block_count,StringPrototypeSlice,66,20 +block_count,StringPrototypeSlice,67,20 +block_count,StringPrototypeSlice,68,14 +block_count,StringPrototypeSlice,69,21 +block_count,StringPrototypeSlice,70,7 +block_count,StringPrototypeSlice,71,7 +block_count,StringPrototypeSlice,72,5 block_count,StringPrototypeSlice,73,0 -block_count,StringPrototypeSlice,74,6 +block_count,StringPrototypeSlice,74,5 block_count,StringPrototypeSlice,75,1 block_count,StringPrototypeSlice,76,1 block_count,StringPrototypeSlice,77,0 -block_count,StringPrototypeSlice,78,8 +block_count,StringPrototypeSlice,78,7 block_count,StringPrototypeSlice,79,0 -block_count,StringPrototypeSlice,80,15 -block_count,StringPrototypeSlice,81,15 +block_count,StringPrototypeSlice,80,14 +block_count,StringPrototypeSlice,81,14 block_count,StringPrototypeSlice,82,6 block_count,StringPrototypeSlice,83,1 block_count,StringPrototypeSlice,84,0 @@ -57569,10 +57558,10 @@ block_count,StringPrototypeSubstring,72,0 block_count,StringPrototypeSubstring,73,0 block_count,StringPrototypeSubstring,74,0 -block_count,StringPrototypeSubstring,75,1 +block_count,StringPrototypeSubstring,75,2 block_count,StringPrototypeSubstring,76,0 -block_count,StringPrototypeSubstring,77,1 -block_count,StringPrototypeSubstring,78,1 +block_count,StringPrototypeSubstring,77,2 +block_count,StringPrototypeSubstring,78,2 block_count,StringPrototypeSubstring,79,1 block_count,StringPrototypeSubstring,80,1 block_count,StringPrototypeSubstring,81,0 @@ -60331,11 +60320,11 @@ block_count,FastNewRestArguments,19,0 block_count,FastNewRestArguments,20,0 block_count,FastNewRestArguments,21,1 -block_count,FastNewRestArguments,22,1 -block_count,FastNewRestArguments,23,1 -block_count,FastNewRestArguments,24,1 +block_count,FastNewRestArguments,22,0 +block_count,FastNewRestArguments,23,0 +block_count,FastNewRestArguments,24,0 block_count,FastNewRestArguments,25,0 -block_count,FastNewRestArguments,26,1 +block_count,FastNewRestArguments,26,0 block_count,FastNewRestArguments,27,0 block_count,FastNewRestArguments,28,0 block_count,FastNewRestArguments,29,0 @@ -60758,7 +60747,7 @@ block_count,StringIndexOf,8,367 block_count,StringIndexOf,9,182 block_count,StringIndexOf,10,215 -block_count,StringIndexOf,11,51 +block_count,StringIndexOf,11,52 block_count,StringIndexOf,12,32 block_count,StringIndexOf,13,31 block_count,StringIndexOf,14,1 @@ -62152,9 +62141,9 @@ block_count,StringFastLocaleCompare,326,1329 block_count,StringFastLocaleCompare,327,910 block_count,StringFastLocaleCompare,328,910 -block_count,StringFastLocaleCompare,329,969 -block_count,StringFastLocaleCompare,330,969 -block_count,StringFastLocaleCompare,331,969 +block_count,StringFastLocaleCompare,329,970 +block_count,StringFastLocaleCompare,330,970 +block_count,StringFastLocaleCompare,331,970 block_count,StringFastLocaleCompare,332,59 block_count,StringFastLocaleCompare,333,910 block_count,StringFastLocaleCompare,334,0 @@ -62163,11 +62152,11 @@ block_count,StringFastLocaleCompare,337,0 block_count,StringFastLocaleCompare,338,419 block_count,StringFastLocaleCompare,339,1329 -block_count,StringFastLocaleCompare,340,6510 +block_count,StringFastLocaleCompare,340,6511 block_count,StringFastLocaleCompare,341,6500 block_count,StringFastLocaleCompare,342,6500 -block_count,StringFastLocaleCompare,343,6443 -block_count,StringFastLocaleCompare,344,6443 +block_count,StringFastLocaleCompare,343,6444 +block_count,StringFastLocaleCompare,344,6444 block_count,StringFastLocaleCompare,345,5181 block_count,StringFastLocaleCompare,346,1262 block_count,StringFastLocaleCompare,347,831 @@ -62770,14 +62759,14 @@ block_count,StringToLowerCaseIntl,42,0 block_count,WideHandler,0,61 block_count,ExtraWideHandler,0,10 -block_count,LdarHandler,0,86 +block_count,LdarHandler,0,82 block_count,LdaZeroHandler,0,10 block_count,LdaZeroHandler,1,7 block_count,LdaZeroHandler,2,3 -block_count,LdaSmiHandler,0,11 +block_count,LdaSmiHandler,0,12 block_count,LdaSmiHandler,1,7 block_count,LdaSmiHandler,2,4 -block_count,LdaUndefinedHandler,0,8 +block_count,LdaUndefinedHandler,0,7 block_count,LdaUndefinedHandler,1,7 block_count,LdaUndefinedHandler,2,0 block_count,LdaNullHandler,0,1 @@ -62790,7 +62779,7 @@ block_count,LdaFalseHandler,0,2 block_count,LdaConstantHandler,0,13 block_count,LdaConstantHandler,1,5 -block_count,LdaConstantHandler,2,8 +block_count,LdaConstantHandler,2,7 block_count,LdaContextSlotHandler,0,0 block_count,LdaContextSlotHandler,1,0 block_count,LdaContextSlotHandler,2,0 @@ -62855,23 +62844,23 @@ block_count,LdaScriptContextSlotHandler,48,0 block_count,LdaScriptContextSlotHandler,49,0 block_count,LdaScriptContextSlotHandler,50,0 -block_count,LdaImmutableContextSlotHandler,0,7 -block_count,LdaImmutableContextSlotHandler,1,4 -block_count,LdaImmutableContextSlotHandler,2,5 -block_count,LdaImmutableContextSlotHandler,3,5 +block_count,LdaImmutableContextSlotHandler,0,6 +block_count,LdaImmutableContextSlotHandler,1,3 +block_count,LdaImmutableContextSlotHandler,2,4 +block_count,LdaImmutableContextSlotHandler,3,4 block_count,LdaImmutableContextSlotHandler,4,1 -block_count,LdaImmutableContextSlotHandler,5,4 +block_count,LdaImmutableContextSlotHandler,5,3 block_count,LdaImmutableContextSlotHandler,6,0 block_count,LdaImmutableContextSlotHandler,7,2 -block_count,LdaImmutableContextSlotHandler,8,7 +block_count,LdaImmutableContextSlotHandler,8,6 block_count,LdaImmutableContextSlotHandler,9,0 -block_count,LdaImmutableContextSlotHandler,10,7 +block_count,LdaImmutableContextSlotHandler,10,6 block_count,LdaImmutableContextSlotHandler,11,1 block_count,LdaImmutableContextSlotHandler,12,5 block_count,LdaCurrentContextSlotHandler,0,5 block_count,LdaCurrentContextSlotHandler,1,0 block_count,LdaCurrentContextSlotHandler,2,5 -block_count,LdaCurrentContextSlotHandler,3,3 +block_count,LdaCurrentContextSlotHandler,3,2 block_count,LdaCurrentContextSlotHandler,4,2 block_count,LdaCurrentScriptContextSlotHandler,0,0 block_count,LdaCurrentScriptContextSlotHandler,1,0 @@ -62916,13 +62905,13 @@ block_count,LdaCurrentScriptContextSlotHandler,40,0 block_count,LdaCurrentScriptContextSlotHandler,41,0 block_count,LdaCurrentScriptContextSlotHandler,42,0 -block_count,LdaImmutableCurrentContextSlotHandler,0,20 +block_count,LdaImmutableCurrentContextSlotHandler,0,18 block_count,LdaImmutableCurrentContextSlotHandler,1,0 -block_count,LdaImmutableCurrentContextSlotHandler,2,20 +block_count,LdaImmutableCurrentContextSlotHandler,2,18 block_count,LdaImmutableCurrentContextSlotHandler,3,4 -block_count,LdaImmutableCurrentContextSlotHandler,4,15 +block_count,LdaImmutableCurrentContextSlotHandler,4,14 block_count,StarHandler,0,19 -block_count,MovHandler,0,19 +block_count,MovHandler,0,18 block_count,PushContextHandler,0,2 block_count,PopContextHandler,0,0 block_count,TestReferenceEqualHandler,0,0 @@ -62995,8 +62984,8 @@ block_count,TestTypeOfHandler,48,0 block_count,TestTypeOfHandler,49,0 block_count,TestTypeOfHandler,50,0 -block_count,LdaGlobalHandler,0,23 -block_count,LdaGlobalHandler,1,13 +block_count,LdaGlobalHandler,0,24 +block_count,LdaGlobalHandler,1,14 block_count,LdaGlobalHandler,2,13 block_count,LdaGlobalHandler,3,13 block_count,LdaGlobalHandler,4,13 @@ -63256,13 +63245,13 @@ block_count,LdaGlobalHandler,258,0 block_count,LdaGlobalHandler,259,0 block_count,LdaGlobalHandler,260,0 -block_count,LdaGlobalHandler,261,0 +block_count,LdaGlobalHandler,261,1 block_count,LdaGlobalHandler,262,0 -block_count,LdaGlobalHandler,263,0 +block_count,LdaGlobalHandler,263,1 block_count,LdaGlobalHandler,264,0 -block_count,LdaGlobalHandler,265,0 +block_count,LdaGlobalHandler,265,1 block_count,LdaGlobalHandler,266,0 -block_count,LdaGlobalHandler,267,0 +block_count,LdaGlobalHandler,267,1 block_count,LdaGlobalHandler,268,9 block_count,LdaGlobalHandler,269,2 block_count,LdaGlobalHandler,270,7 @@ -63497,9 +63486,9 @@ block_count,StaContextSlotHandler,8,0 block_count,StaContextSlotHandler,9,0 block_count,StaContextSlotHandler,10,0 -block_count,StaCurrentContextSlotHandler,0,8 +block_count,StaCurrentContextSlotHandler,0,7 block_count,StaCurrentContextSlotHandler,1,0 -block_count,StaCurrentContextSlotHandler,2,8 +block_count,StaCurrentContextSlotHandler,2,7 block_count,StaScriptContextSlotHandler,0,0 block_count,StaScriptContextSlotHandler,1,0 block_count,StaScriptContextSlotHandler,2,0 @@ -64334,12 +64323,12 @@ block_count,StaLookupSlotHandler,3,0 block_count,StaLookupSlotHandler,4,0 block_count,StaLookupSlotHandler,5,0 -block_count,GetNamedPropertyHandler,0,72 -block_count,GetNamedPropertyHandler,1,44 -block_count,GetNamedPropertyHandler,2,44 +block_count,GetNamedPropertyHandler,0,74 +block_count,GetNamedPropertyHandler,1,46 +block_count,GetNamedPropertyHandler,2,46 block_count,GetNamedPropertyHandler,3,0 -block_count,GetNamedPropertyHandler,4,44 -block_count,GetNamedPropertyHandler,5,6 +block_count,GetNamedPropertyHandler,4,46 +block_count,GetNamedPropertyHandler,5,5 block_count,GetNamedPropertyHandler,6,0 block_count,GetNamedPropertyHandler,7,5 block_count,GetNamedPropertyHandler,8,2 @@ -64349,10 +64338,10 @@ block_count,GetNamedPropertyHandler,12,2 block_count,GetNamedPropertyHandler,13,0 block_count,GetNamedPropertyHandler,14,2 -block_count,GetNamedPropertyHandler,15,38 -block_count,GetNamedPropertyHandler,16,41 -block_count,GetNamedPropertyHandler,17,14 -block_count,GetNamedPropertyHandler,18,14 +block_count,GetNamedPropertyHandler,15,41 +block_count,GetNamedPropertyHandler,16,43 +block_count,GetNamedPropertyHandler,17,15 +block_count,GetNamedPropertyHandler,18,15 block_count,GetNamedPropertyHandler,19,13 block_count,GetNamedPropertyHandler,20,13 block_count,GetNamedPropertyHandler,21,0 @@ -64432,11 +64421,11 @@ block_count,GetNamedPropertyHandler,95,0 block_count,GetNamedPropertyHandler,96,2 block_count,GetNamedPropertyHandler,97,0 -block_count,GetNamedPropertyHandler,98,10 +block_count,GetNamedPropertyHandler,98,11 block_count,GetNamedPropertyHandler,99,13 block_count,GetNamedPropertyHandler,100,13 -block_count,GetNamedPropertyHandler,101,12 -block_count,GetNamedPropertyHandler,102,12 +block_count,GetNamedPropertyHandler,101,13 +block_count,GetNamedPropertyHandler,102,13 block_count,GetNamedPropertyHandler,103,0 block_count,GetNamedPropertyHandler,104,0 block_count,GetNamedPropertyHandler,105,13 @@ -64445,12 +64434,12 @@ block_count,GetNamedPropertyHandler,108,0 block_count,GetNamedPropertyHandler,109,0 block_count,GetNamedPropertyHandler,110,0 -block_count,GetNamedPropertyHandler,111,26 -block_count,GetNamedPropertyHandler,112,40 -block_count,GetNamedPropertyHandler,113,13 -block_count,GetNamedPropertyHandler,114,3 +block_count,GetNamedPropertyHandler,111,28 +block_count,GetNamedPropertyHandler,112,42 +block_count,GetNamedPropertyHandler,113,14 +block_count,GetNamedPropertyHandler,114,2 block_count,GetNamedPropertyHandler,115,2 -block_count,GetNamedPropertyHandler,116,2 +block_count,GetNamedPropertyHandler,116,1 block_count,GetNamedPropertyHandler,117,0 block_count,GetNamedPropertyHandler,118,0 block_count,GetNamedPropertyHandler,119,0 @@ -64581,13 +64570,13 @@ block_count,GetNamedPropertyHandler,244,0 block_count,GetNamedPropertyHandler,245,0 block_count,GetNamedPropertyHandler,246,0 -block_count,GetNamedPropertyHandler,247,10 -block_count,GetNamedPropertyHandler,248,26 -block_count,GetNamedPropertyHandler,249,26 -block_count,GetNamedPropertyHandler,250,4 +block_count,GetNamedPropertyHandler,247,11 +block_count,GetNamedPropertyHandler,248,28 +block_count,GetNamedPropertyHandler,249,28 +block_count,GetNamedPropertyHandler,250,6 block_count,GetNamedPropertyHandler,251,21 -block_count,GetNamedPropertyHandler,252,26 -block_count,GetNamedPropertyHandler,253,25 +block_count,GetNamedPropertyHandler,252,28 +block_count,GetNamedPropertyHandler,253,26 block_count,GetNamedPropertyHandler,254,1 block_count,GetNamedPropertyHandler,255,1 block_count,GetNamedPropertyHandler,256,1 @@ -64635,17 +64624,17 @@ block_count,GetNamedPropertyHandler,298,1 block_count,GetNamedPropertyHandler,299,0 block_count,GetNamedPropertyHandler,300,27 -block_count,GetNamedPropertyHandler,301,72 +block_count,GetNamedPropertyHandler,301,74 block_count,GetNamedPropertyHandler,302,20 -block_count,GetNamedPropertyHandler,303,52 +block_count,GetNamedPropertyHandler,303,54 block_count,GetNamedPropertyFromSuperHandler,0,0 -block_count,GetKeyedPropertyHandler,0,20 -block_count,GetKeyedPropertyHandler,1,9 -block_count,GetKeyedPropertyHandler,2,11 +block_count,GetKeyedPropertyHandler,0,19 +block_count,GetKeyedPropertyHandler,1,8 +block_count,GetKeyedPropertyHandler,2,10 block_count,GetEnumeratedKeyedPropertyHandler,0,1 block_count,SetNamedPropertyHandler,0,10 block_count,DefineNamedOwnPropertyHandler,0,3 -block_count,SetKeyedPropertyHandler,0,12 +block_count,SetKeyedPropertyHandler,0,11 block_count,DefineKeyedOwnPropertyHandler,0,0 block_count,StaInArrayLiteralHandler,0,1 block_count,DefineKeyedOwnPropertyInLiteralHandler,0,0 @@ -64778,7 +64767,7 @@ block_count,AddHandler,126,6 block_count,AddHandler,127,4 block_count,SubHandler,0,1 -block_count,SubHandler,1,1 +block_count,SubHandler,1,0 block_count,SubHandler,2,0 block_count,SubHandler,3,0 block_count,SubHandler,4,0 @@ -64889,7 +64878,7 @@ block_count,SubHandler,109,1 block_count,SubHandler,110,1 block_count,SubHandler,111,0 -block_count,SubHandler,112,1 +block_count,SubHandler,112,0 block_count,MulHandler,0,4 block_count,MulHandler,1,1 block_count,MulHandler,2,1 @@ -65335,7 +65324,7 @@ block_count,ExpHandler,55,0 block_count,ExpHandler,56,0 block_count,ExpHandler,57,0 -block_count,BitwiseOrHandler,0,0 +block_count,BitwiseOrHandler,0,1 block_count,BitwiseOrHandler,1,0 block_count,BitwiseOrHandler,2,0 block_count,BitwiseOrHandler,3,0 @@ -65441,7 +65430,7 @@ block_count,BitwiseOrHandler,103,0 block_count,BitwiseOrHandler,104,0 block_count,BitwiseOrHandler,105,0 -block_count,BitwiseOrHandler,106,0 +block_count,BitwiseOrHandler,106,1 block_count,BitwiseOrHandler,107,0 block_count,BitwiseOrHandler,108,0 block_count,BitwiseOrHandler,109,0 @@ -65467,22 +65456,22 @@ block_count,BitwiseOrHandler,129,0 block_count,BitwiseOrHandler,130,0 block_count,BitwiseOrHandler,131,0 -block_count,BitwiseOrHandler,132,0 +block_count,BitwiseOrHandler,132,1 block_count,BitwiseOrHandler,133,0 block_count,BitwiseOrHandler,134,0 block_count,BitwiseOrHandler,135,0 block_count,BitwiseOrHandler,136,0 block_count,BitwiseOrHandler,137,0 -block_count,BitwiseOrHandler,138,0 +block_count,BitwiseOrHandler,138,1 block_count,BitwiseOrHandler,139,0 block_count,BitwiseOrHandler,140,0 -block_count,BitwiseOrHandler,141,0 +block_count,BitwiseOrHandler,141,1 block_count,BitwiseOrHandler,142,0 block_count,BitwiseOrHandler,143,0 block_count,BitwiseOrHandler,144,0 block_count,BitwiseOrHandler,145,0 -block_count,BitwiseOrHandler,146,0 -block_count,BitwiseOrHandler,147,0 +block_count,BitwiseOrHandler,146,1 +block_count,BitwiseOrHandler,147,1 block_count,BitwiseXorHandler,0,0 block_count,BitwiseXorHandler,1,0 block_count,BitwiseXorHandler,2,0 @@ -66540,8 +66529,8 @@ block_count,ShiftRightLogicalSmiHandler,48,0 block_count,ShiftRightLogicalSmiHandler,49,0 block_count,ShiftRightLogicalSmiHandler,50,0 -block_count,IncHandler,0,12 -block_count,IncHandler,1,12 +block_count,IncHandler,0,11 +block_count,IncHandler,1,11 block_count,IncHandler,2,0 block_count,IncHandler,3,0 block_count,IncHandler,4,0 @@ -66558,19 +66547,19 @@ block_count,IncHandler,15,0 block_count,IncHandler,16,0 block_count,IncHandler,17,0 -block_count,IncHandler,18,12 -block_count,IncHandler,19,12 +block_count,IncHandler,18,11 +block_count,IncHandler,19,11 block_count,IncHandler,20,0 block_count,IncHandler,21,0 block_count,IncHandler,22,0 block_count,IncHandler,23,0 block_count,IncHandler,24,0 -block_count,IncHandler,25,12 -block_count,IncHandler,26,11 +block_count,IncHandler,25,11 +block_count,IncHandler,26,10 block_count,IncHandler,27,0 -block_count,IncHandler,28,11 +block_count,IncHandler,28,10 block_count,IncHandler,29,0 -block_count,IncHandler,30,12 +block_count,IncHandler,30,11 block_count,IncHandler,31,1 block_count,IncHandler,32,10 block_count,DecHandler,0,2 @@ -66930,8 +66919,8 @@ block_count,CallPropertyHandler,66,1 block_count,CallPropertyHandler,67,0 block_count,CallPropertyHandler,68,2 -block_count,CallProperty0Handler,0,4 -block_count,CallProperty0Handler,1,3 +block_count,CallProperty0Handler,0,5 +block_count,CallProperty0Handler,1,4 block_count,CallProperty0Handler,2,0 block_count,CallProperty0Handler,3,0 block_count,CallProperty0Handler,4,0 @@ -66996,9 +66985,9 @@ block_count,CallProperty0Handler,63,0 block_count,CallProperty0Handler,64,0 block_count,CallProperty0Handler,65,0 -block_count,CallProperty0Handler,66,2 +block_count,CallProperty0Handler,66,3 block_count,CallProperty0Handler,67,1 -block_count,CallProperty0Handler,68,4 +block_count,CallProperty0Handler,68,5 block_count,CallProperty1Handler,0,12 block_count,CallProperty1Handler,1,8 block_count,CallProperty1Handler,2,0 @@ -67068,7 +67057,7 @@ block_count,CallProperty1Handler,66,8 block_count,CallProperty1Handler,67,4 block_count,CallProperty1Handler,68,12 -block_count,CallProperty2Handler,0,3 +block_count,CallProperty2Handler,0,4 block_count,CallProperty2Handler,1,2 block_count,CallProperty2Handler,2,0 block_count,CallProperty2Handler,3,0 @@ -67136,7 +67125,7 @@ block_count,CallProperty2Handler,65,0 block_count,CallProperty2Handler,66,1 block_count,CallProperty2Handler,67,1 -block_count,CallProperty2Handler,68,3 +block_count,CallProperty2Handler,68,4 block_count,CallUndefinedReceiverHandler,0,1 block_count,CallUndefinedReceiverHandler,1,0 block_count,CallUndefinedReceiverHandler,2,0 @@ -67206,7 +67195,7 @@ block_count,CallUndefinedReceiverHandler,66,0 block_count,CallUndefinedReceiverHandler,67,0 block_count,CallUndefinedReceiverHandler,68,1 -block_count,CallUndefinedReceiver0Handler,0,1 +block_count,CallUndefinedReceiver0Handler,0,2 block_count,CallUndefinedReceiver0Handler,1,1 block_count,CallUndefinedReceiver0Handler,2,0 block_count,CallUndefinedReceiver0Handler,3,0 @@ -67274,7 +67263,7 @@ block_count,CallUndefinedReceiver0Handler,65,0 block_count,CallUndefinedReceiver0Handler,66,1 block_count,CallUndefinedReceiver0Handler,67,0 -block_count,CallUndefinedReceiver0Handler,68,1 +block_count,CallUndefinedReceiver0Handler,68,2 block_count,CallUndefinedReceiver1Handler,0,5 block_count,CallUndefinedReceiver1Handler,1,2 block_count,CallUndefinedReceiver1Handler,2,0 @@ -67342,10 +67331,10 @@ block_count,CallUndefinedReceiver1Handler,64,0 block_count,CallUndefinedReceiver1Handler,65,0 block_count,CallUndefinedReceiver1Handler,66,1 -block_count,CallUndefinedReceiver1Handler,67,3 +block_count,CallUndefinedReceiver1Handler,67,2 block_count,CallUndefinedReceiver1Handler,68,5 block_count,CallUndefinedReceiver2Handler,0,3 -block_count,CallUndefinedReceiver2Handler,1,2 +block_count,CallUndefinedReceiver2Handler,1,1 block_count,CallUndefinedReceiver2Handler,2,0 block_count,CallUndefinedReceiver2Handler,3,0 block_count,CallUndefinedReceiver2Handler,4,0 @@ -67772,21 +67761,21 @@ block_count,TestEqualHandler,97,1 block_count,TestEqualHandler,98,0 block_count,TestEqualHandler,99,1 -block_count,TestEqualHandler,100,1 +block_count,TestEqualHandler,100,0 block_count,TestEqualHandler,101,0 block_count,TestEqualHandler,102,0 block_count,TestEqualHandler,103,0 block_count,TestEqualHandler,104,0 block_count,TestEqualHandler,105,1 block_count,TestEqualHandler,106,0 -block_count,TestEqualHandler,107,1 +block_count,TestEqualHandler,107,0 block_count,TestEqualHandler,108,1 block_count,TestEqualHandler,109,0 block_count,TestEqualHandler,110,1 block_count,TestEqualHandler,111,1 block_count,TestEqualHandler,112,0 block_count,TestEqualHandler,113,0 -block_count,TestEqualHandler,114,1 +block_count,TestEqualHandler,114,2 block_count,TestEqualHandler,115,0 block_count,TestEqualHandler,116,0 block_count,TestEqualHandler,117,0 @@ -67806,7 +67795,7 @@ block_count,TestEqualHandler,131,0 block_count,TestEqualHandler,132,0 block_count,TestEqualHandler,133,0 -block_count,TestEqualHandler,134,1 +block_count,TestEqualHandler,134,2 block_count,TestEqualHandler,135,0 block_count,TestEqualHandler,136,0 block_count,TestEqualHandler,137,0 @@ -67853,7 +67842,7 @@ block_count,TestEqualHandler,178,0 block_count,TestEqualHandler,179,0 block_count,TestEqualHandler,180,0 -block_count,TestEqualHandler,181,1 +block_count,TestEqualHandler,181,2 block_count,TestEqualHandler,182,4 block_count,TestEqualHandler,183,3 block_count,TestEqualHandler,184,0 @@ -67862,9 +67851,9 @@ block_count,TestEqualHandler,187,4 block_count,TestEqualStrictHandler,0,7 block_count,TestEqualStrictHandler,1,6 -block_count,TestEqualStrictHandler,2,4 -block_count,TestEqualStrictHandler,3,4 -block_count,TestEqualStrictHandler,4,4 +block_count,TestEqualStrictHandler,2,5 +block_count,TestEqualStrictHandler,3,5 +block_count,TestEqualStrictHandler,4,5 block_count,TestEqualStrictHandler,5,2 block_count,TestEqualStrictHandler,6,2 block_count,TestEqualStrictHandler,7,0 @@ -67990,7 +67979,7 @@ block_count,TestEqualStrictHandler,127,5 block_count,TestEqualStrictHandler,128,0 block_count,TestEqualStrictHandler,129,5 -block_count,TestEqualStrictHandler,130,2 +block_count,TestEqualStrictHandler,130,1 block_count,TestEqualStrictHandler,131,7 block_count,TestLessThanHandler,0,10 block_count,TestLessThanHandler,1,10 @@ -68142,8 +68131,8 @@ block_count,TestLessThanHandler,147,9 block_count,TestLessThanHandler,148,1 block_count,TestLessThanHandler,149,10 -block_count,TestGreaterThanHandler,0,1 -block_count,TestGreaterThanHandler,1,1 +block_count,TestGreaterThanHandler,0,2 +block_count,TestGreaterThanHandler,1,2 block_count,TestGreaterThanHandler,2,0 block_count,TestGreaterThanHandler,3,0 block_count,TestGreaterThanHandler,4,0 @@ -68273,7 +68262,7 @@ block_count,TestGreaterThanHandler,128,0 block_count,TestGreaterThanHandler,129,1 block_count,TestGreaterThanHandler,130,0 -block_count,TestGreaterThanHandler,131,0 +block_count,TestGreaterThanHandler,131,1 block_count,TestGreaterThanHandler,132,0 block_count,TestGreaterThanHandler,133,0 block_count,TestGreaterThanHandler,134,0 @@ -68284,14 +68273,14 @@ block_count,TestGreaterThanHandler,139,0 block_count,TestGreaterThanHandler,140,0 block_count,TestGreaterThanHandler,141,0 -block_count,TestGreaterThanHandler,142,1 -block_count,TestGreaterThanHandler,143,0 -block_count,TestGreaterThanHandler,144,1 +block_count,TestGreaterThanHandler,142,0 +block_count,TestGreaterThanHandler,143,1 +block_count,TestGreaterThanHandler,144,2 block_count,TestGreaterThanHandler,145,1 block_count,TestGreaterThanHandler,146,0 block_count,TestGreaterThanHandler,147,1 block_count,TestGreaterThanHandler,148,0 -block_count,TestGreaterThanHandler,149,1 +block_count,TestGreaterThanHandler,149,2 block_count,TestLessThanOrEqualHandler,0,0 block_count,TestLessThanOrEqualHandler,1,0 block_count,TestLessThanOrEqualHandler,2,0 @@ -68665,19 +68654,19 @@ block_count,ToNumberHandler,8,0 block_count,ToNumberHandler,9,0 block_count,ToNumberHandler,10,0 -block_count,ToNumericHandler,0,4 +block_count,ToNumericHandler,0,3 block_count,ToNumericHandler,1,0 block_count,ToNumericHandler,2,0 block_count,ToNumericHandler,3,0 block_count,ToNumericHandler,4,0 block_count,ToNumericHandler,5,0 -block_count,ToNumericHandler,6,4 -block_count,ToNumericHandler,7,4 +block_count,ToNumericHandler,6,3 +block_count,ToNumericHandler,7,3 block_count,ToNumericHandler,8,3 block_count,ToNumericHandler,9,0 block_count,ToNumericHandler,10,3 block_count,ToNumericHandler,11,0 -block_count,ToNumericHandler,12,4 +block_count,ToNumericHandler,12,3 block_count,ToObjectHandler,0,0 block_count,ToStringHandler,0,0 block_count,ToStringHandler,1,0 @@ -69242,15 +69231,15 @@ block_count,JumpLoopHandler,32,0 block_count,JumpLoopHandler,33,0 block_count,JumpLoopHandler,34,0 -block_count,JumpLoopHandler,35,12 -block_count,JumpLoopHandler,36,12 +block_count,JumpLoopHandler,35,11 +block_count,JumpLoopHandler,36,11 block_count,JumpLoopHandler,37,0 -block_count,JumpLoopHandler,38,12 -block_count,JumpLoopHandler,39,12 +block_count,JumpLoopHandler,38,11 +block_count,JumpLoopHandler,39,11 block_count,JumpLoopHandler,40,0 -block_count,JumpLoopHandler,41,12 -block_count,JumpLoopHandler,42,12 -block_count,JumpLoopHandler,43,12 +block_count,JumpLoopHandler,41,11 +block_count,JumpLoopHandler,42,11 +block_count,JumpLoopHandler,43,11 block_count,JumpLoopHandler,44,0 block_count,JumpLoopHandler,45,0 block_count,JumpLoopHandler,46,0 @@ -69266,7 +69255,7 @@ block_count,JumpLoopHandler,56,0 block_count,JumpLoopHandler,57,13 block_count,JumpLoopHandler,58,0 -block_count,JumpLoopHandler,59,13 +block_count,JumpLoopHandler,59,12 block_count,JumpLoopHandler,60,13 block_count,JumpHandler,0,4 block_count,JumpConstantHandler,0,0 @@ -69330,7 +69319,7 @@ block_count,JumpIfToBooleanFalseConstantHandler,18,0 block_count,JumpIfToBooleanFalseConstantHandler,19,0 block_count,JumpIfToBooleanFalseConstantHandler,20,0 -block_count,JumpIfToBooleanTrueHandler,0,6 +block_count,JumpIfToBooleanTrueHandler,0,5 block_count,JumpIfToBooleanTrueHandler,1,5 block_count,JumpIfToBooleanTrueHandler,2,2 block_count,JumpIfToBooleanTrueHandler,3,1 @@ -69351,8 +69340,8 @@ block_count,JumpIfToBooleanTrueHandler,18,0 block_count,JumpIfToBooleanTrueHandler,19,2 block_count,JumpIfToBooleanTrueHandler,20,3 -block_count,JumpIfToBooleanFalseHandler,0,12 -block_count,JumpIfToBooleanFalseHandler,1,10 +block_count,JumpIfToBooleanFalseHandler,0,11 +block_count,JumpIfToBooleanFalseHandler,1,9 block_count,JumpIfToBooleanFalseHandler,2,4 block_count,JumpIfToBooleanFalseHandler,3,3 block_count,JumpIfToBooleanFalseHandler,4,3 @@ -69366,18 +69355,18 @@ block_count,JumpIfToBooleanFalseHandler,12,0 block_count,JumpIfToBooleanFalseHandler,13,0 block_count,JumpIfToBooleanFalseHandler,14,1 -block_count,JumpIfToBooleanFalseHandler,15,5 -block_count,JumpIfToBooleanFalseHandler,16,2 -block_count,JumpIfToBooleanFalseHandler,17,2 +block_count,JumpIfToBooleanFalseHandler,15,4 +block_count,JumpIfToBooleanFalseHandler,16,1 +block_count,JumpIfToBooleanFalseHandler,17,1 block_count,JumpIfToBooleanFalseHandler,18,0 -block_count,JumpIfToBooleanFalseHandler,19,7 +block_count,JumpIfToBooleanFalseHandler,19,6 block_count,JumpIfToBooleanFalseHandler,20,5 block_count,JumpIfTrueHandler,0,6 block_count,JumpIfTrueHandler,1,4 block_count,JumpIfTrueHandler,2,1 block_count,JumpIfFalseHandler,0,22 block_count,JumpIfFalseHandler,1,13 -block_count,JumpIfFalseHandler,2,9 +block_count,JumpIfFalseHandler,2,8 block_count,JumpIfNullHandler,0,0 block_count,JumpIfNullHandler,1,0 block_count,JumpIfNullHandler,2,0 @@ -69483,7 +69472,7 @@ block_count,ReThrowHandler,0,0 block_count,ReturnHandler,0,20 block_count,ReturnHandler,1,0 -block_count,ReturnHandler,2,19 +block_count,ReturnHandler,2,20 block_count,ThrowReferenceErrorIfHoleHandler,0,1 block_count,ThrowReferenceErrorIfHoleHandler,1,1 block_count,ThrowReferenceErrorIfHoleHandler,2,0 @@ -69520,7 +69509,7 @@ block_count,ResumeGeneratorHandler,6,0 block_count,ResumeGeneratorHandler,7,0 block_count,GetIteratorHandler,0,0 -block_count,ShortStarHandler,0,54 +block_count,ShortStarHandler,0,53 block_count,LdarWideHandler,0,0 block_count,LdaSmiWideHandler,0,7 block_count,LdaConstantWideHandler,0,1 diff -Nru chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x86-rl.profile chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86-rl.profile --- chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x86-rl.profile 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86-rl.profile 2025-03-07 21:29:53.000000000 +0000 @@ -1,3 +1,4 @@ +block_hint,RecordWriteSaveFP,12,1,0 block_hint,RecordWriteSaveFP,3,2,1 block_hint,RecordWriteSaveFP,4,9,1 block_hint,RecordWriteSaveFP,6,5,1 @@ -8,16 +9,13 @@ block_hint,RecordWriteSaveFP,21,22,1 block_hint,RecordWriteSaveFP,28,27,0 block_hint,RecordWriteSaveFP,53,45,0 -block_hint,RecordWriteSaveFP,48,47,0 block_hint,RecordWriteSaveFP,50,49,1 block_hint,RecordWriteIgnoreFP,3,2,1 block_hint,RecordWriteIgnoreFP,4,9,1 block_hint,RecordWriteIgnoreFP,6,5,1 block_hint,RecordWriteIgnoreFP,7,8,1 -block_hint,RecordWriteIgnoreFP,25,13,1 block_hint,RecordWriteIgnoreFP,28,27,0 block_hint,RecordWriteIgnoreFP,53,45,0 -block_hint,RecordWriteIgnoreFP,48,47,0 block_hint,AdaptorWithBuiltinExitFrame1,2,1,1 block_hint,AdaptorWithBuiltinExitFrame2,2,1,1 block_hint,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,67,1 @@ -87,6 +85,7 @@ block_hint,CallWithSpread_Baseline,36,29,0 block_hint,CallWithSpread_Baseline,35,30,1 block_hint,CallWithSpread_Baseline,69,86,1 +block_hint,CallWithSpread_Baseline,71,70,1 block_hint,CallWithSpread_Baseline,73,72,1 block_hint,CallWithSpread_Baseline,75,74,1 block_hint,CallWithSpread_Baseline,85,76,0 @@ -356,6 +355,7 @@ block_hint,KeyedStoreIC_Megamorphic,286,285,0 block_hint,KeyedStoreIC_Megamorphic,288,289,1 block_hint,KeyedStoreIC_Megamorphic,295,294,1 +block_hint,KeyedStoreIC_Megamorphic,315,314,1 block_hint,KeyedStoreIC_Megamorphic,685,613,1 block_hint,KeyedStoreIC_Megamorphic,684,683,1 block_hint,KeyedStoreIC_Megamorphic,699,693,0 @@ -1632,7 +1632,6 @@ block_hint,StoreIC,380,379,0 block_hint,StoreIC_Megamorphic,1,2,1 block_hint,StoreIC_Megamorphic,5,4,0 -block_hint,StoreIC_Megamorphic,8,9,1 block_hint,StoreIC_Megamorphic,12,15,1 block_hint,StoreIC_Megamorphic,13,14,1 block_hint,StoreIC_Megamorphic,17,268,1 @@ -1722,6 +1721,7 @@ block_hint,KeyedStoreIC,442,4,0 block_hint,KeyedStoreIC,440,5,0 block_hint,KeyedStoreIC,7,8,0 +block_hint,KeyedStoreIC,15,16,1 block_hint,KeyedStoreIC,22,23,1 block_hint,KeyedStoreIC,27,313,1 block_hint,KeyedStoreIC,203,28,0 @@ -2154,7 +2154,6 @@ block_hint,LessThanOrEqual_Baseline,45,28,1 block_hint,LessThanOrEqual_Baseline,78,69,1 block_hint,LessThanOrEqual_Baseline,89,80,1 -block_hint,LessThanOrEqual_Baseline,91,102,0 block_hint,LessThanOrEqual_Baseline,101,92,1 block_hint,LessThanOrEqual_Baseline,117,116,1 block_hint,GreaterThanOrEqual_Baseline,49,5,0 @@ -3911,7 +3910,6 @@ block_hint,Equal,67,62,0 block_hint,Equal,66,63,0 block_hint,Equal,64,65,1 -block_hint,Equal,68,69,0 block_hint,Equal,77,76,0 block_hint,Equal,81,80,0 block_hint,StrictEqual,2,25,1 @@ -4459,6 +4457,7 @@ block_hint,StringPrototypeSubstring,17,16,0 block_hint,StringPrototypeSubstring,24,19,0 block_hint,StringPrototypeSubstring,23,20,0 +block_hint,StringPrototypeSubstring,22,21,0 block_hint,StringPrototypeSubstring,37,36,0 block_hint,StringPrototypeSubstring,44,39,0 block_hint,StringPrototypeSubstring,43,40,0 @@ -4747,7 +4746,9 @@ block_hint,FastNewRestArguments,41,2,0 block_hint,FastNewRestArguments,4,3,1 block_hint,FastNewRestArguments,7,6,1 +block_hint,FastNewRestArguments,35,8,0 block_hint,FastNewRestArguments,9,10,0 +block_hint,FastNewRestArguments,34,11,0 block_hint,FastNewRestArguments,33,12,0 block_hint,FastNewRestArguments,32,13,0 block_hint,FastNewRestArguments,14,17,1 @@ -4876,6 +4877,8 @@ block_hint,MergeAt,71,76,1 block_hint,MergeAt,72,75,1 block_hint,MergeAt,74,73,0 +block_hint,MergeAt,85,82,0 +block_hint,MergeAt,83,84,0 block_hint,MergeAt,89,88,1 block_hint,MergeAt,91,118,1 block_hint,MergeAt,97,117,1 @@ -5275,7 +5278,6 @@ block_hint,MulSmiHandler,33,30,0 block_hint,MulSmiHandler,32,31,1 block_hint,MulSmiHandler,72,71,1 -block_hint,DivSmiHandler,27,1,0 block_hint,DivSmiHandler,15,2,0 block_hint,DivSmiHandler,4,3,0 block_hint,DivSmiHandler,9,8,0 @@ -5453,8 +5455,6 @@ block_hint,TestEqualStrictHandler,85,71,0 block_hint,TestEqualStrictHandler,94,93,1 block_hint,TestLessThanHandler,49,5,0 -block_hint,TestLessThanHandler,27,6,1 -block_hint,TestLessThanHandler,45,28,1 block_hint,TestLessThanHandler,78,69,1 block_hint,TestLessThanHandler,85,81,0 block_hint,TestLessThanHandler,91,102,0 @@ -5488,9 +5488,7 @@ block_hint,CreateArrayLiteralHandler,12,15,1 block_hint,CreateArrayLiteralHandler,14,13,1 block_hint,CreateArrayLiteralHandler,19,18,0 -block_hint,CreateArrayLiteralHandler,32,31,1 -block_hint,CreateArrayLiteralHandler,34,33,0 -block_hint,CreateArrayLiteralHandler,40,39,1 +block_hint,CreateArrayLiteralHandler,30,29,0 block_hint,CreateArrayLiteralHandler,71,46,0 block_hint,CreateArrayLiteralHandler,48,47,1 block_hint,CreateArrayLiteralHandler,50,49,1 @@ -5605,9 +5603,7 @@ block_hint,GetNamedPropertyWideHandler,23,20,0 block_hint,GetNamedPropertyWideHandler,22,21,1 block_hint,GetNamedPropertyWideHandler,100,106,1 -block_hint,GetNamedPropertyWideHandler,104,101,0 block_hint,GetNamedPropertyWideHandler,103,102,0 -block_hint,GetNamedPropertyWideHandler,247,114,1 block_hint,GetNamedPropertyWideHandler,259,249,0 block_hint,GetNamedPropertyWideHandler,255,258,1 block_hint,GetNamedPropertyWideHandler,256,257,1 @@ -5711,20 +5707,19 @@ block_hint,BitwiseOrSmiExtraWideHandler,1,36,0 block_hint,BitwiseOrSmiExtraWideHandler,41,38,1 block_hint,BitwiseOrSmiExtraWideHandler,40,39,0 -block_hint,BitwiseXorSmiExtraWideHandler,41,38,1 block_hint,BitwiseAndSmiExtraWideHandler,24,3,1 block_hint,BitwiseAndSmiExtraWideHandler,27,26,0 block_hint,BitwiseAndSmiExtraWideHandler,41,38,1 block_hint,CallUndefinedReceiver1ExtraWideHandler,1,67,0 -builtin_count,RecordWriteSaveFP,1865 -builtin_count,RecordWriteIgnoreFP,1 +builtin_count,RecordWriteSaveFP,1853 +builtin_count,RecordWriteIgnoreFP,0 builtin_count,EphemeronKeyBarrierSaveFP,0 builtin_count,AdaptorWithBuiltinExitFrame0,116 builtin_count,AdaptorWithBuiltinExitFrame1,4 builtin_count,AdaptorWithBuiltinExitFrame2,0 builtin_count,AdaptorWithBuiltinExitFrame3,8 builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,384 -builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1427 +builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1429 builtin_count,Call_ReceiverIsAny_Baseline_Compact,5 builtin_count,CallProxy,0 builtin_count,CallWithSpread,19 @@ -5734,16 +5729,16 @@ builtin_count,ConstructWithSpread,0 builtin_count,ConstructWithSpread_Baseline,0 builtin_count,ConstructForwardAllArgs_Baseline,1 -builtin_count,Construct_Baseline,123 -builtin_count,FastNewObject,373 -builtin_count,FastNewClosure,97 -builtin_count,StringEqual,780 +builtin_count,Construct_Baseline,122 +builtin_count,FastNewObject,388 +builtin_count,FastNewClosure,98 +builtin_count,StringEqual,779 builtin_count,StringGreaterThan,0 builtin_count,StringGreaterThanOrEqual,4 builtin_count,StringLessThan,483 builtin_count,StringLessThanOrEqual,49 builtin_count,StringCompare,3 -builtin_count,StringSubstring,576 +builtin_count,StringSubstring,575 builtin_count,OrderedHashTableHealIndex,0 builtin_count,CompileLazy,1 builtin_count,InstantiateAsmJs,0 @@ -5759,23 +5754,23 @@ builtin_count,GrowFastSmiOrObjectElements,351 builtin_count,ToNumber,0 builtin_count,ToNumber_Baseline,0 -builtin_count,ToNumeric_Baseline,87 +builtin_count,ToNumeric_Baseline,86 builtin_count,ToNumberConvertBigInt,3 builtin_count,Typeof,30 builtin_count,Typeof_Baseline,2 builtin_count,KeyedLoadIC_PolymorphicName,1 -builtin_count,KeyedStoreIC_Megamorphic,384 +builtin_count,KeyedStoreIC_Megamorphic,383 builtin_count,DefineKeyedOwnIC_Megamorphic,2 builtin_count,LoadGlobalIC_NoFeedback,16 builtin_count,LoadIC_FunctionPrototype,213 -builtin_count,LoadIC_StringLength,193 +builtin_count,LoadIC_StringLength,192 builtin_count,LoadIC_StringWrapperLength,0 builtin_count,LoadIC_NoFeedback,46 builtin_count,StoreIC_NoFeedback,6 builtin_count,DefineNamedOwnIC_NoFeedback,4 builtin_count,KeyedLoadIC_SloppyArguments,2 -builtin_count,StoreFastElementIC_InBounds,461 -builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,47 +builtin_count,StoreFastElementIC_InBounds,458 +builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,45 builtin_count,StoreFastElementIC_NoTransitionHandleCOW,0 builtin_count,ElementsTransitionAndStore_InBounds,1 builtin_count,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,0 @@ -5788,7 +5783,7 @@ builtin_count,SetDataProperties,2 builtin_count,ReturnReceiver,4 builtin_count,ArrayConstructor,1 -builtin_count,ArrayConstructorImpl,233 +builtin_count,ArrayConstructorImpl,232 builtin_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,0 builtin_count,ArrayNoArgumentConstructor_HoleySmi_DontOverride,0 builtin_count,ArrayNoArgumentConstructor_PackedSmi_DisableAllocationSites,0 @@ -5801,11 +5796,11 @@ builtin_count,ArraySingleArgumentConstructor_HoleyDouble_DisableAllocationSites,0 builtin_count,ArrayIncludesSmi,0 builtin_count,ArrayIncludesSmiOrObject,18 -builtin_count,ArrayIncludes,0 +builtin_count,ArrayIncludes,1 builtin_count,ArrayIndexOfSmi,0 builtin_count,ArrayIndexOfSmiOrObject,144 builtin_count,ArrayIndexOf,26 -builtin_count,ArrayPrototypePop,13 +builtin_count,ArrayPrototypePop,14 builtin_count,ArrayPrototypePush,348 builtin_count,CloneFastJSArray,196 builtin_count,CloneFastJSArrayFillingHoles,41 @@ -5817,7 +5812,7 @@ builtin_count,ArrayPrototypeEntries,0 builtin_count,ArrayPrototypeKeys,0 builtin_count,ArrayPrototypeValues,33 -builtin_count,ArrayIteratorPrototypeNext,78 +builtin_count,ArrayIteratorPrototypeNext,77 builtin_count,AsyncFunctionEnter,0 builtin_count,AsyncFunctionResolve,0 builtin_count,AsyncFunctionAwait,4 @@ -5842,49 +5837,49 @@ builtin_count,CallIteratorWithFeedbackLazyDeoptContinuation,0 builtin_count,GlobalIsFinite,0 builtin_count,GlobalIsNaN,0 -builtin_count,LoadIC,5654 +builtin_count,LoadIC,5643 builtin_count,LoadIC_Megamorphic,10000 builtin_count,LoadIC_Noninlined,5 -builtin_count,LoadICTrampoline,348 -builtin_count,LoadICBaseline,5068 -builtin_count,LoadICTrampoline_Megamorphic,6337 +builtin_count,LoadICTrampoline,340 +builtin_count,LoadICBaseline,5059 +builtin_count,LoadICTrampoline_Megamorphic,6280 builtin_count,LoadSuperIC,5 builtin_count,LoadSuperICBaseline,5 -builtin_count,KeyedLoadIC,950 +builtin_count,KeyedLoadIC,945 builtin_count,EnumeratedKeyedLoadIC,7 -builtin_count,KeyedLoadIC_Megamorphic,2428 +builtin_count,KeyedLoadIC_Megamorphic,2427 builtin_count,KeyedLoadICTrampoline,1 -builtin_count,KeyedLoadICBaseline,884 +builtin_count,KeyedLoadICBaseline,879 builtin_count,EnumeratedKeyedLoadICBaseline,5 -builtin_count,KeyedLoadICTrampoline_Megamorphic,1198 -builtin_count,StoreGlobalIC,321 -builtin_count,StoreGlobalICTrampoline,225 +builtin_count,KeyedLoadICTrampoline_Megamorphic,1221 +builtin_count,StoreGlobalIC,307 +builtin_count,StoreGlobalICTrampoline,224 builtin_count,StoreGlobalICBaseline,6 builtin_count,StoreIC,683 -builtin_count,StoreIC_Megamorphic,1306 +builtin_count,StoreIC_Megamorphic,1305 builtin_count,StoreICTrampoline,19 -builtin_count,StoreICTrampoline_Megamorphic,630 +builtin_count,StoreICTrampoline_Megamorphic,629 builtin_count,StoreICBaseline,621 -builtin_count,DefineNamedOwnIC,80 +builtin_count,DefineNamedOwnIC,79 builtin_count,DefineNamedOwnICBaseline,73 -builtin_count,KeyedStoreIC,496 +builtin_count,KeyedStoreIC,490 builtin_count,KeyedStoreICTrampoline,1 builtin_count,KeyedStoreICTrampoline_Megamorphic,310 -builtin_count,KeyedStoreICBaseline,449 +builtin_count,KeyedStoreICBaseline,444 builtin_count,DefineKeyedOwnIC,2 builtin_count,StoreInArrayLiteralIC,43 builtin_count,StoreInArrayLiteralICBaseline,38 -builtin_count,LoadGlobalIC,1037 +builtin_count,LoadGlobalIC,973 builtin_count,LoadGlobalICInsideTypeof,2 -builtin_count,LoadGlobalICTrampoline,97 -builtin_count,LoadGlobalICBaseline,874 +builtin_count,LoadGlobalICTrampoline,68 +builtin_count,LoadGlobalICBaseline,873 builtin_count,LoadGlobalICInsideTypeofTrampoline,0 builtin_count,LoadGlobalICInsideTypeofBaseline,2 builtin_count,LookupGlobalICBaseline,2 builtin_count,LookupGlobalICInsideTypeofBaseline,0 -builtin_count,KeyedHasIC,727 +builtin_count,KeyedHasIC,726 builtin_count,KeyedHasICBaseline,6 -builtin_count,KeyedHasIC_Megamorphic,725 +builtin_count,KeyedHasIC_Megamorphic,724 builtin_count,IterableToList,0 builtin_count,IterableToListWithSymbolLookup,0 builtin_count,IterableToListMayPreserveHoles,0 @@ -5893,7 +5888,7 @@ builtin_count,MapConstructor,77 builtin_count,MapPrototypeSet,66 builtin_count,MapPrototypeDelete,0 -builtin_count,MapPrototypeGet,6 +builtin_count,MapPrototypeGet,5 builtin_count,MapPrototypeHas,1 builtin_count,MapPrototypeEntries,0 builtin_count,MapPrototypeGetSize,0 @@ -5902,11 +5897,11 @@ builtin_count,MapPrototypeValues,0 builtin_count,MapIteratorPrototypeNext,9 builtin_count,MapIteratorToList,0 -builtin_count,Add_Baseline,569 -builtin_count,AddSmi_Baseline,551 +builtin_count,Add_Baseline,564 +builtin_count,AddSmi_Baseline,552 builtin_count,Subtract_Baseline,123 builtin_count,SubtractSmi_Baseline,72 -builtin_count,Multiply_Baseline,181 +builtin_count,Multiply_Baseline,180 builtin_count,MultiplySmi_Baseline,29 builtin_count,Divide_Baseline,15 builtin_count,DivideSmi_Baseline,5 @@ -5914,9 +5909,9 @@ builtin_count,ModulusSmi_Baseline,4 builtin_count,Exponentiate_Baseline,0 builtin_count,BitwiseAnd_Baseline,32 -builtin_count,BitwiseAndSmi_Baseline,115 -builtin_count,BitwiseOr_Baseline,59 -builtin_count,BitwiseOrSmi_Baseline,283 +builtin_count,BitwiseAndSmi_Baseline,114 +builtin_count,BitwiseOr_Baseline,58 +builtin_count,BitwiseOrSmi_Baseline,284 builtin_count,BitwiseXor_Baseline,40 builtin_count,BitwiseXorSmi_Baseline,1 builtin_count,ShiftLeft_Baseline,5 @@ -5925,15 +5920,15 @@ builtin_count,ShiftRightSmi_Baseline,236 builtin_count,ShiftRightLogical_Baseline,1 builtin_count,ShiftRightLogicalSmi_Baseline,18 -builtin_count,Equal_Baseline,332 -builtin_count,StrictEqual_Baseline,496 -builtin_count,LessThan_Baseline,475 -builtin_count,GreaterThan_Baseline,164 -builtin_count,LessThanOrEqual_Baseline,62 -builtin_count,GreaterThanOrEqual_Baseline,119 +builtin_count,Equal_Baseline,330 +builtin_count,StrictEqual_Baseline,497 +builtin_count,LessThan_Baseline,466 +builtin_count,GreaterThan_Baseline,162 +builtin_count,LessThanOrEqual_Baseline,60 +builtin_count,GreaterThanOrEqual_Baseline,117 builtin_count,BitwiseNot_Baseline,6 builtin_count,Decrement_Baseline,53 -builtin_count,Increment_Baseline,321 +builtin_count,Increment_Baseline,316 builtin_count,Negate_Baseline,13 builtin_count,ObjectAssign,2 builtin_count,ObjectCreate,3 @@ -5951,7 +5946,7 @@ builtin_count,ForInFilter,223 builtin_count,RegExpConstructor,0 builtin_count,FindOrderedHashSetEntry,116 -builtin_count,SetConstructor,115 +builtin_count,SetConstructor,114 builtin_count,SetPrototypeHas,1 builtin_count,SetPrototypeAdd,72 builtin_count,SetPrototypeDelete,9 @@ -5966,7 +5961,7 @@ builtin_count,StringPrototypeSplit,54 builtin_count,TypedArrayConstructor,2 builtin_count,TypedArrayPrototypeByteLength,0 -builtin_count,TypedArrayPrototypeLength,14 +builtin_count,TypedArrayPrototypeLength,13 builtin_count,TypedArrayPrototypeToStringTag,0 builtin_count,WasmToJsWrapperCSA,0 builtin_count,WeakMapConstructor,0 @@ -5985,8 +5980,8 @@ builtin_count,AsyncGeneratorAwait,7 builtin_count,AsyncGeneratorAwaitResolveClosure,7 builtin_count,AsyncGeneratorYieldWithAwaitResolveClosure,8 -builtin_count,StringAdd_CheckNone,8653 -builtin_count,SubString,1671 +builtin_count,StringAdd_CheckNone,8649 +builtin_count,SubString,1670 builtin_count,GetProperty,765 builtin_count,GetPropertyWithReceiver,17 builtin_count,SetProperty,0 @@ -6003,7 +5998,7 @@ builtin_count,ArrayForEach,2 builtin_count,ArrayFrom,0 builtin_count,ArrayIsArray,5 -builtin_count,LoadJoinElement_FastSmiOrObjectElements_0,742 +builtin_count,LoadJoinElement_FastSmiOrObjectElements_0,741 builtin_count,LoadJoinElement_FastDoubleElements_0,103 builtin_count,JoinStackPush,0 builtin_count,JoinStackPop,0 @@ -6030,20 +6025,20 @@ builtin_count,BooleanPrototypeToString,0 builtin_count,ToString,74 builtin_count,StringPrototypeToString,19 -builtin_count,StringPrototypeCharAt,124 -builtin_count,StringPrototypeCharCodeAt,117 +builtin_count,StringPrototypeCharAt,123 +builtin_count,StringPrototypeCharCodeAt,116 builtin_count,StringPrototypeCodePointAt,0 builtin_count,StringPrototypeConcat,0 builtin_count,StringConstructor,33 builtin_count,StringAddConvertLeft,17 builtin_count,StringAddConvertRight,200 builtin_count,StringCharAt,9 -builtin_count,FastNewClosureBaseline,87 -builtin_count,FastNewFunctionContextFunction,93 -builtin_count,CreateRegExpLiteral,41 +builtin_count,FastNewClosureBaseline,88 +builtin_count,FastNewFunctionContextFunction,94 +builtin_count,CreateRegExpLiteral,43 builtin_count,CreateShallowArrayLiteral,20 builtin_count,CreateEmptyArrayLiteral,29 -builtin_count,CreateShallowObjectLiteral,32 +builtin_count,CreateShallowObjectLiteral,31 builtin_count,ObjectConstructor,24 builtin_count,CreateEmptyLiteralObject,3 builtin_count,NumberConstructor,0 @@ -6059,7 +6054,7 @@ builtin_count,ToObject,248 builtin_count,NonPrimitiveToPrimitive_Default,181 builtin_count,NonPrimitiveToPrimitive_Number,14 -builtin_count,NonPrimitiveToPrimitive_String,43 +builtin_count,NonPrimitiveToPrimitive_String,42 builtin_count,OrdinaryToPrimitive_Number,0 builtin_count,OrdinaryToPrimitive_Number_Inline,196 builtin_count,OrdinaryToPrimitive_String,0 @@ -6097,7 +6092,7 @@ builtin_count,NumberIsInteger,0 builtin_count,NumberIsNaN,0 builtin_count,NumberParseFloat,12 -builtin_count,ParseInt,136 +builtin_count,ParseInt,135 builtin_count,NumberParseInt,6 builtin_count,Add,13 builtin_count,Subtract,0 @@ -6138,14 +6133,14 @@ builtin_count,ReflectGet,0 builtin_count,ReflectHas,0 builtin_count,RegExpPrototypeExec,423 -builtin_count,RegExpMatchFast,1252 +builtin_count,RegExpMatchFast,1251 builtin_count,RegExpReplace,199 builtin_count,RegExpPrototypeReplace,0 builtin_count,RegExpSearchFast,1 builtin_count,RegExpPrototypeSourceGetter,0 builtin_count,RegExpSplit,14 -builtin_count,RegExpPrototypeTest,96 -builtin_count,RegExpPrototypeTestFast,452 +builtin_count,RegExpPrototypeTest,97 +builtin_count,RegExpPrototypeTestFast,451 builtin_count,RegExpPrototypeGlobalGetter,0 builtin_count,RegExpPrototypeIgnoreCaseGetter,0 builtin_count,RegExpPrototypeMultilineGetter,0 @@ -6160,7 +6155,7 @@ builtin_count,StringPrototypeIndexOf,5 builtin_count,StringPrototypeIterator,0 builtin_count,StringIteratorPrototypeNext,0 -builtin_count,StringPrototypeMatch,1252 +builtin_count,StringPrototypeMatch,1251 builtin_count,StringPrototypeSearch,1 builtin_count,StringRepeat,0 builtin_count,StringPrototypeSlice,11 @@ -6175,10 +6170,10 @@ builtin_count,TypedArrayPrototypeSubArray,1 builtin_count,NewSloppyArgumentsElements,40 builtin_count,NewStrictArgumentsElements,0 -builtin_count,NewRestArgumentsElements,14 +builtin_count,NewRestArgumentsElements,13 builtin_count,FastNewSloppyArguments,5 builtin_count,FastNewStrictArguments,3 -builtin_count,FastNewRestArguments,1 +builtin_count,FastNewRestArguments,2 builtin_count,AllocateIfMutableHeapNumberScriptContextSlot,1 builtin_count,StoreCurrentScriptContextSlotBaseline,0 builtin_count,StoreScriptContextSlotBaseline,0 @@ -6191,14 +6186,14 @@ builtin_count,Store_FastObjectElements_0,243 builtin_count,Store_FastDoubleElements_0,0 builtin_count,SortCompareDefault,3 -builtin_count,SortCompareUserFn,781 +builtin_count,SortCompareUserFn,780 builtin_count,Copy,2 builtin_count,MergeAt,1 builtin_count,GallopLeft,1 builtin_count,GallopRight,1 builtin_count,ArrayTimSort,38 builtin_count,ArrayPrototypeSort,39 -builtin_count,StringFastLocaleCompare,1431 +builtin_count,StringFastLocaleCompare,1430 builtin_count,JSToWasmWrapper,0 builtin_count,JSToWasmHandleReturns,0 builtin_count,WasmTaggedNonSmiToInt32,0 @@ -6212,7 +6207,7 @@ builtin_count,StringToLowerCaseIntl,147 builtin_count,WideHandler,74 builtin_count,ExtraWideHandler,18 -builtin_count,LdarHandler,243 +builtin_count,LdarHandler,244 builtin_count,LdaZeroHandler,26 builtin_count,LdaSmiHandler,27 builtin_count,LdaUndefinedHandler,14 @@ -6220,11 +6215,11 @@ builtin_count,LdaTheHoleHandler,0 builtin_count,LdaTrueHandler,4 builtin_count,LdaFalseHandler,6 -builtin_count,LdaConstantHandler,23 +builtin_count,LdaConstantHandler,24 builtin_count,LdaContextSlotHandler,1 builtin_count,LdaScriptContextSlotHandler,0 -builtin_count,LdaImmutableContextSlotHandler,9 -builtin_count,LdaCurrentContextSlotHandler,19 +builtin_count,LdaImmutableContextSlotHandler,10 +builtin_count,LdaCurrentContextSlotHandler,20 builtin_count,LdaCurrentScriptContextSlotHandler,0 builtin_count,LdaImmutableCurrentContextSlotHandler,34 builtin_count,StarHandler,35 @@ -6232,27 +6227,27 @@ builtin_count,PushContextHandler,3 builtin_count,PopContextHandler,0 builtin_count,TestReferenceEqualHandler,1 -builtin_count,TestUndetectableHandler,2 +builtin_count,TestUndetectableHandler,1 builtin_count,TestNullHandler,0 builtin_count,TestUndefinedHandler,0 builtin_count,TestTypeOfHandler,1 -builtin_count,LdaGlobalHandler,55 +builtin_count,LdaGlobalHandler,54 builtin_count,LdaGlobalInsideTypeofHandler,0 builtin_count,StaGlobalHandler,2 builtin_count,StaContextSlotHandler,0 -builtin_count,StaCurrentContextSlotHandler,10 +builtin_count,StaCurrentContextSlotHandler,12 builtin_count,StaScriptContextSlotHandler,0 builtin_count,StaCurrentScriptContextSlotHandler,0 builtin_count,LdaLookupGlobalSlotHandler,1 builtin_count,LdaLookupGlobalSlotInsideTypeofHandler,0 builtin_count,StaLookupSlotHandler,0 -builtin_count,GetNamedPropertyHandler,164 +builtin_count,GetNamedPropertyHandler,163 builtin_count,GetNamedPropertyFromSuperHandler,0 builtin_count,GetKeyedPropertyHandler,62 builtin_count,GetEnumeratedKeyedPropertyHandler,1 -builtin_count,SetNamedPropertyHandler,19 +builtin_count,SetNamedPropertyHandler,18 builtin_count,DefineNamedOwnPropertyHandler,4 -builtin_count,SetKeyedPropertyHandler,44 +builtin_count,SetKeyedPropertyHandler,43 builtin_count,DefineKeyedOwnPropertyHandler,0 builtin_count,StaInArrayLiteralHandler,4 builtin_count,DefineKeyedOwnPropertyInLiteralHandler,0 @@ -6292,7 +6287,7 @@ builtin_count,CallAnyReceiverHandler,0 builtin_count,CallPropertyHandler,4 builtin_count,CallProperty0Handler,14 -builtin_count,CallProperty1Handler,29 +builtin_count,CallProperty1Handler,30 builtin_count,CallProperty2Handler,7 builtin_count,CallUndefinedReceiverHandler,1 builtin_count,CallUndefinedReceiver0Handler,11 @@ -6307,7 +6302,7 @@ builtin_count,ConstructForwardAllArgsHandler,0 builtin_count,TestEqualHandler,13 builtin_count,TestEqualStrictHandler,12 -builtin_count,TestLessThanHandler,38 +builtin_count,TestLessThanHandler,39 builtin_count,TestGreaterThanHandler,5 builtin_count,TestLessThanOrEqualHandler,2 builtin_count,TestGreaterThanOrEqualHandler,5 @@ -6315,7 +6310,7 @@ builtin_count,TestInHandler,0 builtin_count,ToNameHandler,0 builtin_count,ToNumberHandler,0 -builtin_count,ToNumericHandler,17 +builtin_count,ToNumericHandler,16 builtin_count,ToObjectHandler,0 builtin_count,ToStringHandler,0 builtin_count,ToBooleanHandler,0 @@ -6328,11 +6323,11 @@ builtin_count,CreateClosureHandler,8 builtin_count,CreateBlockContextHandler,0 builtin_count,CreateCatchContextHandler,0 -builtin_count,CreateFunctionContextHandler,2 +builtin_count,CreateFunctionContextHandler,3 builtin_count,CreateMappedArgumentsHandler,0 builtin_count,CreateUnmappedArgumentsHandler,0 builtin_count,CreateRestParameterHandler,0 -builtin_count,JumpLoopHandler,52 +builtin_count,JumpLoopHandler,53 builtin_count,JumpHandler,9 builtin_count,JumpConstantHandler,0 builtin_count,JumpIfUndefinedConstantHandler,0 @@ -6345,8 +6340,8 @@ builtin_count,JumpIfToBooleanFalseConstantHandler,0 builtin_count,JumpIfToBooleanTrueHandler,13 builtin_count,JumpIfToBooleanFalseHandler,30 -builtin_count,JumpIfTrueHandler,12 -builtin_count,JumpIfFalseHandler,67 +builtin_count,JumpIfTrueHandler,13 +builtin_count,JumpIfFalseHandler,68 builtin_count,JumpIfNullHandler,0 builtin_count,JumpIfNotNullHandler,0 builtin_count,JumpIfUndefinedHandler,1 @@ -6371,7 +6366,7 @@ builtin_count,SuspendGeneratorHandler,0 builtin_count,ResumeGeneratorHandler,0 builtin_count,GetIteratorHandler,0 -builtin_count,ShortStarHandler,122 +builtin_count,ShortStarHandler,123 builtin_count,LdarWideHandler,0 builtin_count,LdaSmiWideHandler,12 builtin_count,LdaConstantWideHandler,1 @@ -6469,22 +6464,22 @@ builtin_count,CallUndefinedReceiverExtraWideHandler,0 builtin_count,CallUndefinedReceiver1ExtraWideHandler,4 builtin_count,CallUndefinedReceiver2ExtraWideHandler,0 -block_count,RecordWriteSaveFP,0,1865 -block_count,RecordWriteSaveFP,1,1802 +block_count,RecordWriteSaveFP,0,1853 +block_count,RecordWriteSaveFP,1,1810 block_count,RecordWriteSaveFP,2,0 -block_count,RecordWriteSaveFP,3,1802 -block_count,RecordWriteSaveFP,4,1802 +block_count,RecordWriteSaveFP,3,1810 +block_count,RecordWriteSaveFP,4,1810 block_count,RecordWriteSaveFP,5,0 -block_count,RecordWriteSaveFP,6,1802 -block_count,RecordWriteSaveFP,7,1801 +block_count,RecordWriteSaveFP,6,1810 +block_count,RecordWriteSaveFP,7,1809 block_count,RecordWriteSaveFP,8,0 block_count,RecordWriteSaveFP,9,0 -block_count,RecordWriteSaveFP,10,0 -block_count,RecordWriteSaveFP,11,1802 -block_count,RecordWriteSaveFP,12,63 -block_count,RecordWriteSaveFP,13,39 -block_count,RecordWriteSaveFP,14,37 -block_count,RecordWriteSaveFP,15,37 +block_count,RecordWriteSaveFP,10,1 +block_count,RecordWriteSaveFP,11,1810 +block_count,RecordWriteSaveFP,12,43 +block_count,RecordWriteSaveFP,13,29 +block_count,RecordWriteSaveFP,14,27 +block_count,RecordWriteSaveFP,15,27 block_count,RecordWriteSaveFP,16,0 block_count,RecordWriteSaveFP,17,2 block_count,RecordWriteSaveFP,18,2 @@ -6494,9 +6489,9 @@ block_count,RecordWriteSaveFP,22,0 block_count,RecordWriteSaveFP,23,0 block_count,RecordWriteSaveFP,24,0 -block_count,RecordWriteSaveFP,25,24 -block_count,RecordWriteSaveFP,26,63 -block_count,RecordWriteSaveFP,27,63 +block_count,RecordWriteSaveFP,25,13 +block_count,RecordWriteSaveFP,26,43 +block_count,RecordWriteSaveFP,27,43 block_count,RecordWriteSaveFP,28,0 block_count,RecordWriteSaveFP,29,0 block_count,RecordWriteSaveFP,30,0 @@ -6513,13 +6508,13 @@ block_count,RecordWriteSaveFP,41,0 block_count,RecordWriteSaveFP,42,0 block_count,RecordWriteSaveFP,43,0 -block_count,RecordWriteSaveFP,44,63 -block_count,RecordWriteSaveFP,45,63 -block_count,RecordWriteSaveFP,46,61 -block_count,RecordWriteSaveFP,47,61 -block_count,RecordWriteSaveFP,48,0 +block_count,RecordWriteSaveFP,44,43 +block_count,RecordWriteSaveFP,45,43 +block_count,RecordWriteSaveFP,46,40 +block_count,RecordWriteSaveFP,47,39 +block_count,RecordWriteSaveFP,48,1 block_count,RecordWriteSaveFP,49,0 -block_count,RecordWriteSaveFP,50,0 +block_count,RecordWriteSaveFP,50,1 block_count,RecordWriteSaveFP,51,2 block_count,RecordWriteSaveFP,52,2 block_count,RecordWriteSaveFP,53,0 @@ -6527,8 +6522,8 @@ block_count,RecordWriteSaveFP,55,0 block_count,RecordWriteSaveFP,56,0 block_count,RecordWriteSaveFP,57,0 -block_count,RecordWriteSaveFP,58,63 -block_count,RecordWriteIgnoreFP,0,1 +block_count,RecordWriteSaveFP,58,43 +block_count,RecordWriteIgnoreFP,0,0 block_count,RecordWriteIgnoreFP,1,0 block_count,RecordWriteIgnoreFP,2,0 block_count,RecordWriteIgnoreFP,3,0 @@ -6603,14 +6598,14 @@ block_count,AdaptorWithBuiltinExitFrame3,3,8 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,384 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,384 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,90 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,5,78 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,91 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,5,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,6,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,7,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,8,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,9,78 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,7,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,8,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,9,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,10,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,11,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,12,0 @@ -6628,15 +6623,15 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,24,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,25,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,26,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,27,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,28,78 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,29,78 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,27,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,28,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,29,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,30,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,31,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,32,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,33,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,34,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,78 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,35,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,36,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,37,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,38,0 @@ -6666,13 +6661,13 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,62,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,64,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,65,11 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,294 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,65,13 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,293 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,67,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,384 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,1427 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,1427 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,84 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,1429 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,1429 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,83 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,3,32 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,4,31 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,5,31 @@ -6736,9 +6731,9 @@ block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,64,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,51 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,1343 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,1345 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,1427 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,1429 block_count,Call_ReceiverIsAny_Baseline_Compact,0,5 block_count,Call_ReceiverIsAny_Baseline_Compact,1,5 block_count,Call_ReceiverIsAny_Baseline_Compact,2,0 @@ -6978,24 +6973,24 @@ block_count,CallWithSpread_Baseline,63,0 block_count,CallWithSpread_Baseline,64,0 block_count,CallWithSpread_Baseline,65,0 -block_count,CallWithSpread_Baseline,66,1 +block_count,CallWithSpread_Baseline,66,2 block_count,CallWithSpread_Baseline,67,0 block_count,CallWithSpread_Baseline,68,2 block_count,CallWithSpread_Baseline,69,2 block_count,CallWithSpread_Baseline,70,0 -block_count,CallWithSpread_Baseline,71,1 +block_count,CallWithSpread_Baseline,71,2 block_count,CallWithSpread_Baseline,72,0 -block_count,CallWithSpread_Baseline,73,1 +block_count,CallWithSpread_Baseline,73,2 block_count,CallWithSpread_Baseline,74,0 -block_count,CallWithSpread_Baseline,75,1 -block_count,CallWithSpread_Baseline,76,1 -block_count,CallWithSpread_Baseline,77,1 +block_count,CallWithSpread_Baseline,75,2 +block_count,CallWithSpread_Baseline,76,2 +block_count,CallWithSpread_Baseline,77,2 block_count,CallWithSpread_Baseline,78,0 block_count,CallWithSpread_Baseline,79,0 block_count,CallWithSpread_Baseline,80,0 block_count,CallWithSpread_Baseline,81,0 block_count,CallWithSpread_Baseline,82,0 -block_count,CallWithSpread_Baseline,83,1 +block_count,CallWithSpread_Baseline,83,2 block_count,CallWithSpread_Baseline,84,0 block_count,CallWithSpread_Baseline,85,0 block_count,CallWithSpread_Baseline,86,0 @@ -7367,7 +7362,7 @@ block_count,ConstructForwardAllArgs_Baseline,41,0 block_count,ConstructForwardAllArgs_Baseline,42,0 block_count,ConstructForwardAllArgs_Baseline,43,1 -block_count,Construct_Baseline,0,123 +block_count,Construct_Baseline,0,122 block_count,Construct_Baseline,1,7 block_count,Construct_Baseline,2,4 block_count,Construct_Baseline,3,4 @@ -7410,15 +7405,15 @@ block_count,Construct_Baseline,40,0 block_count,Construct_Baseline,41,4 block_count,Construct_Baseline,42,3 -block_count,Construct_Baseline,43,115 +block_count,Construct_Baseline,43,114 block_count,Construct_Baseline,44,118 -block_count,FastNewObject,0,373 +block_count,FastNewObject,0,388 block_count,FastNewObject,1,0 -block_count,FastNewObject,2,373 -block_count,FastNewObject,3,373 -block_count,FastNewObject,4,370 -block_count,FastNewObject,5,370 -block_count,FastNewObject,6,370 +block_count,FastNewObject,2,388 +block_count,FastNewObject,3,388 +block_count,FastNewObject,4,385 +block_count,FastNewObject,5,385 +block_count,FastNewObject,6,385 block_count,FastNewObject,7,0 block_count,FastNewObject,8,0 block_count,FastNewObject,9,0 @@ -7444,25 +7439,25 @@ block_count,FastNewObject,29,0 block_count,FastNewObject,30,0 block_count,FastNewObject,31,0 -block_count,FastNewObject,32,370 -block_count,FastNewObject,33,370 +block_count,FastNewObject,32,385 +block_count,FastNewObject,33,385 block_count,FastNewObject,34,0 -block_count,FastNewObject,35,370 +block_count,FastNewObject,35,385 block_count,FastNewObject,36,0 block_count,FastNewObject,37,0 -block_count,FastNewObject,38,370 -block_count,FastNewObject,39,370 +block_count,FastNewObject,38,385 +block_count,FastNewObject,39,384 block_count,FastNewObject,40,1 -block_count,FastNewObject,41,368 +block_count,FastNewObject,41,383 block_count,FastNewObject,42,46 -block_count,FastNewObject,43,322 -block_count,FastNewObject,44,530 -block_count,FastNewObject,45,208 -block_count,FastNewObject,46,322 -block_count,FastNewObject,47,368 -block_count,FastNewObject,48,263 -block_count,FastNewObject,49,105 -block_count,FastNewObject,50,370 +block_count,FastNewObject,43,337 +block_count,FastNewObject,44,547 +block_count,FastNewObject,45,210 +block_count,FastNewObject,46,337 +block_count,FastNewObject,47,383 +block_count,FastNewObject,48,269 +block_count,FastNewObject,49,114 +block_count,FastNewObject,50,384 block_count,FastNewObject,51,0 block_count,FastNewObject,52,0 block_count,FastNewObject,53,0 @@ -7492,21 +7487,21 @@ block_count,FastNewObject,77,2 block_count,FastNewObject,78,0 block_count,FastNewObject,79,2 -block_count,FastNewClosure,0,97 -block_count,FastNewClosure,1,92 -block_count,FastNewClosure,2,92 +block_count,FastNewClosure,0,98 +block_count,FastNewClosure,1,93 +block_count,FastNewClosure,2,93 block_count,FastNewClosure,3,0 block_count,FastNewClosure,4,4 -block_count,FastNewClosure,5,97 +block_count,FastNewClosure,5,98 block_count,FastNewClosure,6,0 -block_count,FastNewClosure,7,97 -block_count,FastNewClosure,8,97 +block_count,FastNewClosure,7,98 +block_count,FastNewClosure,8,98 block_count,FastNewClosure,9,0 -block_count,FastNewClosure,10,97 +block_count,FastNewClosure,10,98 block_count,FastNewClosure,11,0 block_count,FastNewClosure,12,0 -block_count,FastNewClosure,13,97 -block_count,FastNewClosure,14,28 +block_count,FastNewClosure,13,98 +block_count,FastNewClosure,14,29 block_count,FastNewClosure,15,68 block_count,FastNewClosure,16,68 block_count,FastNewClosure,17,0 @@ -7516,10 +7511,10 @@ block_count,FastNewClosure,21,68 block_count,FastNewClosure,22,0 block_count,FastNewClosure,23,68 -block_count,FastNewClosure,24,97 -block_count,FastNewClosure,25,28 +block_count,FastNewClosure,24,98 +block_count,FastNewClosure,25,29 block_count,FastNewClosure,26,68 -block_count,StringEqual,0,780 +block_count,StringEqual,0,779 block_count,StringEqual,1,793 block_count,StringEqual,2,307 block_count,StringEqual,3,17 @@ -7554,16 +7549,16 @@ block_count,StringEqual,32,12 block_count,StringEqual,33,12 block_count,StringEqual,34,0 -block_count,StringEqual,35,277 -block_count,StringEqual,36,277 +block_count,StringEqual,35,276 +block_count,StringEqual,36,276 block_count,StringEqual,37,0 -block_count,StringEqual,38,277 -block_count,StringEqual,39,277 +block_count,StringEqual,38,276 +block_count,StringEqual,39,276 block_count,StringEqual,40,0 -block_count,StringEqual,41,277 -block_count,StringEqual,42,277 +block_count,StringEqual,41,276 +block_count,StringEqual,42,276 block_count,StringEqual,43,0 -block_count,StringEqual,44,277 +block_count,StringEqual,44,276 block_count,StringEqual,45,79 block_count,StringEqual,46,197 block_count,StringEqual,47,220 @@ -7643,7 +7638,7 @@ block_count,StringEqual,121,0 block_count,StringEqual,122,0 block_count,StringEqual,123,0 -block_count,StringEqual,124,486 +block_count,StringEqual,124,485 block_count,StringGreaterThan,0,0 block_count,StringGreaterThan,1,0 block_count,StringGreaterThan,2,0 @@ -7753,7 +7748,7 @@ block_count,StringGreaterThanOrEqual,56,3 block_count,StringLessThan,0,483 block_count,StringLessThan,1,483 -block_count,StringLessThan,2,480 +block_count,StringLessThan,2,479 block_count,StringLessThan,3,0 block_count,StringLessThan,4,0 block_count,StringLessThan,5,0 @@ -7779,14 +7774,14 @@ block_count,StringLessThan,25,0 block_count,StringLessThan,26,0 block_count,StringLessThan,27,0 -block_count,StringLessThan,28,480 +block_count,StringLessThan,28,479 block_count,StringLessThan,29,223 block_count,StringLessThan,30,223 block_count,StringLessThan,31,0 block_count,StringLessThan,32,256 block_count,StringLessThan,33,256 block_count,StringLessThan,34,0 -block_count,StringLessThan,35,480 +block_count,StringLessThan,35,479 block_count,StringLessThan,36,20 block_count,StringLessThan,37,21 block_count,StringLessThan,38,20 @@ -7795,9 +7790,9 @@ block_count,StringLessThan,41,0 block_count,StringLessThan,42,459 block_count,StringLessThan,43,479 -block_count,StringLessThan,44,901 +block_count,StringLessThan,44,900 block_count,StringLessThan,45,900 -block_count,StringLessThan,46,421 +block_count,StringLessThan,46,420 block_count,StringLessThan,47,479 block_count,StringLessThan,48,229 block_count,StringLessThan,49,249 @@ -7810,7 +7805,7 @@ block_count,StringLessThan,56,3 block_count,StringLessThanOrEqual,0,49 block_count,StringLessThanOrEqual,1,49 -block_count,StringLessThanOrEqual,2,45 +block_count,StringLessThanOrEqual,2,44 block_count,StringLessThanOrEqual,3,0 block_count,StringLessThanOrEqual,4,0 block_count,StringLessThanOrEqual,5,0 @@ -7836,26 +7831,26 @@ block_count,StringLessThanOrEqual,25,0 block_count,StringLessThanOrEqual,26,0 block_count,StringLessThanOrEqual,27,0 -block_count,StringLessThanOrEqual,28,45 +block_count,StringLessThanOrEqual,28,44 block_count,StringLessThanOrEqual,29,0 block_count,StringLessThanOrEqual,30,0 block_count,StringLessThanOrEqual,31,0 -block_count,StringLessThanOrEqual,32,45 -block_count,StringLessThanOrEqual,33,45 +block_count,StringLessThanOrEqual,32,44 +block_count,StringLessThanOrEqual,33,44 block_count,StringLessThanOrEqual,34,0 -block_count,StringLessThanOrEqual,35,45 +block_count,StringLessThanOrEqual,35,44 block_count,StringLessThanOrEqual,36,0 block_count,StringLessThanOrEqual,37,0 block_count,StringLessThanOrEqual,38,0 block_count,StringLessThanOrEqual,39,0 block_count,StringLessThanOrEqual,40,0 block_count,StringLessThanOrEqual,41,0 -block_count,StringLessThanOrEqual,42,45 -block_count,StringLessThanOrEqual,43,45 -block_count,StringLessThanOrEqual,44,45 -block_count,StringLessThanOrEqual,45,45 +block_count,StringLessThanOrEqual,42,44 +block_count,StringLessThanOrEqual,43,44 +block_count,StringLessThanOrEqual,44,44 +block_count,StringLessThanOrEqual,45,44 block_count,StringLessThanOrEqual,46,0 -block_count,StringLessThanOrEqual,47,45 +block_count,StringLessThanOrEqual,47,44 block_count,StringLessThanOrEqual,48,8 block_count,StringLessThanOrEqual,49,36 block_count,StringLessThanOrEqual,50,0 @@ -7922,23 +7917,23 @@ block_count,StringCompare,54,0 block_count,StringCompare,55,0 block_count,StringCompare,56,0 -block_count,StringSubstring,0,576 -block_count,StringSubstring,1,564 -block_count,StringSubstring,2,564 -block_count,StringSubstring,3,456 -block_count,StringSubstring,4,206 -block_count,StringSubstring,5,412 -block_count,StringSubstring,6,19 -block_count,StringSubstring,7,19 +block_count,StringSubstring,0,575 +block_count,StringSubstring,1,563 +block_count,StringSubstring,2,563 +block_count,StringSubstring,3,455 +block_count,StringSubstring,4,197 +block_count,StringSubstring,5,394 +block_count,StringSubstring,6,10 +block_count,StringSubstring,7,10 block_count,StringSubstring,8,0 block_count,StringSubstring,9,179 block_count,StringSubstring,10,6 -block_count,StringSubstring,11,206 +block_count,StringSubstring,11,197 block_count,StringSubstring,12,0 -block_count,StringSubstring,13,206 +block_count,StringSubstring,13,197 block_count,StringSubstring,14,0 -block_count,StringSubstring,15,250 -block_count,StringSubstring,16,456 +block_count,StringSubstring,15,258 +block_count,StringSubstring,16,455 block_count,StringSubstring,17,200 block_count,StringSubstring,18,5 block_count,StringSubstring,19,0 @@ -8020,7 +8015,7 @@ block_count,StringSubstring,95,216 block_count,StringSubstring,96,0 block_count,StringSubstring,97,216 -block_count,StringSubstring,98,495 +block_count,StringSubstring,98,494 block_count,StringSubstring,99,278 block_count,StringSubstring,100,216 block_count,StringSubstring,101,216 @@ -8112,16 +8107,16 @@ block_count,StringSubstring,187,0 block_count,StringSubstring,188,0 block_count,StringSubstring,189,107 -block_count,StringSubstring,190,9 -block_count,StringSubstring,191,18 -block_count,StringSubstring,192,7 -block_count,StringSubstring,193,7 +block_count,StringSubstring,190,6 +block_count,StringSubstring,191,13 +block_count,StringSubstring,192,4 +block_count,StringSubstring,193,4 block_count,StringSubstring,194,0 block_count,StringSubstring,195,1 block_count,StringSubstring,196,0 -block_count,StringSubstring,197,9 +block_count,StringSubstring,197,6 block_count,StringSubstring,198,0 -block_count,StringSubstring,199,9 +block_count,StringSubstring,199,6 block_count,StringSubstring,200,0 block_count,StringSubstring,201,0 block_count,StringSubstring,202,0 @@ -8132,7 +8127,7 @@ block_count,StringSubstring,207,0 block_count,StringSubstring,208,0 block_count,StringSubstring,209,0 -block_count,StringSubstring,210,98 +block_count,StringSubstring,210,101 block_count,StringSubstring,211,107 block_count,StringSubstring,212,107 block_count,StringSubstring,213,4 @@ -8271,19 +8266,19 @@ block_count,GrowFastDoubleElements,18,383 block_count,GrowFastDoubleElements,19,0 block_count,GrowFastDoubleElements,20,383 -block_count,GrowFastDoubleElements,21,4375 -block_count,GrowFastDoubleElements,22,3992 +block_count,GrowFastDoubleElements,21,4373 +block_count,GrowFastDoubleElements,22,3990 block_count,GrowFastDoubleElements,23,383 block_count,GrowFastDoubleElements,24,383 block_count,GrowFastDoubleElements,25,102 block_count,GrowFastDoubleElements,26,281 block_count,GrowFastDoubleElements,27,383 block_count,GrowFastDoubleElements,28,164 -block_count,GrowFastDoubleElements,29,4893 -block_count,GrowFastDoubleElements,30,4892 +block_count,GrowFastDoubleElements,29,4890 +block_count,GrowFastDoubleElements,30,4889 block_count,GrowFastDoubleElements,31,0 -block_count,GrowFastDoubleElements,32,4893 -block_count,GrowFastDoubleElements,33,4728 +block_count,GrowFastDoubleElements,32,4890 +block_count,GrowFastDoubleElements,33,4726 block_count,GrowFastDoubleElements,34,164 block_count,GrowFastDoubleElements,35,219 block_count,GrowFastDoubleElements,36,0 @@ -8304,16 +8299,16 @@ block_count,GrowFastSmiOrObjectElements,11,351 block_count,GrowFastSmiOrObjectElements,12,0 block_count,GrowFastSmiOrObjectElements,13,351 -block_count,GrowFastSmiOrObjectElements,14,4634 -block_count,GrowFastSmiOrObjectElements,15,4283 +block_count,GrowFastSmiOrObjectElements,14,4633 +block_count,GrowFastSmiOrObjectElements,15,4282 block_count,GrowFastSmiOrObjectElements,16,351 block_count,GrowFastSmiOrObjectElements,17,351 block_count,GrowFastSmiOrObjectElements,18,17 block_count,GrowFastSmiOrObjectElements,19,333 block_count,GrowFastSmiOrObjectElements,20,351 block_count,GrowFastSmiOrObjectElements,21,46 -block_count,GrowFastSmiOrObjectElements,22,7147 -block_count,GrowFastSmiOrObjectElements,23,7101 +block_count,GrowFastSmiOrObjectElements,22,7146 +block_count,GrowFastSmiOrObjectElements,23,7100 block_count,GrowFastSmiOrObjectElements,24,46 block_count,GrowFastSmiOrObjectElements,25,304 block_count,GrowFastSmiOrObjectElements,26,0 @@ -8366,7 +8361,7 @@ block_count,ToNumber_Baseline,22,0 block_count,ToNumber_Baseline,23,0 block_count,ToNumber_Baseline,24,0 -block_count,ToNumeric_Baseline,0,87 +block_count,ToNumeric_Baseline,0,86 block_count,ToNumeric_Baseline,1,0 block_count,ToNumeric_Baseline,2,0 block_count,ToNumeric_Baseline,3,0 @@ -8394,10 +8389,10 @@ block_count,ToNumeric_Baseline,25,0 block_count,ToNumeric_Baseline,26,0 block_count,ToNumeric_Baseline,27,0 -block_count,ToNumeric_Baseline,28,87 -block_count,ToNumeric_Baseline,29,87 +block_count,ToNumeric_Baseline,28,86 +block_count,ToNumeric_Baseline,29,86 block_count,ToNumeric_Baseline,30,0 -block_count,ToNumeric_Baseline,31,87 +block_count,ToNumeric_Baseline,31,86 block_count,ToNumberConvertBigInt,0,3 block_count,ToNumberConvertBigInt,1,3 block_count,ToNumberConvertBigInt,2,0 @@ -8803,9 +8798,9 @@ block_count,KeyedLoadIC_PolymorphicName,299,0 block_count,KeyedLoadIC_PolymorphicName,300,0 block_count,KeyedLoadIC_PolymorphicName,301,0 -block_count,KeyedStoreIC_Megamorphic,0,384 -block_count,KeyedStoreIC_Megamorphic,1,384 -block_count,KeyedStoreIC_Megamorphic,2,384 +block_count,KeyedStoreIC_Megamorphic,0,383 +block_count,KeyedStoreIC_Megamorphic,1,383 +block_count,KeyedStoreIC_Megamorphic,2,383 block_count,KeyedStoreIC_Megamorphic,3,305 block_count,KeyedStoreIC_Megamorphic,4,304 block_count,KeyedStoreIC_Megamorphic,5,0 @@ -8838,7 +8833,7 @@ block_count,KeyedStoreIC_Megamorphic,32,48 block_count,KeyedStoreIC_Megamorphic,33,0 block_count,KeyedStoreIC_Megamorphic,34,252 -block_count,KeyedStoreIC_Megamorphic,35,174 +block_count,KeyedStoreIC_Megamorphic,35,173 block_count,KeyedStoreIC_Megamorphic,36,165 block_count,KeyedStoreIC_Megamorphic,37,2 block_count,KeyedStoreIC_Megamorphic,38,2 @@ -8986,8 +8981,8 @@ block_count,KeyedStoreIC_Megamorphic,180,98 block_count,KeyedStoreIC_Megamorphic,181,0 block_count,KeyedStoreIC_Megamorphic,182,98 -block_count,KeyedStoreIC_Megamorphic,183,50 -block_count,KeyedStoreIC_Megamorphic,184,47 +block_count,KeyedStoreIC_Megamorphic,183,52 +block_count,KeyedStoreIC_Megamorphic,184,46 block_count,KeyedStoreIC_Megamorphic,185,98 block_count,KeyedStoreIC_Megamorphic,186,86 block_count,KeyedStoreIC_Megamorphic,187,11 @@ -9099,7 +9094,7 @@ block_count,KeyedStoreIC_Megamorphic,293,6 block_count,KeyedStoreIC_Megamorphic,294,0 block_count,KeyedStoreIC_Megamorphic,295,6 -block_count,KeyedStoreIC_Megamorphic,296,26 +block_count,KeyedStoreIC_Megamorphic,296,25 block_count,KeyedStoreIC_Megamorphic,297,19 block_count,KeyedStoreIC_Megamorphic,298,6 block_count,KeyedStoreIC_Megamorphic,299,6 @@ -9122,8 +9117,8 @@ block_count,KeyedStoreIC_Megamorphic,316,0 block_count,KeyedStoreIC_Megamorphic,317,0 block_count,KeyedStoreIC_Megamorphic,318,2 -block_count,KeyedStoreIC_Megamorphic,319,2 -block_count,KeyedStoreIC_Megamorphic,320,2 +block_count,KeyedStoreIC_Megamorphic,319,3 +block_count,KeyedStoreIC_Megamorphic,320,3 block_count,KeyedStoreIC_Megamorphic,321,0 block_count,KeyedStoreIC_Megamorphic,322,0 block_count,KeyedStoreIC_Megamorphic,323,0 @@ -10208,7 +10203,7 @@ block_count,KeyedStoreIC_Megamorphic,1402,7 block_count,KeyedStoreIC_Megamorphic,1403,48 block_count,KeyedStoreIC_Megamorphic,1404,55 -block_count,KeyedStoreIC_Megamorphic,1405,55 +block_count,KeyedStoreIC_Megamorphic,1405,54 block_count,KeyedStoreIC_Megamorphic,1406,54 block_count,KeyedStoreIC_Megamorphic,1407,0 block_count,KeyedStoreIC_Megamorphic,1408,0 @@ -11431,7 +11426,7 @@ block_count,LoadIC_FunctionPrototype,2,1 block_count,LoadIC_FunctionPrototype,3,212 block_count,LoadIC_FunctionPrototype,4,0 -block_count,LoadIC_StringLength,0,193 +block_count,LoadIC_StringLength,0,192 block_count,LoadIC_StringWrapperLength,0,0 block_count,LoadIC_NoFeedback,0,46 block_count,LoadIC_NoFeedback,1,46 @@ -12556,7 +12551,7 @@ block_count,KeyedLoadIC_SloppyArguments,20,0 block_count,KeyedLoadIC_SloppyArguments,21,0 block_count,KeyedLoadIC_SloppyArguments,22,0 -block_count,StoreFastElementIC_InBounds,0,461 +block_count,StoreFastElementIC_InBounds,0,458 block_count,StoreFastElementIC_InBounds,1,0 block_count,StoreFastElementIC_InBounds,2,12 block_count,StoreFastElementIC_InBounds,3,12 @@ -12577,24 +12572,24 @@ block_count,StoreFastElementIC_InBounds,18,0 block_count,StoreFastElementIC_InBounds,19,12 block_count,StoreFastElementIC_InBounds,20,0 -block_count,StoreFastElementIC_InBounds,21,13 -block_count,StoreFastElementIC_InBounds,22,13 +block_count,StoreFastElementIC_InBounds,21,14 +block_count,StoreFastElementIC_InBounds,22,14 block_count,StoreFastElementIC_InBounds,23,0 block_count,StoreFastElementIC_InBounds,24,0 block_count,StoreFastElementIC_InBounds,25,0 block_count,StoreFastElementIC_InBounds,26,0 block_count,StoreFastElementIC_InBounds,27,0 -block_count,StoreFastElementIC_InBounds,28,13 -block_count,StoreFastElementIC_InBounds,29,13 +block_count,StoreFastElementIC_InBounds,28,14 +block_count,StoreFastElementIC_InBounds,29,14 block_count,StoreFastElementIC_InBounds,30,0 -block_count,StoreFastElementIC_InBounds,31,13 +block_count,StoreFastElementIC_InBounds,31,14 block_count,StoreFastElementIC_InBounds,32,0 -block_count,StoreFastElementIC_InBounds,33,13 -block_count,StoreFastElementIC_InBounds,34,13 +block_count,StoreFastElementIC_InBounds,33,14 +block_count,StoreFastElementIC_InBounds,34,14 block_count,StoreFastElementIC_InBounds,35,0 -block_count,StoreFastElementIC_InBounds,36,13 +block_count,StoreFastElementIC_InBounds,36,14 block_count,StoreFastElementIC_InBounds,37,0 -block_count,StoreFastElementIC_InBounds,38,13 +block_count,StoreFastElementIC_InBounds,38,14 block_count,StoreFastElementIC_InBounds,39,0 block_count,StoreFastElementIC_InBounds,40,26 block_count,StoreFastElementIC_InBounds,41,26 @@ -12774,26 +12769,26 @@ block_count,StoreFastElementIC_InBounds,215,19 block_count,StoreFastElementIC_InBounds,216,0 block_count,StoreFastElementIC_InBounds,217,19 -block_count,StoreFastElementIC_InBounds,218,66 +block_count,StoreFastElementIC_InBounds,218,65 block_count,StoreFastElementIC_InBounds,219,0 block_count,StoreFastElementIC_InBounds,220,0 block_count,StoreFastElementIC_InBounds,221,0 block_count,StoreFastElementIC_InBounds,222,0 block_count,StoreFastElementIC_InBounds,223,0 -block_count,StoreFastElementIC_InBounds,224,66 -block_count,StoreFastElementIC_InBounds,225,66 -block_count,StoreFastElementIC_InBounds,226,66 +block_count,StoreFastElementIC_InBounds,224,65 +block_count,StoreFastElementIC_InBounds,225,65 +block_count,StoreFastElementIC_InBounds,226,65 block_count,StoreFastElementIC_InBounds,227,0 block_count,StoreFastElementIC_InBounds,228,0 block_count,StoreFastElementIC_InBounds,229,0 block_count,StoreFastElementIC_InBounds,230,0 block_count,StoreFastElementIC_InBounds,231,0 block_count,StoreFastElementIC_InBounds,232,0 -block_count,StoreFastElementIC_InBounds,233,66 -block_count,StoreFastElementIC_InBounds,234,66 -block_count,StoreFastElementIC_InBounds,235,66 +block_count,StoreFastElementIC_InBounds,233,65 +block_count,StoreFastElementIC_InBounds,234,65 +block_count,StoreFastElementIC_InBounds,235,65 block_count,StoreFastElementIC_InBounds,236,0 -block_count,StoreFastElementIC_InBounds,237,66 +block_count,StoreFastElementIC_InBounds,237,65 block_count,StoreFastElementIC_InBounds,238,0 block_count,StoreFastElementIC_InBounds,239,0 block_count,StoreFastElementIC_InBounds,240,19 @@ -12890,26 +12885,26 @@ block_count,StoreFastElementIC_InBounds,331,0 block_count,StoreFastElementIC_InBounds,332,0 block_count,StoreFastElementIC_InBounds,333,0 -block_count,StoreFastElementIC_InBounds,334,196 +block_count,StoreFastElementIC_InBounds,334,197 block_count,StoreFastElementIC_InBounds,335,0 block_count,StoreFastElementIC_InBounds,336,0 block_count,StoreFastElementIC_InBounds,337,0 block_count,StoreFastElementIC_InBounds,338,0 block_count,StoreFastElementIC_InBounds,339,0 -block_count,StoreFastElementIC_InBounds,340,196 -block_count,StoreFastElementIC_InBounds,341,196 -block_count,StoreFastElementIC_InBounds,342,196 +block_count,StoreFastElementIC_InBounds,340,197 +block_count,StoreFastElementIC_InBounds,341,197 +block_count,StoreFastElementIC_InBounds,342,197 block_count,StoreFastElementIC_InBounds,343,6 block_count,StoreFastElementIC_InBounds,344,6 block_count,StoreFastElementIC_InBounds,345,0 block_count,StoreFastElementIC_InBounds,346,0 block_count,StoreFastElementIC_InBounds,347,0 block_count,StoreFastElementIC_InBounds,348,6 -block_count,StoreFastElementIC_InBounds,349,190 -block_count,StoreFastElementIC_InBounds,350,196 -block_count,StoreFastElementIC_InBounds,351,196 +block_count,StoreFastElementIC_InBounds,349,191 +block_count,StoreFastElementIC_InBounds,350,197 +block_count,StoreFastElementIC_InBounds,351,197 block_count,StoreFastElementIC_InBounds,352,0 -block_count,StoreFastElementIC_InBounds,353,196 +block_count,StoreFastElementIC_InBounds,353,197 block_count,StoreFastElementIC_InBounds,354,0 block_count,StoreFastElementIC_InBounds,355,0 block_count,StoreFastElementIC_InBounds,356,0 @@ -12966,26 +12961,26 @@ block_count,StoreFastElementIC_InBounds,407,0 block_count,StoreFastElementIC_InBounds,408,0 block_count,StoreFastElementIC_InBounds,409,0 -block_count,StoreFastElementIC_InBounds,410,56 +block_count,StoreFastElementIC_InBounds,410,52 block_count,StoreFastElementIC_InBounds,411,0 block_count,StoreFastElementIC_InBounds,412,0 block_count,StoreFastElementIC_InBounds,413,0 block_count,StoreFastElementIC_InBounds,414,0 block_count,StoreFastElementIC_InBounds,415,0 -block_count,StoreFastElementIC_InBounds,416,56 -block_count,StoreFastElementIC_InBounds,417,56 -block_count,StoreFastElementIC_InBounds,418,56 +block_count,StoreFastElementIC_InBounds,416,52 +block_count,StoreFastElementIC_InBounds,417,52 +block_count,StoreFastElementIC_InBounds,418,52 block_count,StoreFastElementIC_InBounds,419,48 block_count,StoreFastElementIC_InBounds,420,48 block_count,StoreFastElementIC_InBounds,421,0 block_count,StoreFastElementIC_InBounds,422,0 block_count,StoreFastElementIC_InBounds,423,0 block_count,StoreFastElementIC_InBounds,424,48 -block_count,StoreFastElementIC_InBounds,425,7 -block_count,StoreFastElementIC_InBounds,426,56 -block_count,StoreFastElementIC_InBounds,427,56 +block_count,StoreFastElementIC_InBounds,425,3 +block_count,StoreFastElementIC_InBounds,426,52 +block_count,StoreFastElementIC_InBounds,427,52 block_count,StoreFastElementIC_InBounds,428,0 -block_count,StoreFastElementIC_InBounds,429,56 +block_count,StoreFastElementIC_InBounds,429,52 block_count,StoreFastElementIC_InBounds,430,0 block_count,StoreFastElementIC_InBounds,431,0 block_count,StoreFastElementIC_InBounds,432,0 @@ -13857,7 +13852,7 @@ block_count,StoreFastElementIC_InBounds,1298,0 block_count,StoreFastElementIC_InBounds,1299,0 block_count,StoreFastElementIC_InBounds,1300,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,47 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,45 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,1,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,3 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,3,0 @@ -14049,21 +14044,21 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,189,4 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,190,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,191,4 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,192,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,192,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,193,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,194,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,195,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,196,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,197,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,198,33 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,199,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,198,31 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,199,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,200,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,201,33 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,202,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,201,31 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,202,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,203,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,204,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,205,2 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,206,30 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,206,28 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,207,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,208,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,209,2 @@ -14079,15 +14074,15 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,219,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,220,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,221,28 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,222,26 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,222,25 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,223,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,224,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,225,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,226,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,227,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,228,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,229,26 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,230,24 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,229,24 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,230,22 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,231,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,232,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,233,2 @@ -14105,12 +14100,12 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,245,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,246,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,247,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,248,27 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,249,30 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,248,26 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,249,28 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,250,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,251,30 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,252,33 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,253,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,251,28 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,252,31 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,253,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,254,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,255,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,256,0 @@ -14139,9 +14134,9 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,279,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,280,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,281,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,282,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,282,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,283,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,284,33 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,284,31 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,285,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,286,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,287,0 @@ -14499,9 +14494,9 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,639,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,640,4 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,641,4 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,642,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,642,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,643,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,644,1 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,644,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,645,3 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,646,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,647,0 @@ -14525,7 +14520,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,665,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,666,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,667,2 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,668,2 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,668,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,669,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,670,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,671,0 @@ -14554,7 +14549,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,694,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,695,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,696,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,697,3 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,697,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,698,3 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,699,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,700,3 @@ -19364,7 +19359,7 @@ block_count,ArrayConstructor,1,0 block_count,ArrayConstructor,2,1 block_count,ArrayConstructor,3,1 -block_count,ArrayConstructorImpl,0,233 +block_count,ArrayConstructorImpl,0,232 block_count,ArrayConstructorImpl,1,120 block_count,ArrayConstructorImpl,2,4 block_count,ArrayConstructorImpl,3,2 @@ -19406,7 +19401,7 @@ block_count,ArrayConstructorImpl,39,0 block_count,ArrayConstructorImpl,40,115 block_count,ArrayConstructorImpl,41,0 -block_count,ArrayConstructorImpl,42,113 +block_count,ArrayConstructorImpl,42,112 block_count,ArrayConstructorImpl,43,113 block_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,0,0 block_count,ArrayNoArgumentConstructor_PackedSmi_DontOverride,1,0 @@ -19946,20 +19941,20 @@ block_count,ArrayIncludesSmiOrObject,135,0 block_count,ArrayIncludesSmiOrObject,136,32 block_count,ArrayIncludesSmiOrObject,137,15 -block_count,ArrayIncludes,0,0 +block_count,ArrayIncludes,0,1 block_count,ArrayIncludes,1,0 -block_count,ArrayIncludes,2,0 -block_count,ArrayIncludes,3,0 -block_count,ArrayIncludes,4,0 +block_count,ArrayIncludes,2,1 +block_count,ArrayIncludes,3,1 +block_count,ArrayIncludes,4,1 block_count,ArrayIncludes,5,0 -block_count,ArrayIncludes,6,0 -block_count,ArrayIncludes,7,0 -block_count,ArrayIncludes,8,0 -block_count,ArrayIncludes,9,0 +block_count,ArrayIncludes,6,1 +block_count,ArrayIncludes,7,1 +block_count,ArrayIncludes,8,1 +block_count,ArrayIncludes,9,1 block_count,ArrayIncludes,10,0 -block_count,ArrayIncludes,11,0 -block_count,ArrayIncludes,12,0 -block_count,ArrayIncludes,13,0 +block_count,ArrayIncludes,11,1 +block_count,ArrayIncludes,12,1 +block_count,ArrayIncludes,13,1 block_count,ArrayIncludes,14,0 block_count,ArrayIncludes,15,0 block_count,ArrayIncludes,16,0 @@ -19969,10 +19964,10 @@ block_count,ArrayIncludes,20,0 block_count,ArrayIncludes,21,0 block_count,ArrayIncludes,22,0 -block_count,ArrayIncludes,23,0 -block_count,ArrayIncludes,24,0 -block_count,ArrayIncludes,25,0 -block_count,ArrayIncludes,26,0 +block_count,ArrayIncludes,23,1 +block_count,ArrayIncludes,24,1 +block_count,ArrayIncludes,25,1 +block_count,ArrayIncludes,26,1 block_count,ArrayIncludes,27,0 block_count,ArrayIncludes,28,0 block_count,ArrayIncludes,29,0 @@ -19980,7 +19975,7 @@ block_count,ArrayIncludes,31,0 block_count,ArrayIncludes,32,0 block_count,ArrayIncludes,33,0 -block_count,ArrayIncludes,34,0 +block_count,ArrayIncludes,34,1 block_count,ArrayIncludes,35,0 block_count,ArrayIndexOfSmi,0,0 block_count,ArrayIndexOfSmi,1,0 @@ -20169,32 +20164,32 @@ block_count,ArrayIndexOfSmiOrObject,23,0 block_count,ArrayIndexOfSmiOrObject,24,0 block_count,ArrayIndexOfSmiOrObject,25,116 -block_count,ArrayIndexOfSmiOrObject,26,1764 +block_count,ArrayIndexOfSmiOrObject,26,1763 block_count,ArrayIndexOfSmiOrObject,27,1676 block_count,ArrayIndexOfSmiOrObject,28,1676 -block_count,ArrayIndexOfSmiOrObject,29,1663 +block_count,ArrayIndexOfSmiOrObject,29,1662 block_count,ArrayIndexOfSmiOrObject,30,0 -block_count,ArrayIndexOfSmiOrObject,31,1663 +block_count,ArrayIndexOfSmiOrObject,31,1662 block_count,ArrayIndexOfSmiOrObject,32,1385 block_count,ArrayIndexOfSmiOrObject,33,277 block_count,ArrayIndexOfSmiOrObject,34,228 block_count,ArrayIndexOfSmiOrObject,35,42 block_count,ArrayIndexOfSmiOrObject,36,37 block_count,ArrayIndexOfSmiOrObject,37,4 -block_count,ArrayIndexOfSmiOrObject,38,186 -block_count,ArrayIndexOfSmiOrObject,39,186 +block_count,ArrayIndexOfSmiOrObject,38,185 +block_count,ArrayIndexOfSmiOrObject,39,185 block_count,ArrayIndexOfSmiOrObject,40,0 block_count,ArrayIndexOfSmiOrObject,41,0 block_count,ArrayIndexOfSmiOrObject,42,0 -block_count,ArrayIndexOfSmiOrObject,43,186 -block_count,ArrayIndexOfSmiOrObject,44,186 +block_count,ArrayIndexOfSmiOrObject,43,185 +block_count,ArrayIndexOfSmiOrObject,44,185 block_count,ArrayIndexOfSmiOrObject,45,0 -block_count,ArrayIndexOfSmiOrObject,46,186 -block_count,ArrayIndexOfSmiOrObject,47,186 +block_count,ArrayIndexOfSmiOrObject,46,185 +block_count,ArrayIndexOfSmiOrObject,47,185 block_count,ArrayIndexOfSmiOrObject,48,0 -block_count,ArrayIndexOfSmiOrObject,49,186 -block_count,ArrayIndexOfSmiOrObject,50,186 -block_count,ArrayIndexOfSmiOrObject,51,186 +block_count,ArrayIndexOfSmiOrObject,49,185 +block_count,ArrayIndexOfSmiOrObject,50,185 +block_count,ArrayIndexOfSmiOrObject,51,185 block_count,ArrayIndexOfSmiOrObject,52,87 block_count,ArrayIndexOfSmiOrObject,53,98 block_count,ArrayIndexOfSmiOrObject,54,98 @@ -20278,7 +20273,7 @@ block_count,ArrayIndexOfSmiOrObject,132,48 block_count,ArrayIndexOfSmiOrObject,133,13 block_count,ArrayIndexOfSmiOrObject,134,0 -block_count,ArrayIndexOfSmiOrObject,135,1647 +block_count,ArrayIndexOfSmiOrObject,135,1646 block_count,ArrayIndexOfSmiOrObject,136,87 block_count,ArrayIndexOfSmiOrObject,137,0 block_count,ArrayIndexOfSmiOrObject,138,0 @@ -20342,23 +20337,23 @@ block_count,ArrayIndexOf,42,0 block_count,ArrayIndexOf,43,0 block_count,ArrayIndexOf,44,0 -block_count,ArrayPrototypePop,0,13 +block_count,ArrayPrototypePop,0,14 block_count,ArrayPrototypePop,1,0 -block_count,ArrayPrototypePop,2,13 -block_count,ArrayPrototypePop,3,13 -block_count,ArrayPrototypePop,4,13 -block_count,ArrayPrototypePop,5,13 -block_count,ArrayPrototypePop,6,13 +block_count,ArrayPrototypePop,2,14 +block_count,ArrayPrototypePop,3,14 +block_count,ArrayPrototypePop,4,14 +block_count,ArrayPrototypePop,5,14 +block_count,ArrayPrototypePop,6,14 block_count,ArrayPrototypePop,7,0 -block_count,ArrayPrototypePop,8,13 -block_count,ArrayPrototypePop,9,13 -block_count,ArrayPrototypePop,10,13 -block_count,ArrayPrototypePop,11,13 +block_count,ArrayPrototypePop,8,14 +block_count,ArrayPrototypePop,9,14 +block_count,ArrayPrototypePop,10,14 +block_count,ArrayPrototypePop,11,14 block_count,ArrayPrototypePop,12,0 -block_count,ArrayPrototypePop,13,13 -block_count,ArrayPrototypePop,14,13 -block_count,ArrayPrototypePop,15,13 -block_count,ArrayPrototypePop,16,13 +block_count,ArrayPrototypePop,13,14 +block_count,ArrayPrototypePop,14,14 +block_count,ArrayPrototypePop,15,14 +block_count,ArrayPrototypePop,16,14 block_count,ArrayPrototypePop,17,12 block_count,ArrayPrototypePop,18,0 block_count,ArrayPrototypePop,19,0 @@ -20415,16 +20410,16 @@ block_count,ArrayPrototypePush,30,0 block_count,ArrayPrototypePush,31,0 block_count,ArrayPrototypePush,32,0 -block_count,ArrayPrototypePush,33,26 -block_count,ArrayPrototypePush,34,25 +block_count,ArrayPrototypePush,33,25 +block_count,ArrayPrototypePush,34,24 block_count,ArrayPrototypePush,35,0 block_count,ArrayPrototypePush,36,0 block_count,ArrayPrototypePush,37,0 block_count,ArrayPrototypePush,38,0 block_count,ArrayPrototypePush,39,0 block_count,ArrayPrototypePush,40,0 -block_count,ArrayPrototypePush,41,74 -block_count,ArrayPrototypePush,42,73 +block_count,ArrayPrototypePush,41,73 +block_count,ArrayPrototypePush,42,72 block_count,ArrayPrototypePush,43,0 block_count,ArrayPrototypePush,44,0 block_count,ArrayPrototypePush,45,0 @@ -20433,14 +20428,14 @@ block_count,ArrayPrototypePush,48,32 block_count,ArrayPrototypePush,49,32 block_count,ArrayPrototypePush,50,32 -block_count,ArrayPrototypePush,51,32 -block_count,ArrayPrototypePush,52,32 +block_count,ArrayPrototypePush,51,31 +block_count,ArrayPrototypePush,52,31 block_count,ArrayPrototypePush,53,0 -block_count,ArrayPrototypePush,54,32 +block_count,ArrayPrototypePush,54,31 block_count,ArrayPrototypePush,55,0 block_count,ArrayPrototypePush,56,0 block_count,ArrayPrototypePush,57,0 -block_count,ArrayPrototypePush,58,32 +block_count,ArrayPrototypePush,58,31 block_count,ArrayPrototypePush,59,0 block_count,ArrayPrototypePush,60,0 block_count,ArrayPrototypePush,61,0 @@ -20449,7 +20444,7 @@ block_count,ArrayPrototypePush,64,0 block_count,ArrayPrototypePush,65,0 block_count,ArrayPrototypePush,66,0 -block_count,ArrayPrototypePush,67,315 +block_count,ArrayPrototypePush,67,316 block_count,ArrayPrototypePush,68,313 block_count,ArrayPrototypePush,69,2 block_count,ArrayPrototypePush,70,2 @@ -20515,9 +20510,9 @@ block_count,ArrayPrototypePush,130,0 block_count,ArrayPrototypePush,131,0 block_count,ArrayPrototypePush,132,0 -block_count,ArrayPrototypePush,133,313 +block_count,ArrayPrototypePush,133,314 block_count,ArrayPrototypePush,134,313 -block_count,ArrayPrototypePush,135,288 +block_count,ArrayPrototypePush,135,289 block_count,ArrayPrototypePush,136,24 block_count,ArrayPrototypePush,137,24 block_count,ArrayPrototypePush,138,24 @@ -20539,19 +20534,19 @@ block_count,ArrayPrototypePush,154,23 block_count,ArrayPrototypePush,155,24 block_count,ArrayPrototypePush,156,2 -block_count,ArrayPrototypePush,157,180 -block_count,ArrayPrototypePush,158,178 +block_count,ArrayPrototypePush,157,179 +block_count,ArrayPrototypePush,158,177 block_count,ArrayPrototypePush,159,2 block_count,ArrayPrototypePush,160,22 block_count,ArrayPrototypePush,161,24 block_count,ArrayPrototypePush,162,0 block_count,ArrayPrototypePush,163,0 block_count,ArrayPrototypePush,164,313 -block_count,ArrayPrototypePush,165,312 -block_count,ArrayPrototypePush,166,322 -block_count,ArrayPrototypePush,167,322 +block_count,ArrayPrototypePush,165,313 +block_count,ArrayPrototypePush,166,323 +block_count,ArrayPrototypePush,167,323 block_count,ArrayPrototypePush,168,9 -block_count,ArrayPrototypePush,169,312 +block_count,ArrayPrototypePush,169,313 block_count,ArrayPrototypePush,170,0 block_count,ArrayPrototypePush,171,0 block_count,ArrayPrototypePush,172,313 @@ -20880,8 +20875,8 @@ block_count,ExtractFastJSArray,29,0 block_count,ExtractFastJSArray,30,0 block_count,ExtractFastJSArray,31,0 -block_count,ExtractFastJSArray,32,5 -block_count,ExtractFastJSArray,33,5 +block_count,ExtractFastJSArray,32,1 +block_count,ExtractFastJSArray,33,1 block_count,ExtractFastJSArray,34,0 block_count,ExtractFastJSArray,35,0 block_count,ExtractFastJSArray,36,0 @@ -21206,7 +21201,7 @@ block_count,CreateObjectFromSlowBoilerplateHelper,125,55 block_count,CreateObjectFromSlowBoilerplateHelper,126,60 block_count,CreateObjectFromSlowBoilerplateHelper,127,60 -block_count,CreateObjectFromSlowBoilerplateHelper,128,60 +block_count,CreateObjectFromSlowBoilerplateHelper,128,59 block_count,CreateObjectFromSlowBoilerplateHelper,129,58 block_count,CreateObjectFromSlowBoilerplateHelper,130,1 block_count,CreateObjectFromSlowBoilerplateHelper,131,1 @@ -21356,13 +21351,13 @@ block_count,ArrayPrototypeValues,12,0 block_count,ArrayPrototypeValues,13,33 block_count,ArrayPrototypeValues,14,33 -block_count,ArrayIteratorPrototypeNext,0,78 +block_count,ArrayIteratorPrototypeNext,0,77 block_count,ArrayIteratorPrototypeNext,1,0 -block_count,ArrayIteratorPrototypeNext,2,78 -block_count,ArrayIteratorPrototypeNext,3,78 -block_count,ArrayIteratorPrototypeNext,4,78 +block_count,ArrayIteratorPrototypeNext,2,77 +block_count,ArrayIteratorPrototypeNext,3,77 +block_count,ArrayIteratorPrototypeNext,4,77 block_count,ArrayIteratorPrototypeNext,5,0 -block_count,ArrayIteratorPrototypeNext,6,78 +block_count,ArrayIteratorPrototypeNext,6,77 block_count,ArrayIteratorPrototypeNext,7,2 block_count,ArrayIteratorPrototypeNext,8,2 block_count,ArrayIteratorPrototypeNext,9,0 @@ -21543,22 +21538,22 @@ block_count,ArrayIteratorPrototypeNext,184,0 block_count,ArrayIteratorPrototypeNext,185,0 block_count,ArrayIteratorPrototypeNext,186,0 -block_count,ArrayIteratorPrototypeNext,187,75 +block_count,ArrayIteratorPrototypeNext,187,74 block_count,ArrayIteratorPrototypeNext,188,0 -block_count,ArrayIteratorPrototypeNext,189,75 -block_count,ArrayIteratorPrototypeNext,190,75 +block_count,ArrayIteratorPrototypeNext,189,74 +block_count,ArrayIteratorPrototypeNext,190,74 block_count,ArrayIteratorPrototypeNext,191,0 -block_count,ArrayIteratorPrototypeNext,192,75 -block_count,ArrayIteratorPrototypeNext,193,75 -block_count,ArrayIteratorPrototypeNext,194,19 -block_count,ArrayIteratorPrototypeNext,195,56 -block_count,ArrayIteratorPrototypeNext,196,56 +block_count,ArrayIteratorPrototypeNext,192,74 +block_count,ArrayIteratorPrototypeNext,193,74 +block_count,ArrayIteratorPrototypeNext,194,18 +block_count,ArrayIteratorPrototypeNext,195,55 +block_count,ArrayIteratorPrototypeNext,196,55 block_count,ArrayIteratorPrototypeNext,197,0 block_count,ArrayIteratorPrototypeNext,198,0 block_count,ArrayIteratorPrototypeNext,199,0 block_count,ArrayIteratorPrototypeNext,200,0 -block_count,ArrayIteratorPrototypeNext,201,56 -block_count,ArrayIteratorPrototypeNext,202,56 +block_count,ArrayIteratorPrototypeNext,201,55 +block_count,ArrayIteratorPrototypeNext,202,55 block_count,ArrayIteratorPrototypeNext,203,0 block_count,ArrayIteratorPrototypeNext,204,0 block_count,ArrayIteratorPrototypeNext,205,0 @@ -21578,13 +21573,13 @@ block_count,ArrayIteratorPrototypeNext,219,0 block_count,ArrayIteratorPrototypeNext,220,0 block_count,ArrayIteratorPrototypeNext,221,3 -block_count,ArrayIteratorPrototypeNext,222,44 +block_count,ArrayIteratorPrototypeNext,222,43 block_count,ArrayIteratorPrototypeNext,223,0 block_count,ArrayIteratorPrototypeNext,224,0 block_count,ArrayIteratorPrototypeNext,225,0 -block_count,ArrayIteratorPrototypeNext,226,48 +block_count,ArrayIteratorPrototypeNext,226,47 block_count,ArrayIteratorPrototypeNext,227,0 -block_count,ArrayIteratorPrototypeNext,228,48 +block_count,ArrayIteratorPrototypeNext,228,47 block_count,ArrayIteratorPrototypeNext,229,0 block_count,ArrayIteratorPrototypeNext,230,7 block_count,ArrayIteratorPrototypeNext,231,0 @@ -21605,7 +21600,7 @@ block_count,ArrayIteratorPrototypeNext,246,0 block_count,ArrayIteratorPrototypeNext,247,0 block_count,ArrayIteratorPrototypeNext,248,0 -block_count,ArrayIteratorPrototypeNext,249,56 +block_count,ArrayIteratorPrototypeNext,249,55 block_count,ArrayIteratorPrototypeNext,250,0 block_count,ArrayIteratorPrototypeNext,251,0 block_count,ArrayIteratorPrototypeNext,252,0 @@ -21616,7 +21611,7 @@ block_count,ArrayIteratorPrototypeNext,257,0 block_count,ArrayIteratorPrototypeNext,258,20 block_count,ArrayIteratorPrototypeNext,259,1 -block_count,ArrayIteratorPrototypeNext,260,19 +block_count,ArrayIteratorPrototypeNext,260,18 block_count,ArrayIteratorPrototypeNext,261,20 block_count,ArrayIteratorPrototypeNext,262,1 block_count,ArrayIteratorPrototypeNext,263,57 @@ -21631,12 +21626,12 @@ block_count,ArrayIteratorPrototypeNext,272,0 block_count,ArrayIteratorPrototypeNext,273,0 block_count,ArrayIteratorPrototypeNext,274,57 -block_count,ArrayIteratorPrototypeNext,275,78 +block_count,ArrayIteratorPrototypeNext,275,77 block_count,ArrayIteratorPrototypeNext,276,0 -block_count,ArrayIteratorPrototypeNext,277,78 +block_count,ArrayIteratorPrototypeNext,277,77 block_count,ArrayIteratorPrototypeNext,278,0 -block_count,ArrayIteratorPrototypeNext,279,78 -block_count,ArrayIteratorPrototypeNext,280,78 +block_count,ArrayIteratorPrototypeNext,279,77 +block_count,ArrayIteratorPrototypeNext,280,77 block_count,AsyncFunctionEnter,0,0 block_count,AsyncFunctionEnter,1,0 block_count,AsyncFunctionEnter,2,0 @@ -22035,15 +22030,15 @@ block_count,GlobalIsNaN,8,0 block_count,GlobalIsNaN,9,0 block_count,GlobalIsNaN,10,0 -block_count,LoadIC,0,5654 -block_count,LoadIC,1,5653 +block_count,LoadIC,0,5643 +block_count,LoadIC,1,5642 block_count,LoadIC,2,1 -block_count,LoadIC,3,5654 -block_count,LoadIC,4,5654 -block_count,LoadIC,5,1482 +block_count,LoadIC,3,5643 +block_count,LoadIC,4,5643 +block_count,LoadIC,5,1479 block_count,LoadIC,6,0 -block_count,LoadIC,7,1481 -block_count,LoadIC,8,291 +block_count,LoadIC,7,1479 +block_count,LoadIC,8,289 block_count,LoadIC,9,1 block_count,LoadIC,10,1 block_count,LoadIC,11,0 @@ -22057,36 +22052,36 @@ block_count,LoadIC,19,0 block_count,LoadIC,20,0 block_count,LoadIC,21,0 -block_count,LoadIC,22,290 -block_count,LoadIC,23,290 +block_count,LoadIC,22,288 +block_count,LoadIC,23,288 block_count,LoadIC,24,0 -block_count,LoadIC,25,290 -block_count,LoadIC,26,245 -block_count,LoadIC,27,242 -block_count,LoadIC,28,2 -block_count,LoadIC,29,45 -block_count,LoadIC,30,47 -block_count,LoadIC,31,44 -block_count,LoadIC,32,44 +block_count,LoadIC,25,288 +block_count,LoadIC,26,244 +block_count,LoadIC,27,243 +block_count,LoadIC,28,1 +block_count,LoadIC,29,43 +block_count,LoadIC,30,45 +block_count,LoadIC,31,42 +block_count,LoadIC,32,42 block_count,LoadIC,33,0 block_count,LoadIC,34,2 block_count,LoadIC,35,1189 -block_count,LoadIC,36,1964 -block_count,LoadIC,37,775 -block_count,LoadIC,38,775 +block_count,LoadIC,36,1960 +block_count,LoadIC,37,771 +block_count,LoadIC,38,771 block_count,LoadIC,39,0 -block_count,LoadIC,40,1189 -block_count,LoadIC,41,4171 -block_count,LoadIC,42,5649 -block_count,LoadIC,43,1917 -block_count,LoadIC,44,1908 -block_count,LoadIC,45,1585 -block_count,LoadIC,46,1584 +block_count,LoadIC,40,1188 +block_count,LoadIC,41,4163 +block_count,LoadIC,42,5638 +block_count,LoadIC,43,1915 +block_count,LoadIC,44,1905 +block_count,LoadIC,45,1583 +block_count,LoadIC,46,1583 block_count,LoadIC,47,0 -block_count,LoadIC,48,1584 +block_count,LoadIC,48,1582 block_count,LoadIC,49,0 -block_count,LoadIC,50,1585 -block_count,LoadIC,51,206 +block_count,LoadIC,50,1583 +block_count,LoadIC,51,205 block_count,LoadIC,52,37 block_count,LoadIC,53,37 block_count,LoadIC,54,0 @@ -22143,8 +22138,8 @@ block_count,LoadIC,105,0 block_count,LoadIC,106,0 block_count,LoadIC,107,1 -block_count,LoadIC,108,168 -block_count,LoadIC,109,168 +block_count,LoadIC,108,167 +block_count,LoadIC,109,167 block_count,LoadIC,110,0 block_count,LoadIC,111,0 block_count,LoadIC,112,0 @@ -22156,27 +22151,27 @@ block_count,LoadIC,118,0 block_count,LoadIC,119,0 block_count,LoadIC,120,0 -block_count,LoadIC,121,168 +block_count,LoadIC,121,167 block_count,LoadIC,122,0 -block_count,LoadIC,123,1378 -block_count,LoadIC,124,1583 -block_count,LoadIC,125,1582 -block_count,LoadIC,126,1497 -block_count,LoadIC,127,1497 +block_count,LoadIC,123,1377 +block_count,LoadIC,124,1581 +block_count,LoadIC,125,1580 +block_count,LoadIC,126,1495 +block_count,LoadIC,127,1495 block_count,LoadIC,128,0 block_count,LoadIC,129,85 -block_count,LoadIC,130,1582 +block_count,LoadIC,130,1580 block_count,LoadIC,131,0 -block_count,LoadIC,132,323 -block_count,LoadIC,133,8 -block_count,LoadIC,134,8 +block_count,LoadIC,132,322 +block_count,LoadIC,133,9 +block_count,LoadIC,134,9 block_count,LoadIC,135,0 -block_count,LoadIC,136,3731 -block_count,LoadIC,137,5314 -block_count,LoadIC,138,1837 -block_count,LoadIC,139,582 -block_count,LoadIC,140,496 -block_count,LoadIC,141,254 +block_count,LoadIC,136,3723 +block_count,LoadIC,137,5304 +block_count,LoadIC,138,1835 +block_count,LoadIC,139,580 +block_count,LoadIC,140,495 +block_count,LoadIC,141,253 block_count,LoadIC,142,14 block_count,LoadIC,143,2 block_count,LoadIC,144,2 @@ -22246,7 +22241,7 @@ block_count,LoadIC,208,0 block_count,LoadIC,209,0 block_count,LoadIC,210,11 -block_count,LoadIC,211,240 +block_count,LoadIC,211,239 block_count,LoadIC,212,241 block_count,LoadIC,213,241 block_count,LoadIC,214,0 @@ -22304,19 +22299,19 @@ block_count,LoadIC,266,0 block_count,LoadIC,267,241 block_count,LoadIC,268,85 -block_count,LoadIC,269,1255 -block_count,LoadIC,270,3477 -block_count,LoadIC,271,3477 -block_count,LoadIC,272,899 -block_count,LoadIC,273,2577 -block_count,LoadIC,274,3477 -block_count,LoadIC,275,3305 -block_count,LoadIC,276,171 -block_count,LoadIC,277,171 -block_count,LoadIC,278,171 +block_count,LoadIC,269,1254 +block_count,LoadIC,270,3468 +block_count,LoadIC,271,3468 +block_count,LoadIC,272,895 +block_count,LoadIC,273,2573 +block_count,LoadIC,274,3468 +block_count,LoadIC,275,3296 +block_count,LoadIC,276,172 +block_count,LoadIC,277,172 +block_count,LoadIC,278,172 block_count,LoadIC,279,0 -block_count,LoadIC,280,171 -block_count,LoadIC,281,171 +block_count,LoadIC,280,172 +block_count,LoadIC,281,172 block_count,LoadIC,282,0 block_count,LoadIC,283,0 block_count,LoadIC,284,0 @@ -22378,24 +22373,24 @@ block_count,LoadIC_Megamorphic,4,10000 block_count,LoadIC_Megamorphic,5,0 block_count,LoadIC_Megamorphic,6,10000 -block_count,LoadIC_Megamorphic,7,8303 -block_count,LoadIC_Megamorphic,8,8232 -block_count,LoadIC_Megamorphic,9,71 -block_count,LoadIC_Megamorphic,10,1696 -block_count,LoadIC_Megamorphic,11,1767 -block_count,LoadIC_Megamorphic,12,1759 -block_count,LoadIC_Megamorphic,13,1758 +block_count,LoadIC_Megamorphic,7,8067 +block_count,LoadIC_Megamorphic,8,8038 +block_count,LoadIC_Megamorphic,9,29 +block_count,LoadIC_Megamorphic,10,1932 +block_count,LoadIC_Megamorphic,11,1961 +block_count,LoadIC_Megamorphic,12,1953 +block_count,LoadIC_Megamorphic,13,1951 block_count,LoadIC_Megamorphic,14,1 block_count,LoadIC_Megamorphic,15,7 block_count,LoadIC_Megamorphic,16,9990 -block_count,LoadIC_Megamorphic,17,3705 -block_count,LoadIC_Megamorphic,18,3705 -block_count,LoadIC_Megamorphic,19,3623 -block_count,LoadIC_Megamorphic,20,3623 +block_count,LoadIC_Megamorphic,17,3702 +block_count,LoadIC_Megamorphic,18,3702 +block_count,LoadIC_Megamorphic,19,3622 +block_count,LoadIC_Megamorphic,20,3622 block_count,LoadIC_Megamorphic,21,0 -block_count,LoadIC_Megamorphic,22,3623 +block_count,LoadIC_Megamorphic,22,3622 block_count,LoadIC_Megamorphic,23,0 -block_count,LoadIC_Megamorphic,24,3623 +block_count,LoadIC_Megamorphic,24,3622 block_count,LoadIC_Megamorphic,25,7 block_count,LoadIC_Megamorphic,26,4 block_count,LoadIC_Megamorphic,27,4 @@ -22468,23 +22463,23 @@ block_count,LoadIC_Megamorphic,94,0 block_count,LoadIC_Megamorphic,95,3 block_count,LoadIC_Megamorphic,96,0 -block_count,LoadIC_Megamorphic,97,3616 -block_count,LoadIC_Megamorphic,98,3623 -block_count,LoadIC_Megamorphic,99,3621 -block_count,LoadIC_Megamorphic,100,2853 -block_count,LoadIC_Megamorphic,101,2853 +block_count,LoadIC_Megamorphic,97,3615 +block_count,LoadIC_Megamorphic,98,3622 +block_count,LoadIC_Megamorphic,99,3620 +block_count,LoadIC_Megamorphic,100,2852 +block_count,LoadIC_Megamorphic,101,2852 block_count,LoadIC_Megamorphic,102,0 block_count,LoadIC_Megamorphic,103,768 -block_count,LoadIC_Megamorphic,104,3621 +block_count,LoadIC_Megamorphic,104,3620 block_count,LoadIC_Megamorphic,105,1 -block_count,LoadIC_Megamorphic,106,81 +block_count,LoadIC_Megamorphic,106,80 block_count,LoadIC_Megamorphic,107,0 block_count,LoadIC_Megamorphic,108,0 block_count,LoadIC_Megamorphic,109,0 -block_count,LoadIC_Megamorphic,110,6285 -block_count,LoadIC_Megamorphic,111,9907 -block_count,LoadIC_Megamorphic,112,4346 -block_count,LoadIC_Megamorphic,113,2286 +block_count,LoadIC_Megamorphic,110,6287 +block_count,LoadIC_Megamorphic,111,9908 +block_count,LoadIC_Megamorphic,112,4344 +block_count,LoadIC_Megamorphic,113,2285 block_count,LoadIC_Megamorphic,114,1517 block_count,LoadIC_Megamorphic,115,1515 block_count,LoadIC_Megamorphic,116,724 @@ -22615,12 +22610,12 @@ block_count,LoadIC_Megamorphic,241,1 block_count,LoadIC_Megamorphic,242,768 block_count,LoadIC_Megamorphic,243,2059 -block_count,LoadIC_Megamorphic,244,5561 -block_count,LoadIC_Megamorphic,245,5561 +block_count,LoadIC_Megamorphic,244,5563 +block_count,LoadIC_Megamorphic,245,5563 block_count,LoadIC_Megamorphic,246,290 -block_count,LoadIC_Megamorphic,247,5270 -block_count,LoadIC_Megamorphic,248,5561 -block_count,LoadIC_Megamorphic,249,5540 +block_count,LoadIC_Megamorphic,247,5273 +block_count,LoadIC_Megamorphic,248,5563 +block_count,LoadIC_Megamorphic,249,5542 block_count,LoadIC_Megamorphic,250,21 block_count,LoadIC_Megamorphic,251,21 block_count,LoadIC_Megamorphic,252,21 @@ -23005,15 +23000,15 @@ block_count,LoadIC_Noninlined,321,0 block_count,LoadIC_Noninlined,322,0 block_count,LoadIC_Noninlined,323,1 -block_count,LoadICTrampoline,0,348 -block_count,LoadICTrampoline,1,348 +block_count,LoadICTrampoline,0,340 +block_count,LoadICTrampoline,1,340 block_count,LoadICTrampoline,2,0 -block_count,LoadICTrampoline,3,348 -block_count,LoadICBaseline,0,5068 -block_count,LoadICTrampoline_Megamorphic,0,6337 -block_count,LoadICTrampoline_Megamorphic,1,6337 +block_count,LoadICTrampoline,3,340 +block_count,LoadICBaseline,0,5059 +block_count,LoadICTrampoline_Megamorphic,0,6280 +block_count,LoadICTrampoline_Megamorphic,1,6280 block_count,LoadICTrampoline_Megamorphic,2,0 -block_count,LoadICTrampoline_Megamorphic,3,6337 +block_count,LoadICTrampoline_Megamorphic,3,6280 block_count,LoadSuperIC,0,5 block_count,LoadSuperIC,1,5 block_count,LoadSuperIC,2,5 @@ -23622,15 +23617,15 @@ block_count,LoadSuperIC,605,0 block_count,LoadSuperIC,606,0 block_count,LoadSuperICBaseline,0,5 -block_count,KeyedLoadIC,0,950 -block_count,KeyedLoadIC,1,950 +block_count,KeyedLoadIC,0,945 +block_count,KeyedLoadIC,1,945 block_count,KeyedLoadIC,2,0 -block_count,KeyedLoadIC,3,950 -block_count,KeyedLoadIC,4,950 -block_count,KeyedLoadIC,5,947 -block_count,KeyedLoadIC,6,95 +block_count,KeyedLoadIC,3,945 +block_count,KeyedLoadIC,4,945 +block_count,KeyedLoadIC,5,942 +block_count,KeyedLoadIC,6,93 block_count,KeyedLoadIC,7,0 -block_count,KeyedLoadIC,8,95 +block_count,KeyedLoadIC,8,93 block_count,KeyedLoadIC,9,51 block_count,KeyedLoadIC,10,2 block_count,KeyedLoadIC,11,1 @@ -23670,14 +23665,14 @@ block_count,KeyedLoadIC,45,1 block_count,KeyedLoadIC,46,0 block_count,KeyedLoadIC,47,49 -block_count,KeyedLoadIC,48,44 -block_count,KeyedLoadIC,49,73 +block_count,KeyedLoadIC,48,42 +block_count,KeyedLoadIC,49,70 block_count,KeyedLoadIC,50,28 block_count,KeyedLoadIC,51,28 block_count,KeyedLoadIC,52,0 -block_count,KeyedLoadIC,53,44 -block_count,KeyedLoadIC,54,851 -block_count,KeyedLoadIC,55,895 +block_count,KeyedLoadIC,53,42 +block_count,KeyedLoadIC,54,848 +block_count,KeyedLoadIC,55,890 block_count,KeyedLoadIC,56,2 block_count,KeyedLoadIC,57,2 block_count,KeyedLoadIC,58,0 @@ -23771,8 +23766,8 @@ block_count,KeyedLoadIC,146,0 block_count,KeyedLoadIC,147,0 block_count,KeyedLoadIC,148,0 -block_count,KeyedLoadIC,149,893 -block_count,KeyedLoadIC,150,893 +block_count,KeyedLoadIC,149,888 +block_count,KeyedLoadIC,150,888 block_count,KeyedLoadIC,151,7 block_count,KeyedLoadIC,152,0 block_count,KeyedLoadIC,153,0 @@ -24010,9 +24005,9 @@ block_count,KeyedLoadIC,385,7 block_count,KeyedLoadIC,386,7 block_count,KeyedLoadIC,387,3 -block_count,KeyedLoadIC,388,6 -block_count,KeyedLoadIC,389,2 -block_count,KeyedLoadIC,390,2 +block_count,KeyedLoadIC,388,7 +block_count,KeyedLoadIC,389,3 +block_count,KeyedLoadIC,390,3 block_count,KeyedLoadIC,391,0 block_count,KeyedLoadIC,392,0 block_count,KeyedLoadIC,393,0 @@ -24047,7 +24042,7 @@ block_count,KeyedLoadIC,422,0 block_count,KeyedLoadIC,423,0 block_count,KeyedLoadIC,424,0 -block_count,KeyedLoadIC,425,886 +block_count,KeyedLoadIC,425,881 block_count,KeyedLoadIC,426,0 block_count,KeyedLoadIC,427,0 block_count,KeyedLoadIC,428,0 @@ -24058,43 +24053,43 @@ block_count,KeyedLoadIC,433,0 block_count,KeyedLoadIC,434,0 block_count,KeyedLoadIC,435,0 -block_count,KeyedLoadIC,436,885 -block_count,KeyedLoadIC,437,885 -block_count,KeyedLoadIC,438,886 -block_count,KeyedLoadIC,439,544 +block_count,KeyedLoadIC,436,880 +block_count,KeyedLoadIC,437,880 +block_count,KeyedLoadIC,438,881 +block_count,KeyedLoadIC,439,538 block_count,KeyedLoadIC,440,10 -block_count,KeyedLoadIC,441,534 -block_count,KeyedLoadIC,442,544 +block_count,KeyedLoadIC,441,528 +block_count,KeyedLoadIC,442,538 block_count,KeyedLoadIC,443,1 -block_count,KeyedLoadIC,444,542 +block_count,KeyedLoadIC,444,537 block_count,KeyedLoadIC,445,0 block_count,KeyedLoadIC,446,41 -block_count,KeyedLoadIC,447,284 +block_count,KeyedLoadIC,447,280 block_count,KeyedLoadIC,448,0 block_count,KeyedLoadIC,449,0 block_count,KeyedLoadIC,450,0 block_count,KeyedLoadIC,451,0 -block_count,KeyedLoadIC,452,325 +block_count,KeyedLoadIC,452,322 block_count,KeyedLoadIC,453,27 -block_count,KeyedLoadIC,454,87 +block_count,KeyedLoadIC,454,86 block_count,KeyedLoadIC,455,0 block_count,KeyedLoadIC,456,0 block_count,KeyedLoadIC,457,0 -block_count,KeyedLoadIC,458,114 -block_count,KeyedLoadIC,459,109 +block_count,KeyedLoadIC,458,113 +block_count,KeyedLoadIC,459,108 block_count,KeyedLoadIC,460,5 -block_count,KeyedLoadIC,461,40 +block_count,KeyedLoadIC,461,39 block_count,KeyedLoadIC,462,0 -block_count,KeyedLoadIC,463,40 -block_count,KeyedLoadIC,464,40 -block_count,KeyedLoadIC,465,62 +block_count,KeyedLoadIC,463,39 +block_count,KeyedLoadIC,464,39 +block_count,KeyedLoadIC,465,61 block_count,KeyedLoadIC,466,61 block_count,KeyedLoadIC,467,0 block_count,KeyedLoadIC,468,61 block_count,KeyedLoadIC,469,61 block_count,KeyedLoadIC,470,0 -block_count,KeyedLoadIC,471,341 -block_count,KeyedLoadIC,472,341 +block_count,KeyedLoadIC,471,342 +block_count,KeyedLoadIC,472,342 block_count,KeyedLoadIC,473,0 block_count,KeyedLoadIC,474,0 block_count,KeyedLoadIC,475,0 @@ -24117,18 +24112,18 @@ block_count,KeyedLoadIC,492,0 block_count,KeyedLoadIC,493,0 block_count,KeyedLoadIC,494,0 -block_count,KeyedLoadIC,495,341 -block_count,KeyedLoadIC,496,341 +block_count,KeyedLoadIC,495,342 +block_count,KeyedLoadIC,496,342 block_count,KeyedLoadIC,497,0 -block_count,KeyedLoadIC,498,341 +block_count,KeyedLoadIC,498,342 block_count,KeyedLoadIC,499,0 -block_count,KeyedLoadIC,500,50 +block_count,KeyedLoadIC,500,49 block_count,KeyedLoadIC,501,0 block_count,KeyedLoadIC,502,2 block_count,KeyedLoadIC,503,14 block_count,KeyedLoadIC,504,0 block_count,KeyedLoadIC,505,1 -block_count,KeyedLoadIC,506,192 +block_count,KeyedLoadIC,506,194 block_count,KeyedLoadIC,507,79 block_count,KeyedLoadIC,508,0 block_count,KeyedLoadIC,509,0 @@ -24188,8 +24183,8 @@ block_count,KeyedLoadIC,563,0 block_count,KeyedLoadIC,564,0 block_count,KeyedLoadIC,565,0 -block_count,KeyedLoadIC,566,192 -block_count,KeyedLoadIC,567,189 +block_count,KeyedLoadIC,566,194 +block_count,KeyedLoadIC,567,191 block_count,KeyedLoadIC,568,3 block_count,KeyedLoadIC,569,0 block_count,KeyedLoadIC,570,3 @@ -24960,53 +24955,53 @@ block_count,EnumeratedKeyedLoadIC,679,2 block_count,EnumeratedKeyedLoadIC,680,0 block_count,EnumeratedKeyedLoadIC,681,0 -block_count,KeyedLoadIC_Megamorphic,0,2428 -block_count,KeyedLoadIC_Megamorphic,1,2428 -block_count,KeyedLoadIC_Megamorphic,2,2428 -block_count,KeyedLoadIC_Megamorphic,3,2103 -block_count,KeyedLoadIC_Megamorphic,4,2100 +block_count,KeyedLoadIC_Megamorphic,0,2427 +block_count,KeyedLoadIC_Megamorphic,1,2427 +block_count,KeyedLoadIC_Megamorphic,2,2427 +block_count,KeyedLoadIC_Megamorphic,3,2102 +block_count,KeyedLoadIC_Megamorphic,4,2099 block_count,KeyedLoadIC_Megamorphic,5,3 block_count,KeyedLoadIC_Megamorphic,6,0 block_count,KeyedLoadIC_Megamorphic,7,3 -block_count,KeyedLoadIC_Megamorphic,8,2100 -block_count,KeyedLoadIC_Megamorphic,9,2098 +block_count,KeyedLoadIC_Megamorphic,8,2099 +block_count,KeyedLoadIC_Megamorphic,9,2097 block_count,KeyedLoadIC_Megamorphic,10,48 -block_count,KeyedLoadIC_Megamorphic,11,43 +block_count,KeyedLoadIC_Megamorphic,11,42 block_count,KeyedLoadIC_Megamorphic,12,5 -block_count,KeyedLoadIC_Megamorphic,13,2050 -block_count,KeyedLoadIC_Megamorphic,14,2050 -block_count,KeyedLoadIC_Megamorphic,15,1952 -block_count,KeyedLoadIC_Megamorphic,16,1952 -block_count,KeyedLoadIC_Megamorphic,17,1851 +block_count,KeyedLoadIC_Megamorphic,13,2049 +block_count,KeyedLoadIC_Megamorphic,14,2049 +block_count,KeyedLoadIC_Megamorphic,15,1951 +block_count,KeyedLoadIC_Megamorphic,16,1951 +block_count,KeyedLoadIC_Megamorphic,17,1850 block_count,KeyedLoadIC_Megamorphic,18,0 block_count,KeyedLoadIC_Megamorphic,19,0 block_count,KeyedLoadIC_Megamorphic,20,0 -block_count,KeyedLoadIC_Megamorphic,21,1851 +block_count,KeyedLoadIC_Megamorphic,21,1850 block_count,KeyedLoadIC_Megamorphic,22,1002 block_count,KeyedLoadIC_Megamorphic,23,848 -block_count,KeyedLoadIC_Megamorphic,24,101 +block_count,KeyedLoadIC_Megamorphic,24,100 block_count,KeyedLoadIC_Megamorphic,25,0 block_count,KeyedLoadIC_Megamorphic,26,97 -block_count,KeyedLoadIC_Megamorphic,27,43 -block_count,KeyedLoadIC_Megamorphic,28,43 -block_count,KeyedLoadIC_Megamorphic,29,43 +block_count,KeyedLoadIC_Megamorphic,27,42 +block_count,KeyedLoadIC_Megamorphic,28,42 +block_count,KeyedLoadIC_Megamorphic,29,42 block_count,KeyedLoadIC_Megamorphic,30,0 block_count,KeyedLoadIC_Megamorphic,31,0 block_count,KeyedLoadIC_Megamorphic,32,0 -block_count,KeyedLoadIC_Megamorphic,33,43 -block_count,KeyedLoadIC_Megamorphic,34,43 +block_count,KeyedLoadIC_Megamorphic,33,42 +block_count,KeyedLoadIC_Megamorphic,34,42 block_count,KeyedLoadIC_Megamorphic,35,0 block_count,KeyedLoadIC_Megamorphic,36,0 block_count,KeyedLoadIC_Megamorphic,37,0 -block_count,KeyedLoadIC_Megamorphic,38,43 -block_count,KeyedLoadIC_Megamorphic,39,43 -block_count,KeyedLoadIC_Megamorphic,40,43 -block_count,KeyedLoadIC_Megamorphic,41,43 -block_count,KeyedLoadIC_Megamorphic,42,43 +block_count,KeyedLoadIC_Megamorphic,38,42 +block_count,KeyedLoadIC_Megamorphic,39,42 +block_count,KeyedLoadIC_Megamorphic,40,42 +block_count,KeyedLoadIC_Megamorphic,41,42 +block_count,KeyedLoadIC_Megamorphic,42,42 block_count,KeyedLoadIC_Megamorphic,43,0 block_count,KeyedLoadIC_Megamorphic,44,0 block_count,KeyedLoadIC_Megamorphic,45,0 -block_count,KeyedLoadIC_Megamorphic,46,43 +block_count,KeyedLoadIC_Megamorphic,46,42 block_count,KeyedLoadIC_Megamorphic,47,0 block_count,KeyedLoadIC_Megamorphic,48,42 block_count,KeyedLoadIC_Megamorphic,49,0 @@ -25021,8 +25016,8 @@ block_count,KeyedLoadIC_Megamorphic,58,0 block_count,KeyedLoadIC_Megamorphic,59,0 block_count,KeyedLoadIC_Megamorphic,60,0 -block_count,KeyedLoadIC_Megamorphic,61,891 -block_count,KeyedLoadIC_Megamorphic,62,891 +block_count,KeyedLoadIC_Megamorphic,61,890 +block_count,KeyedLoadIC_Megamorphic,62,890 block_count,KeyedLoadIC_Megamorphic,63,800 block_count,KeyedLoadIC_Megamorphic,64,678 block_count,KeyedLoadIC_Megamorphic,65,34 @@ -25053,7 +25048,7 @@ block_count,KeyedLoadIC_Megamorphic,90,643 block_count,KeyedLoadIC_Megamorphic,91,0 block_count,KeyedLoadIC_Megamorphic,92,643 -block_count,KeyedLoadIC_Megamorphic,93,489 +block_count,KeyedLoadIC_Megamorphic,93,488 block_count,KeyedLoadIC_Megamorphic,94,154 block_count,KeyedLoadIC_Megamorphic,95,230 block_count,KeyedLoadIC_Megamorphic,96,207 @@ -25087,7 +25082,7 @@ block_count,KeyedLoadIC_Megamorphic,124,0 block_count,KeyedLoadIC_Megamorphic,125,90 block_count,KeyedLoadIC_Megamorphic,126,90 -block_count,KeyedLoadIC_Megamorphic,127,153 +block_count,KeyedLoadIC_Megamorphic,127,152 block_count,KeyedLoadIC_Megamorphic,128,113 block_count,KeyedLoadIC_Megamorphic,129,62 block_count,KeyedLoadIC_Megamorphic,130,51 @@ -25098,7 +25093,7 @@ block_count,KeyedLoadIC_Megamorphic,135,51 block_count,KeyedLoadIC_Megamorphic,136,0 block_count,KeyedLoadIC_Megamorphic,137,51 -block_count,KeyedLoadIC_Megamorphic,138,118 +block_count,KeyedLoadIC_Megamorphic,138,117 block_count,KeyedLoadIC_Megamorphic,139,0 block_count,KeyedLoadIC_Megamorphic,140,0 block_count,KeyedLoadIC_Megamorphic,141,0 @@ -25138,39 +25133,39 @@ block_count,KeyedLoadIC_Megamorphic,175,0 block_count,KeyedLoadIC_Megamorphic,176,0 block_count,KeyedLoadIC_Megamorphic,177,0 -block_count,KeyedLoadIC_Megamorphic,178,118 -block_count,KeyedLoadIC_Megamorphic,179,773 +block_count,KeyedLoadIC_Megamorphic,178,117 +block_count,KeyedLoadIC_Megamorphic,179,772 block_count,KeyedLoadIC_Megamorphic,180,0 block_count,KeyedLoadIC_Megamorphic,181,0 block_count,KeyedLoadIC_Megamorphic,182,0 block_count,KeyedLoadIC_Megamorphic,183,0 block_count,KeyedLoadIC_Megamorphic,184,0 -block_count,KeyedLoadIC_Megamorphic,185,773 -block_count,KeyedLoadIC_Megamorphic,186,773 -block_count,KeyedLoadIC_Megamorphic,187,1412 -block_count,KeyedLoadIC_Megamorphic,188,1412 -block_count,KeyedLoadIC_Megamorphic,189,1352 -block_count,KeyedLoadIC_Megamorphic,190,1352 -block_count,KeyedLoadIC_Megamorphic,191,1352 -block_count,KeyedLoadIC_Megamorphic,192,1352 -block_count,KeyedLoadIC_Megamorphic,193,565 -block_count,KeyedLoadIC_Megamorphic,194,565 +block_count,KeyedLoadIC_Megamorphic,185,772 +block_count,KeyedLoadIC_Megamorphic,186,772 +block_count,KeyedLoadIC_Megamorphic,187,1411 +block_count,KeyedLoadIC_Megamorphic,188,1411 +block_count,KeyedLoadIC_Megamorphic,189,1351 +block_count,KeyedLoadIC_Megamorphic,190,1351 +block_count,KeyedLoadIC_Megamorphic,191,1351 +block_count,KeyedLoadIC_Megamorphic,192,1351 +block_count,KeyedLoadIC_Megamorphic,193,564 +block_count,KeyedLoadIC_Megamorphic,194,564 block_count,KeyedLoadIC_Megamorphic,195,0 -block_count,KeyedLoadIC_Megamorphic,196,565 -block_count,KeyedLoadIC_Megamorphic,197,3367 -block_count,KeyedLoadIC_Megamorphic,198,3367 +block_count,KeyedLoadIC_Megamorphic,196,564 +block_count,KeyedLoadIC_Megamorphic,197,3365 +block_count,KeyedLoadIC_Megamorphic,198,3365 block_count,KeyedLoadIC_Megamorphic,199,0 -block_count,KeyedLoadIC_Megamorphic,200,3367 -block_count,KeyedLoadIC_Megamorphic,201,1920 +block_count,KeyedLoadIC_Megamorphic,200,3365 +block_count,KeyedLoadIC_Megamorphic,201,1919 block_count,KeyedLoadIC_Megamorphic,202,1446 -block_count,KeyedLoadIC_Megamorphic,203,3367 -block_count,KeyedLoadIC_Megamorphic,204,2802 -block_count,KeyedLoadIC_Megamorphic,205,565 -block_count,KeyedLoadIC_Megamorphic,206,565 -block_count,KeyedLoadIC_Megamorphic,207,565 -block_count,KeyedLoadIC_Megamorphic,208,565 +block_count,KeyedLoadIC_Megamorphic,203,3365 +block_count,KeyedLoadIC_Megamorphic,204,2800 +block_count,KeyedLoadIC_Megamorphic,205,564 +block_count,KeyedLoadIC_Megamorphic,206,564 +block_count,KeyedLoadIC_Megamorphic,207,564 +block_count,KeyedLoadIC_Megamorphic,208,564 block_count,KeyedLoadIC_Megamorphic,209,0 -block_count,KeyedLoadIC_Megamorphic,210,565 +block_count,KeyedLoadIC_Megamorphic,210,564 block_count,KeyedLoadIC_Megamorphic,211,555 block_count,KeyedLoadIC_Megamorphic,212,0 block_count,KeyedLoadIC_Megamorphic,213,555 @@ -25178,15 +25173,15 @@ block_count,KeyedLoadIC_Megamorphic,215,555 block_count,KeyedLoadIC_Megamorphic,216,9 block_count,KeyedLoadIC_Megamorphic,217,0 -block_count,KeyedLoadIC_Megamorphic,218,787 +block_count,KeyedLoadIC_Megamorphic,218,786 block_count,KeyedLoadIC_Megamorphic,219,0 -block_count,KeyedLoadIC_Megamorphic,220,787 +block_count,KeyedLoadIC_Megamorphic,220,786 block_count,KeyedLoadIC_Megamorphic,221,30 block_count,KeyedLoadIC_Megamorphic,222,756 -block_count,KeyedLoadIC_Megamorphic,223,3071 -block_count,KeyedLoadIC_Megamorphic,224,3000 -block_count,KeyedLoadIC_Megamorphic,225,2913 -block_count,KeyedLoadIC_Megamorphic,226,2314 +block_count,KeyedLoadIC_Megamorphic,223,3069 +block_count,KeyedLoadIC_Megamorphic,224,2998 +block_count,KeyedLoadIC_Megamorphic,225,2912 +block_count,KeyedLoadIC_Megamorphic,226,2312 block_count,KeyedLoadIC_Megamorphic,227,599 block_count,KeyedLoadIC_Megamorphic,228,86 block_count,KeyedLoadIC_Megamorphic,229,70 @@ -25195,12 +25190,12 @@ block_count,KeyedLoadIC_Megamorphic,232,439 block_count,KeyedLoadIC_Megamorphic,233,439 block_count,KeyedLoadIC_Megamorphic,234,0 -block_count,KeyedLoadIC_Megamorphic,235,713 +block_count,KeyedLoadIC_Megamorphic,235,712 block_count,KeyedLoadIC_Megamorphic,236,0 -block_count,KeyedLoadIC_Megamorphic,237,713 -block_count,KeyedLoadIC_Megamorphic,238,713 +block_count,KeyedLoadIC_Megamorphic,237,712 +block_count,KeyedLoadIC_Megamorphic,238,712 block_count,KeyedLoadIC_Megamorphic,239,0 -block_count,KeyedLoadIC_Megamorphic,240,713 +block_count,KeyedLoadIC_Megamorphic,240,712 block_count,KeyedLoadIC_Megamorphic,241,0 block_count,KeyedLoadIC_Megamorphic,242,0 block_count,KeyedLoadIC_Megamorphic,243,0 @@ -25208,7 +25203,7 @@ block_count,KeyedLoadIC_Megamorphic,245,0 block_count,KeyedLoadIC_Megamorphic,246,0 block_count,KeyedLoadIC_Megamorphic,247,0 -block_count,KeyedLoadIC_Megamorphic,248,713 +block_count,KeyedLoadIC_Megamorphic,248,712 block_count,KeyedLoadIC_Megamorphic,249,0 block_count,KeyedLoadIC_Megamorphic,250,0 block_count,KeyedLoadIC_Megamorphic,251,0 @@ -25251,8 +25246,8 @@ block_count,KeyedLoadIC_Megamorphic,288,0 block_count,KeyedLoadIC_Megamorphic,289,0 block_count,KeyedLoadIC_Megamorphic,290,0 -block_count,KeyedLoadIC_Megamorphic,291,639 -block_count,KeyedLoadIC_Megamorphic,292,713 +block_count,KeyedLoadIC_Megamorphic,291,638 +block_count,KeyedLoadIC_Megamorphic,292,712 block_count,KeyedLoadIC_Megamorphic,293,0 block_count,KeyedLoadIC_Megamorphic,294,0 block_count,KeyedLoadIC_Megamorphic,295,0 @@ -25295,7 +25290,7 @@ block_count,KeyedLoadIC_Megamorphic,332,0 block_count,KeyedLoadIC_Megamorphic,333,0 block_count,KeyedLoadIC_Megamorphic,334,0 -block_count,KeyedLoadIC_Megamorphic,335,713 +block_count,KeyedLoadIC_Megamorphic,335,712 block_count,KeyedLoadIC_Megamorphic,336,0 block_count,KeyedLoadIC_Megamorphic,337,59 block_count,KeyedLoadIC_Megamorphic,338,0 @@ -25342,14 +25337,14 @@ block_count,KeyedLoadIC_Megamorphic,379,387 block_count,KeyedLoadIC_Megamorphic,380,9 block_count,KeyedLoadIC_Megamorphic,381,377 -block_count,KeyedLoadIC_Megamorphic,382,1016 +block_count,KeyedLoadIC_Megamorphic,382,1015 block_count,KeyedLoadIC_Megamorphic,383,870 block_count,KeyedLoadIC_Megamorphic,384,731 block_count,KeyedLoadIC_Megamorphic,385,638 block_count,KeyedLoadIC_Megamorphic,386,93 block_count,KeyedLoadIC_Megamorphic,387,139 block_count,KeyedLoadIC_Megamorphic,388,145 -block_count,KeyedLoadIC_Megamorphic,389,103 +block_count,KeyedLoadIC_Megamorphic,389,102 block_count,KeyedLoadIC_Megamorphic,390,69 block_count,KeyedLoadIC_Megamorphic,391,33 block_count,KeyedLoadIC_Megamorphic,392,19 @@ -25360,7 +25355,7 @@ block_count,KeyedLoadIC_Megamorphic,397,74 block_count,KeyedLoadIC_Megamorphic,398,0 block_count,KeyedLoadIC_Megamorphic,399,74 -block_count,KeyedLoadIC_Megamorphic,400,273 +block_count,KeyedLoadIC_Megamorphic,400,272 block_count,KeyedLoadIC_Megamorphic,401,47 block_count,KeyedLoadIC_Megamorphic,402,225 block_count,KeyedLoadIC_Megamorphic,403,48 @@ -25374,13 +25369,13 @@ block_count,KeyedLoadIC_Megamorphic,411,116 block_count,KeyedLoadIC_Megamorphic,412,0 block_count,KeyedLoadIC_Megamorphic,413,116 -block_count,KeyedLoadIC_Megamorphic,414,90 -block_count,KeyedLoadIC_Megamorphic,415,90 +block_count,KeyedLoadIC_Megamorphic,414,86 +block_count,KeyedLoadIC_Megamorphic,415,86 block_count,KeyedLoadIC_Megamorphic,416,0 -block_count,KeyedLoadIC_Megamorphic,417,26 -block_count,KeyedLoadIC_Megamorphic,418,26 -block_count,KeyedLoadIC_Megamorphic,419,10 -block_count,KeyedLoadIC_Megamorphic,420,10 +block_count,KeyedLoadIC_Megamorphic,417,30 +block_count,KeyedLoadIC_Megamorphic,418,30 +block_count,KeyedLoadIC_Megamorphic,419,14 +block_count,KeyedLoadIC_Megamorphic,420,14 block_count,KeyedLoadIC_Megamorphic,421,0 block_count,KeyedLoadIC_Megamorphic,422,16 block_count,KeyedLoadIC_Megamorphic,423,100 @@ -25685,17 +25680,17 @@ block_count,KeyedLoadIC_Megamorphic,722,0 block_count,KeyedLoadIC_Megamorphic,723,643 block_count,KeyedLoadIC_Megamorphic,724,643 -block_count,KeyedLoadIC_Megamorphic,725,1066 +block_count,KeyedLoadIC_Megamorphic,725,1065 block_count,KeyedLoadIC_Megamorphic,726,991 block_count,KeyedLoadIC_Megamorphic,727,422 -block_count,KeyedLoadIC_Megamorphic,728,569 +block_count,KeyedLoadIC_Megamorphic,728,568 block_count,KeyedLoadIC_Megamorphic,729,74 block_count,KeyedLoadIC_Megamorphic,730,0 block_count,KeyedLoadIC_Megamorphic,731,0 block_count,KeyedLoadIC_Megamorphic,732,0 -block_count,KeyedLoadIC_Megamorphic,733,569 +block_count,KeyedLoadIC_Megamorphic,733,568 block_count,KeyedLoadIC_Megamorphic,734,0 -block_count,KeyedLoadIC_Megamorphic,735,569 +block_count,KeyedLoadIC_Megamorphic,735,568 block_count,KeyedLoadIC_Megamorphic,736,919 block_count,KeyedLoadIC_Megamorphic,737,2 block_count,KeyedLoadIC_Megamorphic,738,0 @@ -25907,7 +25902,7 @@ block_count,KeyedLoadIC_Megamorphic,944,0 block_count,KeyedLoadIC_Megamorphic,945,324 block_count,KeyedLoadIC_Megamorphic,946,328 -block_count,KeyedLoadIC_Megamorphic,947,426 +block_count,KeyedLoadIC_Megamorphic,947,425 block_count,KeyedLoadIC_Megamorphic,948,416 block_count,KeyedLoadIC_Megamorphic,949,404 block_count,KeyedLoadIC_Megamorphic,950,76 @@ -25917,7 +25912,7 @@ block_count,KeyedLoadIC_Megamorphic,954,394 block_count,KeyedLoadIC_Megamorphic,955,0 block_count,KeyedLoadIC_Megamorphic,956,0 -block_count,KeyedLoadIC_Megamorphic,957,322 +block_count,KeyedLoadIC_Megamorphic,957,321 block_count,KeyedLoadIC_Megamorphic,958,0 block_count,KeyedLoadIC_Megamorphic,959,0 block_count,KeyedLoadIC_Megamorphic,960,0 @@ -26127,28 +26122,28 @@ block_count,KeyedLoadICTrampoline,1,1 block_count,KeyedLoadICTrampoline,2,0 block_count,KeyedLoadICTrampoline,3,1 -block_count,KeyedLoadICBaseline,0,884 +block_count,KeyedLoadICBaseline,0,879 block_count,EnumeratedKeyedLoadICBaseline,0,5 -block_count,KeyedLoadICTrampoline_Megamorphic,0,1198 -block_count,KeyedLoadICTrampoline_Megamorphic,1,1198 +block_count,KeyedLoadICTrampoline_Megamorphic,0,1221 +block_count,KeyedLoadICTrampoline_Megamorphic,1,1221 block_count,KeyedLoadICTrampoline_Megamorphic,2,0 -block_count,KeyedLoadICTrampoline_Megamorphic,3,1198 -block_count,StoreGlobalIC,0,321 -block_count,StoreGlobalIC,1,321 -block_count,StoreGlobalIC,2,321 -block_count,StoreGlobalIC,3,321 -block_count,StoreGlobalIC,4,321 -block_count,StoreGlobalIC,5,321 +block_count,KeyedLoadICTrampoline_Megamorphic,3,1221 +block_count,StoreGlobalIC,0,307 +block_count,StoreGlobalIC,1,307 +block_count,StoreGlobalIC,2,307 +block_count,StoreGlobalIC,3,307 +block_count,StoreGlobalIC,4,307 +block_count,StoreGlobalIC,5,307 block_count,StoreGlobalIC,6,7 block_count,StoreGlobalIC,7,0 block_count,StoreGlobalIC,8,0 block_count,StoreGlobalIC,9,0 block_count,StoreGlobalIC,10,0 block_count,StoreGlobalIC,11,0 -block_count,StoreGlobalIC,12,7 +block_count,StoreGlobalIC,12,6 block_count,StoreGlobalIC,13,0 -block_count,StoreGlobalIC,14,7 -block_count,StoreGlobalIC,15,313 +block_count,StoreGlobalIC,14,6 +block_count,StoreGlobalIC,15,300 block_count,StoreGlobalIC,16,0 block_count,StoreGlobalIC,17,0 block_count,StoreGlobalIC,18,0 @@ -26655,10 +26650,10 @@ block_count,StoreGlobalIC,519,0 block_count,StoreGlobalIC,520,0 block_count,StoreGlobalIC,521,0 -block_count,StoreGlobalICTrampoline,0,225 -block_count,StoreGlobalICTrampoline,1,225 +block_count,StoreGlobalICTrampoline,0,224 +block_count,StoreGlobalICTrampoline,1,224 block_count,StoreGlobalICTrampoline,2,0 -block_count,StoreGlobalICTrampoline,3,225 +block_count,StoreGlobalICTrampoline,3,224 block_count,StoreGlobalICBaseline,0,6 block_count,StoreIC,0,683 block_count,StoreIC,1,683 @@ -26666,31 +26661,31 @@ block_count,StoreIC,3,683 block_count,StoreIC,4,683 block_count,StoreIC,5,676 -block_count,StoreIC,6,199 +block_count,StoreIC,6,200 block_count,StoreIC,7,0 -block_count,StoreIC,8,198 +block_count,StoreIC,8,200 block_count,StoreIC,9,41 block_count,StoreIC,10,0 -block_count,StoreIC,11,40 -block_count,StoreIC,12,40 +block_count,StoreIC,11,41 +block_count,StoreIC,12,41 block_count,StoreIC,13,0 -block_count,StoreIC,14,40 -block_count,StoreIC,15,36 -block_count,StoreIC,16,36 +block_count,StoreIC,14,41 +block_count,StoreIC,15,38 +block_count,StoreIC,16,38 block_count,StoreIC,17,0 -block_count,StoreIC,18,4 -block_count,StoreIC,19,4 -block_count,StoreIC,20,3 -block_count,StoreIC,21,3 +block_count,StoreIC,18,2 +block_count,StoreIC,19,2 +block_count,StoreIC,20,2 +block_count,StoreIC,21,2 block_count,StoreIC,22,0 block_count,StoreIC,23,0 -block_count,StoreIC,24,157 -block_count,StoreIC,25,240 +block_count,StoreIC,24,158 +block_count,StoreIC,25,242 block_count,StoreIC,26,83 block_count,StoreIC,27,83 block_count,StoreIC,28,0 -block_count,StoreIC,29,157 -block_count,StoreIC,30,477 +block_count,StoreIC,29,158 +block_count,StoreIC,30,476 block_count,StoreIC,31,675 block_count,StoreIC,32,241 block_count,StoreIC,33,9 @@ -26847,7 +26842,7 @@ block_count,StoreIC,184,0 block_count,StoreIC,185,0 block_count,StoreIC,186,227 -block_count,StoreIC,187,189 +block_count,StoreIC,187,188 block_count,StoreIC,188,180 block_count,StoreIC,189,5 block_count,StoreIC,190,5 @@ -26857,7 +26852,7 @@ block_count,StoreIC,194,34 block_count,StoreIC,195,0 block_count,StoreIC,196,34 -block_count,StoreIC,197,141 +block_count,StoreIC,197,140 block_count,StoreIC,198,0 block_count,StoreIC,199,8 block_count,StoreIC,200,4 @@ -26912,8 +26907,8 @@ block_count,StoreIC,249,19 block_count,StoreIC,250,22 block_count,StoreIC,251,42 -block_count,StoreIC,252,185 -block_count,StoreIC,253,178 +block_count,StoreIC,252,184 +block_count,StoreIC,253,177 block_count,StoreIC,254,7 block_count,StoreIC,255,4 block_count,StoreIC,256,2 @@ -26969,18 +26964,18 @@ block_count,StoreIC,306,419 block_count,StoreIC,307,400 block_count,StoreIC,308,400 -block_count,StoreIC,309,39 +block_count,StoreIC,309,40 block_count,StoreIC,310,36 block_count,StoreIC,311,36 block_count,StoreIC,312,0 block_count,StoreIC,313,3 -block_count,StoreIC,314,39 +block_count,StoreIC,314,40 block_count,StoreIC,315,0 -block_count,StoreIC,316,39 +block_count,StoreIC,316,40 block_count,StoreIC,317,6 block_count,StoreIC,318,33 -block_count,StoreIC,319,39 -block_count,StoreIC,320,39 +block_count,StoreIC,319,40 +block_count,StoreIC,320,40 block_count,StoreIC,321,0 block_count,StoreIC,322,0 block_count,StoreIC,323,0 @@ -26994,19 +26989,19 @@ block_count,StoreIC,331,0 block_count,StoreIC,332,0 block_count,StoreIC,333,0 -block_count,StoreIC,334,191 -block_count,StoreIC,335,191 -block_count,StoreIC,336,191 +block_count,StoreIC,334,190 +block_count,StoreIC,335,190 +block_count,StoreIC,336,190 block_count,StoreIC,337,11 block_count,StoreIC,338,0 block_count,StoreIC,339,11 -block_count,StoreIC,340,179 +block_count,StoreIC,340,178 block_count,StoreIC,341,0 -block_count,StoreIC,342,191 +block_count,StoreIC,342,190 block_count,StoreIC,343,43 -block_count,StoreIC,344,147 -block_count,StoreIC,345,191 -block_count,StoreIC,346,191 +block_count,StoreIC,344,146 +block_count,StoreIC,345,190 +block_count,StoreIC,346,190 block_count,StoreIC,347,0 block_count,StoreIC,348,0 block_count,StoreIC,349,0 @@ -27044,24 +27039,24 @@ block_count,StoreIC,381,6 block_count,StoreIC,382,0 block_count,StoreIC,383,1 -block_count,StoreIC_Megamorphic,0,1306 -block_count,StoreIC_Megamorphic,1,1306 +block_count,StoreIC_Megamorphic,0,1305 +block_count,StoreIC_Megamorphic,1,1305 block_count,StoreIC_Megamorphic,2,0 -block_count,StoreIC_Megamorphic,3,1306 -block_count,StoreIC_Megamorphic,4,1306 +block_count,StoreIC_Megamorphic,3,1305 +block_count,StoreIC_Megamorphic,4,1305 block_count,StoreIC_Megamorphic,5,0 -block_count,StoreIC_Megamorphic,6,1306 -block_count,StoreIC_Megamorphic,7,1195 -block_count,StoreIC_Megamorphic,8,1175 -block_count,StoreIC_Megamorphic,9,19 -block_count,StoreIC_Megamorphic,10,110 -block_count,StoreIC_Megamorphic,11,130 -block_count,StoreIC_Megamorphic,12,129 -block_count,StoreIC_Megamorphic,13,128 +block_count,StoreIC_Megamorphic,6,1305 +block_count,StoreIC_Megamorphic,7,1224 +block_count,StoreIC_Megamorphic,8,1160 +block_count,StoreIC_Megamorphic,9,63 +block_count,StoreIC_Megamorphic,10,81 +block_count,StoreIC_Megamorphic,11,144 +block_count,StoreIC_Megamorphic,12,144 +block_count,StoreIC_Megamorphic,13,142 block_count,StoreIC_Megamorphic,14,1 block_count,StoreIC_Megamorphic,15,0 -block_count,StoreIC_Megamorphic,16,1304 -block_count,StoreIC_Megamorphic,17,522 +block_count,StoreIC_Megamorphic,16,1303 +block_count,StoreIC_Megamorphic,17,521 block_count,StoreIC_Megamorphic,18,1 block_count,StoreIC_Megamorphic,19,1 block_count,StoreIC_Megamorphic,20,1 @@ -27204,18 +27199,18 @@ block_count,StoreIC_Megamorphic,157,0 block_count,StoreIC_Megamorphic,158,520 block_count,StoreIC_Megamorphic,159,520 -block_count,StoreIC_Megamorphic,160,318 -block_count,StoreIC_Megamorphic,161,318 -block_count,StoreIC_Megamorphic,162,318 +block_count,StoreIC_Megamorphic,160,317 +block_count,StoreIC_Megamorphic,161,317 +block_count,StoreIC_Megamorphic,162,317 block_count,StoreIC_Megamorphic,163,0 -block_count,StoreIC_Megamorphic,164,318 +block_count,StoreIC_Megamorphic,164,317 block_count,StoreIC_Megamorphic,165,0 -block_count,StoreIC_Megamorphic,166,318 -block_count,StoreIC_Megamorphic,167,318 +block_count,StoreIC_Megamorphic,166,317 +block_count,StoreIC_Megamorphic,167,317 block_count,StoreIC_Megamorphic,168,0 block_count,StoreIC_Megamorphic,169,0 block_count,StoreIC_Megamorphic,170,0 -block_count,StoreIC_Megamorphic,171,318 +block_count,StoreIC_Megamorphic,171,317 block_count,StoreIC_Megamorphic,172,199 block_count,StoreIC_Megamorphic,173,199 block_count,StoreIC_Megamorphic,174,0 @@ -27236,7 +27231,7 @@ block_count,StoreIC_Megamorphic,189,118 block_count,StoreIC_Megamorphic,190,0 block_count,StoreIC_Megamorphic,191,118 -block_count,StoreIC_Megamorphic,192,318 +block_count,StoreIC_Megamorphic,192,317 block_count,StoreIC_Megamorphic,193,29 block_count,StoreIC_Megamorphic,194,0 block_count,StoreIC_Megamorphic,195,0 @@ -27338,18 +27333,18 @@ block_count,StoreIC_Megamorphic,291,781 block_count,StoreIC_Megamorphic,292,781 block_count,StoreIC_Megamorphic,293,781 -block_count,StoreIC_Megamorphic,294,6 +block_count,StoreIC_Megamorphic,294,5 block_count,StoreIC_Megamorphic,295,5 block_count,StoreIC_Megamorphic,296,5 block_count,StoreIC_Megamorphic,297,0 block_count,StoreIC_Megamorphic,298,0 -block_count,StoreIC_Megamorphic,299,6 +block_count,StoreIC_Megamorphic,299,5 block_count,StoreIC_Megamorphic,300,0 -block_count,StoreIC_Megamorphic,301,6 +block_count,StoreIC_Megamorphic,301,5 block_count,StoreIC_Megamorphic,302,0 -block_count,StoreIC_Megamorphic,303,6 -block_count,StoreIC_Megamorphic,304,6 -block_count,StoreIC_Megamorphic,305,6 +block_count,StoreIC_Megamorphic,303,5 +block_count,StoreIC_Megamorphic,304,5 +block_count,StoreIC_Megamorphic,305,5 block_count,StoreIC_Megamorphic,306,0 block_count,StoreIC_Megamorphic,307,0 block_count,StoreIC_Megamorphic,308,0 @@ -27369,7 +27364,7 @@ block_count,StoreIC_Megamorphic,322,1 block_count,StoreIC_Megamorphic,323,0 block_count,StoreIC_Megamorphic,324,1 -block_count,StoreIC_Megamorphic,325,443 +block_count,StoreIC_Megamorphic,325,442 block_count,StoreIC_Megamorphic,326,0 block_count,StoreIC_Megamorphic,327,444 block_count,StoreIC_Megamorphic,328,2 @@ -27380,13 +27375,13 @@ block_count,StoreIC_Megamorphic,333,0 block_count,StoreIC_Megamorphic,334,0 block_count,StoreIC_Megamorphic,335,0 -block_count,StoreIC_Megamorphic,336,330 +block_count,StoreIC_Megamorphic,336,329 block_count,StoreIC_Megamorphic,337,0 -block_count,StoreIC_Megamorphic,338,330 +block_count,StoreIC_Megamorphic,338,329 block_count,StoreIC_Megamorphic,339,2 block_count,StoreIC_Megamorphic,340,327 -block_count,StoreIC_Megamorphic,341,330 -block_count,StoreIC_Megamorphic,342,330 +block_count,StoreIC_Megamorphic,341,329 +block_count,StoreIC_Megamorphic,342,329 block_count,StoreIC_Megamorphic,343,0 block_count,StoreIC_Megamorphic,344,0 block_count,StoreIC_Megamorphic,345,0 @@ -27415,16 +27410,16 @@ block_count,StoreICTrampoline,1,19 block_count,StoreICTrampoline,2,0 block_count,StoreICTrampoline,3,19 -block_count,StoreICTrampoline_Megamorphic,0,630 -block_count,StoreICTrampoline_Megamorphic,1,630 +block_count,StoreICTrampoline_Megamorphic,0,629 +block_count,StoreICTrampoline_Megamorphic,1,629 block_count,StoreICTrampoline_Megamorphic,2,0 -block_count,StoreICTrampoline_Megamorphic,3,630 +block_count,StoreICTrampoline_Megamorphic,3,629 block_count,StoreICBaseline,0,621 -block_count,DefineNamedOwnIC,0,80 -block_count,DefineNamedOwnIC,1,80 +block_count,DefineNamedOwnIC,0,79 +block_count,DefineNamedOwnIC,1,79 block_count,DefineNamedOwnIC,2,0 -block_count,DefineNamedOwnIC,3,80 -block_count,DefineNamedOwnIC,4,80 +block_count,DefineNamedOwnIC,3,79 +block_count,DefineNamedOwnIC,4,79 block_count,DefineNamedOwnIC,5,75 block_count,DefineNamedOwnIC,6,0 block_count,DefineNamedOwnIC,7,0 @@ -27744,19 +27739,19 @@ block_count,DefineNamedOwnIC,321,0 block_count,DefineNamedOwnIC,322,0 block_count,DefineNamedOwnIC,323,0 -block_count,DefineNamedOwnIC,324,60 -block_count,DefineNamedOwnIC,325,60 -block_count,DefineNamedOwnIC,326,60 +block_count,DefineNamedOwnIC,324,59 +block_count,DefineNamedOwnIC,325,59 +block_count,DefineNamedOwnIC,326,59 block_count,DefineNamedOwnIC,327,9 block_count,DefineNamedOwnIC,328,0 block_count,DefineNamedOwnIC,329,9 block_count,DefineNamedOwnIC,330,50 block_count,DefineNamedOwnIC,331,0 -block_count,DefineNamedOwnIC,332,60 +block_count,DefineNamedOwnIC,332,59 block_count,DefineNamedOwnIC,333,0 -block_count,DefineNamedOwnIC,334,60 -block_count,DefineNamedOwnIC,335,60 -block_count,DefineNamedOwnIC,336,60 +block_count,DefineNamedOwnIC,334,59 +block_count,DefineNamedOwnIC,335,59 +block_count,DefineNamedOwnIC,336,59 block_count,DefineNamedOwnIC,337,0 block_count,DefineNamedOwnIC,338,0 block_count,DefineNamedOwnIC,339,0 @@ -27795,15 +27790,15 @@ block_count,DefineNamedOwnIC,372,0 block_count,DefineNamedOwnIC,373,0 block_count,DefineNamedOwnICBaseline,0,73 -block_count,KeyedStoreIC,0,496 -block_count,KeyedStoreIC,1,496 +block_count,KeyedStoreIC,0,490 +block_count,KeyedStoreIC,1,490 block_count,KeyedStoreIC,2,0 -block_count,KeyedStoreIC,3,496 -block_count,KeyedStoreIC,4,496 -block_count,KeyedStoreIC,5,493 -block_count,KeyedStoreIC,6,44 +block_count,KeyedStoreIC,3,490 +block_count,KeyedStoreIC,4,490 +block_count,KeyedStoreIC,5,488 +block_count,KeyedStoreIC,6,43 block_count,KeyedStoreIC,7,0 -block_count,KeyedStoreIC,8,44 +block_count,KeyedStoreIC,8,43 block_count,KeyedStoreIC,9,23 block_count,KeyedStoreIC,10,0 block_count,KeyedStoreIC,11,0 @@ -27815,15 +27810,15 @@ block_count,KeyedStoreIC,17,0 block_count,KeyedStoreIC,18,22 block_count,KeyedStoreIC,19,20 -block_count,KeyedStoreIC,20,36 +block_count,KeyedStoreIC,20,35 block_count,KeyedStoreIC,21,15 block_count,KeyedStoreIC,22,15 block_count,KeyedStoreIC,23,0 block_count,KeyedStoreIC,24,20 -block_count,KeyedStoreIC,25,449 -block_count,KeyedStoreIC,26,470 -block_count,KeyedStoreIC,27,469 -block_count,KeyedStoreIC,28,469 +block_count,KeyedStoreIC,25,445 +block_count,KeyedStoreIC,26,465 +block_count,KeyedStoreIC,27,464 +block_count,KeyedStoreIC,28,464 block_count,KeyedStoreIC,29,102 block_count,KeyedStoreIC,30,102 block_count,KeyedStoreIC,31,0 @@ -27836,7 +27831,7 @@ block_count,KeyedStoreIC,38,1 block_count,KeyedStoreIC,39,0 block_count,KeyedStoreIC,40,0 -block_count,KeyedStoreIC,41,101 +block_count,KeyedStoreIC,41,100 block_count,KeyedStoreIC,42,0 block_count,KeyedStoreIC,43,0 block_count,KeyedStoreIC,44,0 @@ -27997,7 +27992,7 @@ block_count,KeyedStoreIC,199,0 block_count,KeyedStoreIC,200,0 block_count,KeyedStoreIC,201,0 -block_count,KeyedStoreIC,202,366 +block_count,KeyedStoreIC,202,361 block_count,KeyedStoreIC,203,0 block_count,KeyedStoreIC,204,0 block_count,KeyedStoreIC,205,0 @@ -28245,7 +28240,7 @@ block_count,KeyedStoreICTrampoline_Megamorphic,1,310 block_count,KeyedStoreICTrampoline_Megamorphic,2,0 block_count,KeyedStoreICTrampoline_Megamorphic,3,310 -block_count,KeyedStoreICBaseline,0,449 +block_count,KeyedStoreICBaseline,0,444 block_count,DefineKeyedOwnIC,0,2 block_count,DefineKeyedOwnIC,1,2 block_count,DefineKeyedOwnIC,2,0 @@ -28716,11 +28711,11 @@ block_count,StoreInArrayLiteralIC,29,0 block_count,StoreInArrayLiteralIC,30,0 block_count,StoreInArrayLiteralICBaseline,0,38 -block_count,LoadGlobalIC,0,1037 -block_count,LoadGlobalIC,1,1037 -block_count,LoadGlobalIC,2,933 -block_count,LoadGlobalIC,3,933 -block_count,LoadGlobalIC,4,933 +block_count,LoadGlobalIC,0,973 +block_count,LoadGlobalIC,1,973 +block_count,LoadGlobalIC,2,869 +block_count,LoadGlobalIC,3,868 +block_count,LoadGlobalIC,4,868 block_count,LoadGlobalIC,5,0 block_count,LoadGlobalIC,6,0 block_count,LoadGlobalIC,7,0 @@ -29171,11 +29166,11 @@ block_count,LoadGlobalICInsideTypeof,222,0 block_count,LoadGlobalICInsideTypeof,223,0 block_count,LoadGlobalICInsideTypeof,224,0 -block_count,LoadGlobalICTrampoline,0,97 -block_count,LoadGlobalICTrampoline,1,97 +block_count,LoadGlobalICTrampoline,0,68 +block_count,LoadGlobalICTrampoline,1,68 block_count,LoadGlobalICTrampoline,2,0 -block_count,LoadGlobalICTrampoline,3,97 -block_count,LoadGlobalICBaseline,0,874 +block_count,LoadGlobalICTrampoline,3,68 +block_count,LoadGlobalICBaseline,0,873 block_count,LoadGlobalICInsideTypeofTrampoline,0,0 block_count,LoadGlobalICInsideTypeofTrampoline,1,0 block_count,LoadGlobalICInsideTypeofTrampoline,2,0 @@ -29187,13 +29182,13 @@ block_count,LookupGlobalICBaseline,3,0 block_count,LookupGlobalICBaseline,4,2 block_count,LookupGlobalICBaseline,5,2 -block_count,LookupGlobalICBaseline,6,2 +block_count,LookupGlobalICBaseline,6,1 block_count,LookupGlobalICBaseline,7,0 block_count,LookupGlobalICBaseline,8,0 -block_count,LookupGlobalICBaseline,9,2 -block_count,LookupGlobalICBaseline,10,2 +block_count,LookupGlobalICBaseline,9,1 +block_count,LookupGlobalICBaseline,10,1 block_count,LookupGlobalICBaseline,11,0 -block_count,LookupGlobalICBaseline,12,2 +block_count,LookupGlobalICBaseline,12,1 block_count,LookupGlobalICInsideTypeofBaseline,0,0 block_count,LookupGlobalICInsideTypeofBaseline,1,0 block_count,LookupGlobalICInsideTypeofBaseline,2,0 @@ -29207,11 +29202,11 @@ block_count,LookupGlobalICInsideTypeofBaseline,10,0 block_count,LookupGlobalICInsideTypeofBaseline,11,0 block_count,LookupGlobalICInsideTypeofBaseline,12,0 -block_count,KeyedHasIC,0,727 -block_count,KeyedHasIC,1,727 +block_count,KeyedHasIC,0,726 +block_count,KeyedHasIC,1,726 block_count,KeyedHasIC,2,0 -block_count,KeyedHasIC,3,727 -block_count,KeyedHasIC,4,727 +block_count,KeyedHasIC,3,726 +block_count,KeyedHasIC,4,726 block_count,KeyedHasIC,5,726 block_count,KeyedHasIC,6,726 block_count,KeyedHasIC,7,0 @@ -29254,7 +29249,7 @@ block_count,KeyedHasIC,44,1 block_count,KeyedHasIC,45,1 block_count,KeyedHasIC,46,0 -block_count,KeyedHasIC,47,725 +block_count,KeyedHasIC,47,724 block_count,KeyedHasIC,48,0 block_count,KeyedHasIC,49,0 block_count,KeyedHasIC,50,0 @@ -29480,15 +29475,15 @@ block_count,KeyedHasIC,270,0 block_count,KeyedHasIC,271,0 block_count,KeyedHasIC,272,0 -block_count,KeyedHasIC,273,725 +block_count,KeyedHasIC,273,724 block_count,KeyedHasIC,274,0 block_count,KeyedHasIC,275,0 block_count,KeyedHasICBaseline,0,6 -block_count,KeyedHasIC_Megamorphic,0,725 -block_count,KeyedHasIC_Megamorphic,1,725 +block_count,KeyedHasIC_Megamorphic,0,724 +block_count,KeyedHasIC_Megamorphic,1,724 block_count,KeyedHasIC_Megamorphic,2,0 -block_count,KeyedHasIC_Megamorphic,3,725 -block_count,KeyedHasIC_Megamorphic,4,725 +block_count,KeyedHasIC_Megamorphic,3,724 +block_count,KeyedHasIC_Megamorphic,4,724 block_count,KeyedHasIC_Megamorphic,5,723 block_count,KeyedHasIC_Megamorphic,6,723 block_count,KeyedHasIC_Megamorphic,7,0 @@ -29514,23 +29509,23 @@ block_count,KeyedHasIC_Megamorphic,27,0 block_count,KeyedHasIC_Megamorphic,28,0 block_count,KeyedHasIC_Megamorphic,29,1 -block_count,KeyedHasIC_Megamorphic,30,722 -block_count,KeyedHasIC_Megamorphic,31,2855 -block_count,KeyedHasIC_Megamorphic,32,2855 -block_count,KeyedHasIC_Megamorphic,33,2852 -block_count,KeyedHasIC_Megamorphic,34,2731 +block_count,KeyedHasIC_Megamorphic,30,721 +block_count,KeyedHasIC_Megamorphic,31,2854 +block_count,KeyedHasIC_Megamorphic,32,2854 +block_count,KeyedHasIC_Megamorphic,33,2850 +block_count,KeyedHasIC_Megamorphic,34,2729 block_count,KeyedHasIC_Megamorphic,35,719 block_count,KeyedHasIC_Megamorphic,36,719 block_count,KeyedHasIC_Megamorphic,37,0 block_count,KeyedHasIC_Megamorphic,38,719 -block_count,KeyedHasIC_Megamorphic,39,4316 -block_count,KeyedHasIC_Megamorphic,40,4316 +block_count,KeyedHasIC_Megamorphic,39,4314 +block_count,KeyedHasIC_Megamorphic,40,4314 block_count,KeyedHasIC_Megamorphic,41,0 -block_count,KeyedHasIC_Megamorphic,42,4316 -block_count,KeyedHasIC_Megamorphic,43,1418 -block_count,KeyedHasIC_Megamorphic,44,2897 -block_count,KeyedHasIC_Megamorphic,45,4316 -block_count,KeyedHasIC_Megamorphic,46,3597 +block_count,KeyedHasIC_Megamorphic,42,4314 +block_count,KeyedHasIC_Megamorphic,43,1417 +block_count,KeyedHasIC_Megamorphic,44,2896 +block_count,KeyedHasIC_Megamorphic,45,4314 +block_count,KeyedHasIC_Megamorphic,46,3595 block_count,KeyedHasIC_Megamorphic,47,719 block_count,KeyedHasIC_Megamorphic,48,719 block_count,KeyedHasIC_Megamorphic,49,719 @@ -29544,19 +29539,19 @@ block_count,KeyedHasIC_Megamorphic,57,0 block_count,KeyedHasIC_Megamorphic,58,719 block_count,KeyedHasIC_Megamorphic,59,0 -block_count,KeyedHasIC_Megamorphic,60,2011 +block_count,KeyedHasIC_Megamorphic,60,2010 block_count,KeyedHasIC_Megamorphic,61,0 -block_count,KeyedHasIC_Megamorphic,62,2011 +block_count,KeyedHasIC_Megamorphic,62,2010 block_count,KeyedHasIC_Megamorphic,63,489 -block_count,KeyedHasIC_Megamorphic,64,1522 -block_count,KeyedHasIC_Megamorphic,65,7543 -block_count,KeyedHasIC_Megamorphic,66,7540 -block_count,KeyedHasIC_Megamorphic,67,7538 -block_count,KeyedHasIC_Megamorphic,68,6021 -block_count,KeyedHasIC_Megamorphic,69,1517 +block_count,KeyedHasIC_Megamorphic,64,1521 +block_count,KeyedHasIC_Megamorphic,65,7539 +block_count,KeyedHasIC_Megamorphic,66,7536 +block_count,KeyedHasIC_Megamorphic,67,7534 +block_count,KeyedHasIC_Megamorphic,68,6018 +block_count,KeyedHasIC_Megamorphic,69,1516 block_count,KeyedHasIC_Megamorphic,70,2 block_count,KeyedHasIC_Megamorphic,71,2 -block_count,KeyedHasIC_Megamorphic,72,2006 +block_count,KeyedHasIC_Megamorphic,72,2005 block_count,KeyedHasIC_Megamorphic,73,1005 block_count,KeyedHasIC_Megamorphic,74,1000 block_count,KeyedHasIC_Megamorphic,75,1000 @@ -29600,8 +29595,8 @@ block_count,KeyedHasIC_Megamorphic,113,0 block_count,KeyedHasIC_Megamorphic,114,0 block_count,KeyedHasIC_Megamorphic,115,0 -block_count,KeyedHasIC_Megamorphic,116,2847 -block_count,KeyedHasIC_Megamorphic,117,2847 +block_count,KeyedHasIC_Megamorphic,116,2846 +block_count,KeyedHasIC_Megamorphic,117,2846 block_count,KeyedHasIC_Megamorphic,118,0 block_count,KeyedHasIC_Megamorphic,119,0 block_count,KeyedHasIC_Megamorphic,120,0 @@ -29639,14 +29634,14 @@ block_count,KeyedHasIC_Megamorphic,152,0 block_count,KeyedHasIC_Megamorphic,153,0 block_count,KeyedHasIC_Megamorphic,154,0 -block_count,KeyedHasIC_Megamorphic,155,2847 +block_count,KeyedHasIC_Megamorphic,155,2846 block_count,KeyedHasIC_Megamorphic,156,4 block_count,KeyedHasIC_Megamorphic,157,4 block_count,KeyedHasIC_Megamorphic,158,0 -block_count,KeyedHasIC_Megamorphic,159,2842 -block_count,KeyedHasIC_Megamorphic,160,2847 -block_count,KeyedHasIC_Megamorphic,161,2133 -block_count,KeyedHasIC_Megamorphic,162,714 +block_count,KeyedHasIC_Megamorphic,159,2841 +block_count,KeyedHasIC_Megamorphic,160,2846 +block_count,KeyedHasIC_Megamorphic,161,2132 +block_count,KeyedHasIC_Megamorphic,162,713 block_count,KeyedHasIC_Megamorphic,163,1 block_count,KeyedHasIC_Megamorphic,164,1 block_count,KeyedHasIC_Megamorphic,165,1 @@ -30033,9 +30028,9 @@ block_count,FindOrderedHashMapEntry,14,57 block_count,FindOrderedHashMapEntry,15,63 block_count,FindOrderedHashMapEntry,16,131 -block_count,FindOrderedHashMapEntry,17,166 -block_count,FindOrderedHashMapEntry,18,58 -block_count,FindOrderedHashMapEntry,19,35 +block_count,FindOrderedHashMapEntry,17,219 +block_count,FindOrderedHashMapEntry,18,112 +block_count,FindOrderedHashMapEntry,19,88 block_count,FindOrderedHashMapEntry,20,23 block_count,FindOrderedHashMapEntry,21,107 block_count,FindOrderedHashMapEntry,22,0 @@ -30072,14 +30067,14 @@ block_count,FindOrderedHashMapEntry,53,8 block_count,FindOrderedHashMapEntry,54,259 block_count,FindOrderedHashMapEntry,55,327 -block_count,FindOrderedHashMapEntry,56,285 -block_count,FindOrderedHashMapEntry,57,285 +block_count,FindOrderedHashMapEntry,56,284 +block_count,FindOrderedHashMapEntry,57,284 block_count,FindOrderedHashMapEntry,58,1 block_count,FindOrderedHashMapEntry,59,283 block_count,FindOrderedHashMapEntry,60,127 block_count,FindOrderedHashMapEntry,61,33 block_count,FindOrderedHashMapEntry,62,93 -block_count,FindOrderedHashMapEntry,63,33 +block_count,FindOrderedHashMapEntry,63,32 block_count,FindOrderedHashMapEntry,64,60 block_count,FindOrderedHashMapEntry,65,156 block_count,FindOrderedHashMapEntry,66,217 @@ -30099,7 +30094,7 @@ block_count,FindOrderedHashMapEntry,80,3 block_count,FindOrderedHashMapEntry,81,0 block_count,FindOrderedHashMapEntry,82,0 -block_count,FindOrderedHashMapEntry,83,2 +block_count,FindOrderedHashMapEntry,83,1 block_count,MapConstructor,0,77 block_count,MapConstructor,1,0 block_count,MapConstructor,2,77 @@ -30511,9 +30506,9 @@ block_count,MapPrototypeSet,27,42 block_count,MapPrototypeSet,28,46 block_count,MapPrototypeSet,29,46 -block_count,MapPrototypeSet,30,78 -block_count,MapPrototypeSet,31,43 -block_count,MapPrototypeSet,32,32 +block_count,MapPrototypeSet,30,77 +block_count,MapPrototypeSet,31,42 +block_count,MapPrototypeSet,32,31 block_count,MapPrototypeSet,33,11 block_count,MapPrototypeSet,34,34 block_count,MapPrototypeSet,35,0 @@ -30685,13 +30680,13 @@ block_count,MapPrototypeDelete,96,0 block_count,MapPrototypeDelete,97,0 block_count,MapPrototypeDelete,98,0 -block_count,MapPrototypeGet,0,6 +block_count,MapPrototypeGet,0,5 block_count,MapPrototypeGet,1,0 -block_count,MapPrototypeGet,2,6 -block_count,MapPrototypeGet,3,6 -block_count,MapPrototypeGet,4,6 +block_count,MapPrototypeGet,2,5 +block_count,MapPrototypeGet,3,5 +block_count,MapPrototypeGet,4,5 block_count,MapPrototypeGet,5,0 -block_count,MapPrototypeGet,6,6 +block_count,MapPrototypeGet,6,5 block_count,MapPrototypeGet,7,3 block_count,MapPrototypeGet,8,2 block_count,MapPrototypeGet,9,0 @@ -30879,26 +30874,26 @@ block_count,MapIteratorToList,54,0 block_count,MapIteratorToList,55,0 block_count,MapIteratorToList,56,0 -block_count,Add_Baseline,0,569 -block_count,Add_Baseline,1,333 +block_count,Add_Baseline,0,564 +block_count,Add_Baseline,1,332 block_count,Add_Baseline,2,5 block_count,Add_Baseline,3,5 block_count,Add_Baseline,4,0 -block_count,Add_Baseline,5,327 -block_count,Add_Baseline,6,327 +block_count,Add_Baseline,5,326 +block_count,Add_Baseline,6,326 block_count,Add_Baseline,7,0 block_count,Add_Baseline,8,326 -block_count,Add_Baseline,9,327 +block_count,Add_Baseline,9,326 block_count,Add_Baseline,10,0 -block_count,Add_Baseline,11,235 -block_count,Add_Baseline,12,143 -block_count,Add_Baseline,13,122 -block_count,Add_Baseline,14,122 +block_count,Add_Baseline,11,232 +block_count,Add_Baseline,12,141 +block_count,Add_Baseline,13,121 +block_count,Add_Baseline,14,121 block_count,Add_Baseline,15,0 block_count,Add_Baseline,16,20 -block_count,Add_Baseline,17,92 -block_count,Add_Baseline,18,92 -block_count,Add_Baseline,19,86 +block_count,Add_Baseline,17,90 +block_count,Add_Baseline,18,90 +block_count,Add_Baseline,19,85 block_count,Add_Baseline,20,0 block_count,Add_Baseline,21,0 block_count,Add_Baseline,22,0 @@ -30912,19 +30907,19 @@ block_count,Add_Baseline,30,0 block_count,Add_Baseline,31,0 block_count,Add_Baseline,32,0 -block_count,Add_Baseline,33,86 +block_count,Add_Baseline,33,84 block_count,Add_Baseline,34,6 -block_count,Add_Baseline,35,6 +block_count,Add_Baseline,35,5 block_count,Add_Baseline,36,0 block_count,Add_Baseline,37,0 block_count,Add_Baseline,38,0 block_count,Add_Baseline,39,0 block_count,Add_Baseline,40,0 block_count,Add_Baseline,41,0 -block_count,Add_Baseline,42,79 +block_count,Add_Baseline,42,78 block_count,Add_Baseline,43,0 -block_count,Add_Baseline,44,79 -block_count,Add_Baseline,45,79 +block_count,Add_Baseline,44,78 +block_count,Add_Baseline,45,78 block_count,Add_Baseline,46,5 block_count,Add_Baseline,47,0 block_count,Add_Baseline,48,0 @@ -30936,23 +30931,23 @@ block_count,Add_Baseline,54,0 block_count,Add_Baseline,55,12 block_count,Add_Baseline,56,0 -block_count,Add_Baseline,57,13 +block_count,Add_Baseline,57,12 block_count,Add_Baseline,58,0 -block_count,Add_Baseline,59,13 -block_count,Add_Baseline,60,13 -block_count,Add_Baseline,61,149 +block_count,Add_Baseline,59,12 +block_count,Add_Baseline,60,12 +block_count,Add_Baseline,61,147 block_count,Add_Baseline,62,0 -block_count,Add_Baseline,63,149 -block_count,Add_Baseline,64,149 +block_count,Add_Baseline,63,147 +block_count,Add_Baseline,64,147 block_count,Add_Baseline,65,0 -block_count,Add_Baseline,66,149 -block_count,Add_Baseline,67,149 -block_count,AddSmi_Baseline,0,551 -block_count,AddSmi_Baseline,1,549 -block_count,AddSmi_Baseline,2,549 +block_count,Add_Baseline,66,147 +block_count,Add_Baseline,67,147 +block_count,AddSmi_Baseline,0,552 +block_count,AddSmi_Baseline,1,550 +block_count,AddSmi_Baseline,2,550 block_count,AddSmi_Baseline,3,0 -block_count,AddSmi_Baseline,4,549 -block_count,AddSmi_Baseline,5,549 +block_count,AddSmi_Baseline,4,550 +block_count,AddSmi_Baseline,5,550 block_count,AddSmi_Baseline,6,0 block_count,AddSmi_Baseline,7,2 block_count,AddSmi_Baseline,8,2 @@ -31021,10 +31016,10 @@ block_count,Subtract_Baseline,12,0 block_count,Subtract_Baseline,13,59 block_count,Subtract_Baseline,14,59 -block_count,Subtract_Baseline,15,57 -block_count,Subtract_Baseline,16,57 -block_count,Subtract_Baseline,17,54 -block_count,Subtract_Baseline,18,54 +block_count,Subtract_Baseline,15,58 +block_count,Subtract_Baseline,16,58 +block_count,Subtract_Baseline,17,55 +block_count,Subtract_Baseline,18,55 block_count,Subtract_Baseline,19,0 block_count,Subtract_Baseline,20,3 block_count,Subtract_Baseline,21,0 @@ -31082,20 +31077,20 @@ block_count,SubtractSmi_Baseline,16,0 block_count,SubtractSmi_Baseline,17,17 block_count,SubtractSmi_Baseline,18,17 -block_count,Multiply_Baseline,0,181 +block_count,Multiply_Baseline,0,180 block_count,Multiply_Baseline,1,30 block_count,Multiply_Baseline,2,15 block_count,Multiply_Baseline,3,15 block_count,Multiply_Baseline,4,0 block_count,Multiply_Baseline,5,14 block_count,Multiply_Baseline,6,14 -block_count,Multiply_Baseline,7,12 +block_count,Multiply_Baseline,7,11 block_count,Multiply_Baseline,8,11 block_count,Multiply_Baseline,9,0 block_count,Multiply_Baseline,10,0 block_count,Multiply_Baseline,11,0 block_count,Multiply_Baseline,12,0 -block_count,Multiply_Baseline,13,12 +block_count,Multiply_Baseline,13,11 block_count,Multiply_Baseline,14,2 block_count,Multiply_Baseline,15,2 block_count,Multiply_Baseline,16,0 @@ -31147,18 +31142,18 @@ block_count,Multiply_Baseline,62,0 block_count,Multiply_Baseline,63,0 block_count,Multiply_Baseline,64,0 -block_count,Multiply_Baseline,65,166 +block_count,Multiply_Baseline,65,165 block_count,Multiply_Baseline,66,0 -block_count,Multiply_Baseline,67,166 -block_count,Multiply_Baseline,68,166 +block_count,Multiply_Baseline,67,165 +block_count,Multiply_Baseline,68,165 block_count,Multiply_Baseline,69,0 -block_count,Multiply_Baseline,70,166 -block_count,Multiply_Baseline,71,166 +block_count,Multiply_Baseline,70,165 +block_count,Multiply_Baseline,71,165 block_count,MultiplySmi_Baseline,0,29 block_count,MultiplySmi_Baseline,1,24 block_count,MultiplySmi_Baseline,2,23 block_count,MultiplySmi_Baseline,3,16 -block_count,MultiplySmi_Baseline,4,15 +block_count,MultiplySmi_Baseline,4,16 block_count,MultiplySmi_Baseline,5,0 block_count,MultiplySmi_Baseline,6,0 block_count,MultiplySmi_Baseline,7,0 @@ -31301,7 +31296,7 @@ block_count,DivideSmi_Baseline,10,0 block_count,DivideSmi_Baseline,11,0 block_count,DivideSmi_Baseline,12,3 -block_count,DivideSmi_Baseline,13,0 +block_count,DivideSmi_Baseline,13,1 block_count,DivideSmi_Baseline,14,2 block_count,DivideSmi_Baseline,15,0 block_count,DivideSmi_Baseline,16,2 @@ -31312,14 +31307,14 @@ block_count,DivideSmi_Baseline,21,0 block_count,DivideSmi_Baseline,22,3 block_count,DivideSmi_Baseline,23,3 -block_count,DivideSmi_Baseline,24,2 -block_count,DivideSmi_Baseline,25,2 +block_count,DivideSmi_Baseline,24,1 +block_count,DivideSmi_Baseline,25,1 block_count,DivideSmi_Baseline,26,0 -block_count,DivideSmi_Baseline,27,2 -block_count,DivideSmi_Baseline,28,2 +block_count,DivideSmi_Baseline,27,1 +block_count,DivideSmi_Baseline,28,1 block_count,DivideSmi_Baseline,29,0 -block_count,DivideSmi_Baseline,30,2 -block_count,DivideSmi_Baseline,31,2 +block_count,DivideSmi_Baseline,30,1 +block_count,DivideSmi_Baseline,31,1 block_count,Modulus_Baseline,0,2 block_count,Modulus_Baseline,1,2 block_count,Modulus_Baseline,2,0 @@ -31390,8 +31385,8 @@ block_count,Modulus_Baseline,67,0 block_count,Modulus_Baseline,68,0 block_count,ModulusSmi_Baseline,0,4 -block_count,ModulusSmi_Baseline,1,4 -block_count,ModulusSmi_Baseline,2,4 +block_count,ModulusSmi_Baseline,1,3 +block_count,ModulusSmi_Baseline,2,3 block_count,ModulusSmi_Baseline,3,0 block_count,ModulusSmi_Baseline,4,0 block_count,ModulusSmi_Baseline,5,0 @@ -31401,15 +31396,15 @@ block_count,ModulusSmi_Baseline,9,0 block_count,ModulusSmi_Baseline,10,0 block_count,ModulusSmi_Baseline,11,0 -block_count,ModulusSmi_Baseline,12,4 +block_count,ModulusSmi_Baseline,12,3 block_count,ModulusSmi_Baseline,13,0 -block_count,ModulusSmi_Baseline,14,4 +block_count,ModulusSmi_Baseline,14,3 block_count,ModulusSmi_Baseline,15,0 -block_count,ModulusSmi_Baseline,16,4 -block_count,ModulusSmi_Baseline,17,4 +block_count,ModulusSmi_Baseline,16,3 +block_count,ModulusSmi_Baseline,17,3 block_count,ModulusSmi_Baseline,18,0 -block_count,ModulusSmi_Baseline,19,4 -block_count,ModulusSmi_Baseline,20,4 +block_count,ModulusSmi_Baseline,19,3 +block_count,ModulusSmi_Baseline,20,3 block_count,ModulusSmi_Baseline,21,0 block_count,ModulusSmi_Baseline,22,0 block_count,ModulusSmi_Baseline,23,0 @@ -31576,7 +31571,7 @@ block_count,BitwiseAnd_Baseline,76,0 block_count,BitwiseAnd_Baseline,77,32 block_count,BitwiseAnd_Baseline,78,32 -block_count,BitwiseAndSmi_Baseline,0,115 +block_count,BitwiseAndSmi_Baseline,0,114 block_count,BitwiseAndSmi_Baseline,1,6 block_count,BitwiseAndSmi_Baseline,2,6 block_count,BitwiseAndSmi_Baseline,3,1 @@ -31608,10 +31603,10 @@ block_count,BitwiseAndSmi_Baseline,29,6 block_count,BitwiseAndSmi_Baseline,30,6 block_count,BitwiseAndSmi_Baseline,31,108 -block_count,BitwiseAndSmi_Baseline,32,115 +block_count,BitwiseAndSmi_Baseline,32,114 block_count,BitwiseAndSmi_Baseline,33,0 -block_count,BitwiseAndSmi_Baseline,34,115 -block_count,BitwiseOr_Baseline,0,59 +block_count,BitwiseAndSmi_Baseline,34,114 +block_count,BitwiseOr_Baseline,0,58 block_count,BitwiseOr_Baseline,1,54 block_count,BitwiseOr_Baseline,2,4 block_count,BitwiseOr_Baseline,3,4 @@ -31655,7 +31650,7 @@ block_count,BitwiseOr_Baseline,41,0 block_count,BitwiseOr_Baseline,42,0 block_count,BitwiseOr_Baseline,43,4 -block_count,BitwiseOr_Baseline,44,59 +block_count,BitwiseOr_Baseline,44,58 block_count,BitwiseOr_Baseline,45,55 block_count,BitwiseOr_Baseline,46,3 block_count,BitwiseOr_Baseline,47,3 @@ -31677,20 +31672,20 @@ block_count,BitwiseOr_Baseline,63,0 block_count,BitwiseOr_Baseline,64,0 block_count,BitwiseOr_Baseline,65,3 -block_count,BitwiseOr_Baseline,66,59 -block_count,BitwiseOr_Baseline,67,53 +block_count,BitwiseOr_Baseline,66,58 +block_count,BitwiseOr_Baseline,67,52 block_count,BitwiseOr_Baseline,68,5 block_count,BitwiseOr_Baseline,69,0 block_count,BitwiseOr_Baseline,70,5 block_count,BitwiseOr_Baseline,71,5 -block_count,BitwiseOr_Baseline,72,59 +block_count,BitwiseOr_Baseline,72,58 block_count,BitwiseOr_Baseline,73,5 -block_count,BitwiseOr_Baseline,74,53 -block_count,BitwiseOr_Baseline,75,59 +block_count,BitwiseOr_Baseline,74,52 +block_count,BitwiseOr_Baseline,75,58 block_count,BitwiseOr_Baseline,76,0 -block_count,BitwiseOr_Baseline,77,59 -block_count,BitwiseOr_Baseline,78,59 -block_count,BitwiseOrSmi_Baseline,0,283 +block_count,BitwiseOr_Baseline,77,58 +block_count,BitwiseOr_Baseline,78,58 +block_count,BitwiseOrSmi_Baseline,0,284 block_count,BitwiseOrSmi_Baseline,1,4 block_count,BitwiseOrSmi_Baseline,2,4 block_count,BitwiseOrSmi_Baseline,3,0 @@ -31721,10 +31716,10 @@ block_count,BitwiseOrSmi_Baseline,28,2 block_count,BitwiseOrSmi_Baseline,29,2 block_count,BitwiseOrSmi_Baseline,30,4 -block_count,BitwiseOrSmi_Baseline,31,278 -block_count,BitwiseOrSmi_Baseline,32,283 +block_count,BitwiseOrSmi_Baseline,31,279 +block_count,BitwiseOrSmi_Baseline,32,284 block_count,BitwiseOrSmi_Baseline,33,0 -block_count,BitwiseOrSmi_Baseline,34,283 +block_count,BitwiseOrSmi_Baseline,34,284 block_count,BitwiseXor_Baseline,0,40 block_count,BitwiseXor_Baseline,1,22 block_count,BitwiseXor_Baseline,2,17 @@ -31906,14 +31901,14 @@ block_count,ShiftLeft_Baseline,64,0 block_count,ShiftLeft_Baseline,65,0 block_count,ShiftLeft_Baseline,66,5 -block_count,ShiftLeft_Baseline,67,5 +block_count,ShiftLeft_Baseline,67,4 block_count,ShiftLeft_Baseline,68,0 block_count,ShiftLeft_Baseline,69,0 block_count,ShiftLeft_Baseline,70,0 block_count,ShiftLeft_Baseline,71,0 block_count,ShiftLeft_Baseline,72,5 block_count,ShiftLeft_Baseline,73,0 -block_count,ShiftLeft_Baseline,74,5 +block_count,ShiftLeft_Baseline,74,4 block_count,ShiftLeft_Baseline,75,5 block_count,ShiftLeft_Baseline,76,0 block_count,ShiftLeft_Baseline,77,5 @@ -32072,7 +32067,7 @@ block_count,ShiftRightSmi_Baseline,28,0 block_count,ShiftRightSmi_Baseline,29,5 block_count,ShiftRightSmi_Baseline,30,5 -block_count,ShiftRightSmi_Baseline,31,230 +block_count,ShiftRightSmi_Baseline,31,231 block_count,ShiftRightSmi_Baseline,32,236 block_count,ShiftRightSmi_Baseline,33,0 block_count,ShiftRightSmi_Baseline,34,236 @@ -32196,14 +32191,14 @@ block_count,ShiftRightLogicalSmi_Baseline,41,18 block_count,ShiftRightLogicalSmi_Baseline,42,0 block_count,ShiftRightLogicalSmi_Baseline,43,18 -block_count,Equal_Baseline,0,332 -block_count,Equal_Baseline,1,336 -block_count,Equal_Baseline,2,255 +block_count,Equal_Baseline,0,330 +block_count,Equal_Baseline,1,334 +block_count,Equal_Baseline,2,253 block_count,Equal_Baseline,3,60 -block_count,Equal_Baseline,4,58 +block_count,Equal_Baseline,4,57 block_count,Equal_Baseline,5,23 block_count,Equal_Baseline,6,22 -block_count,Equal_Baseline,7,19 +block_count,Equal_Baseline,7,18 block_count,Equal_Baseline,8,14 block_count,Equal_Baseline,9,14 block_count,Equal_Baseline,10,0 @@ -32266,24 +32261,24 @@ block_count,Equal_Baseline,67,0 block_count,Equal_Baseline,68,0 block_count,Equal_Baseline,69,0 -block_count,Equal_Baseline,70,35 +block_count,Equal_Baseline,70,34 block_count,Equal_Baseline,71,0 block_count,Equal_Baseline,72,34 -block_count,Equal_Baseline,73,25 +block_count,Equal_Baseline,73,24 block_count,Equal_Baseline,74,9 block_count,Equal_Baseline,75,9 block_count,Equal_Baseline,76,9 block_count,Equal_Baseline,77,0 block_count,Equal_Baseline,78,34 block_count,Equal_Baseline,79,0 -block_count,Equal_Baseline,80,34 +block_count,Equal_Baseline,80,33 block_count,Equal_Baseline,81,34 block_count,Equal_Baseline,82,4 -block_count,Equal_Baseline,83,30 +block_count,Equal_Baseline,83,29 block_count,Equal_Baseline,84,34 block_count,Equal_Baseline,85,2 block_count,Equal_Baseline,86,2 -block_count,Equal_Baseline,87,194 +block_count,Equal_Baseline,87,193 block_count,Equal_Baseline,88,4 block_count,Equal_Baseline,89,0 block_count,Equal_Baseline,90,0 @@ -32303,7 +32298,7 @@ block_count,Equal_Baseline,104,0 block_count,Equal_Baseline,105,0 block_count,Equal_Baseline,106,4 -block_count,Equal_Baseline,107,189 +block_count,Equal_Baseline,107,188 block_count,Equal_Baseline,108,0 block_count,Equal_Baseline,109,0 block_count,Equal_Baseline,110,0 @@ -32319,7 +32314,7 @@ block_count,Equal_Baseline,120,7 block_count,Equal_Baseline,121,4 block_count,Equal_Baseline,122,2 -block_count,Equal_Baseline,123,81 +block_count,Equal_Baseline,123,80 block_count,Equal_Baseline,124,16 block_count,Equal_Baseline,125,15 block_count,Equal_Baseline,126,10 @@ -32340,48 +32335,48 @@ block_count,Equal_Baseline,141,0 block_count,Equal_Baseline,142,64 block_count,Equal_Baseline,143,83 -block_count,Equal_Baseline,144,214 -block_count,Equal_Baseline,145,332 +block_count,Equal_Baseline,144,212 +block_count,Equal_Baseline,145,330 block_count,Equal_Baseline,146,0 -block_count,Equal_Baseline,147,332 -block_count,StrictEqual_Baseline,0,496 -block_count,StrictEqual_Baseline,1,411 -block_count,StrictEqual_Baseline,2,285 -block_count,StrictEqual_Baseline,3,285 -block_count,StrictEqual_Baseline,4,283 -block_count,StrictEqual_Baseline,5,139 -block_count,StrictEqual_Baseline,6,139 -block_count,StrictEqual_Baseline,7,62 -block_count,StrictEqual_Baseline,8,60 -block_count,StrictEqual_Baseline,9,48 +block_count,Equal_Baseline,147,330 +block_count,StrictEqual_Baseline,0,497 +block_count,StrictEqual_Baseline,1,412 +block_count,StrictEqual_Baseline,2,289 +block_count,StrictEqual_Baseline,3,289 +block_count,StrictEqual_Baseline,4,288 +block_count,StrictEqual_Baseline,5,140 +block_count,StrictEqual_Baseline,6,140 +block_count,StrictEqual_Baseline,7,63 +block_count,StrictEqual_Baseline,8,61 +block_count,StrictEqual_Baseline,9,49 block_count,StrictEqual_Baseline,10,0 -block_count,StrictEqual_Baseline,11,48 +block_count,StrictEqual_Baseline,11,49 block_count,StrictEqual_Baseline,12,0 -block_count,StrictEqual_Baseline,13,48 +block_count,StrictEqual_Baseline,13,49 block_count,StrictEqual_Baseline,14,11 block_count,StrictEqual_Baseline,15,5 block_count,StrictEqual_Baseline,16,6 block_count,StrictEqual_Baseline,17,1 -block_count,StrictEqual_Baseline,18,77 -block_count,StrictEqual_Baseline,19,77 +block_count,StrictEqual_Baseline,18,76 +block_count,StrictEqual_Baseline,19,76 block_count,StrictEqual_Baseline,20,0 block_count,StrictEqual_Baseline,21,0 block_count,StrictEqual_Baseline,22,0 -block_count,StrictEqual_Baseline,23,76 +block_count,StrictEqual_Baseline,23,75 block_count,StrictEqual_Baseline,24,0 block_count,StrictEqual_Baseline,25,0 block_count,StrictEqual_Baseline,26,0 block_count,StrictEqual_Baseline,27,0 -block_count,StrictEqual_Baseline,28,144 +block_count,StrictEqual_Baseline,28,147 block_count,StrictEqual_Baseline,29,0 -block_count,StrictEqual_Baseline,30,144 -block_count,StrictEqual_Baseline,31,39 +block_count,StrictEqual_Baseline,30,147 +block_count,StrictEqual_Baseline,31,41 block_count,StrictEqual_Baseline,32,105 -block_count,StrictEqual_Baseline,33,144 +block_count,StrictEqual_Baseline,33,147 block_count,StrictEqual_Baseline,34,0 -block_count,StrictEqual_Baseline,35,143 -block_count,StrictEqual_Baseline,36,144 -block_count,StrictEqual_Baseline,37,99 +block_count,StrictEqual_Baseline,35,146 +block_count,StrictEqual_Baseline,36,147 +block_count,StrictEqual_Baseline,37,102 block_count,StrictEqual_Baseline,38,44 block_count,StrictEqual_Baseline,39,1 block_count,StrictEqual_Baseline,40,0 @@ -32393,15 +32388,15 @@ block_count,StrictEqual_Baseline,46,0 block_count,StrictEqual_Baseline,47,0 block_count,StrictEqual_Baseline,48,0 -block_count,StrictEqual_Baseline,49,125 +block_count,StrictEqual_Baseline,49,123 block_count,StrictEqual_Baseline,50,1 block_count,StrictEqual_Baseline,51,0 block_count,StrictEqual_Baseline,52,0 block_count,StrictEqual_Baseline,53,0 block_count,StrictEqual_Baseline,54,0 -block_count,StrictEqual_Baseline,55,124 +block_count,StrictEqual_Baseline,55,122 block_count,StrictEqual_Baseline,56,10 -block_count,StrictEqual_Baseline,57,85 +block_count,StrictEqual_Baseline,57,84 block_count,StrictEqual_Baseline,58,38 block_count,StrictEqual_Baseline,59,38 block_count,StrictEqual_Baseline,60,21 @@ -32420,16 +32415,16 @@ block_count,StrictEqual_Baseline,73,0 block_count,StrictEqual_Baseline,74,0 block_count,StrictEqual_Baseline,75,0 -block_count,StrictEqual_Baseline,76,46 -block_count,StrictEqual_Baseline,77,266 -block_count,StrictEqual_Baseline,78,85 -block_count,StrictEqual_Baseline,79,496 +block_count,StrictEqual_Baseline,76,45 +block_count,StrictEqual_Baseline,77,265 +block_count,StrictEqual_Baseline,78,84 +block_count,StrictEqual_Baseline,79,497 block_count,StrictEqual_Baseline,80,0 -block_count,StrictEqual_Baseline,81,495 -block_count,LessThan_Baseline,0,475 -block_count,LessThan_Baseline,1,476 +block_count,StrictEqual_Baseline,81,497 +block_count,LessThan_Baseline,0,466 +block_count,LessThan_Baseline,1,466 block_count,LessThan_Baseline,2,40 -block_count,LessThan_Baseline,3,9 +block_count,LessThan_Baseline,3,10 block_count,LessThan_Baseline,4,0 block_count,LessThan_Baseline,5,0 block_count,LessThan_Baseline,6,0 @@ -32516,7 +32511,7 @@ block_count,LessThan_Baseline,87,0 block_count,LessThan_Baseline,88,0 block_count,LessThan_Baseline,89,30 -block_count,LessThan_Baseline,90,435 +block_count,LessThan_Baseline,90,426 block_count,LessThan_Baseline,91,1 block_count,LessThan_Baseline,92,0 block_count,LessThan_Baseline,93,0 @@ -32528,24 +32523,24 @@ block_count,LessThan_Baseline,99,0 block_count,LessThan_Baseline,100,0 block_count,LessThan_Baseline,101,1 -block_count,LessThan_Baseline,102,434 -block_count,LessThan_Baseline,103,115 -block_count,LessThan_Baseline,104,319 +block_count,LessThan_Baseline,102,424 +block_count,LessThan_Baseline,103,111 +block_count,LessThan_Baseline,104,312 block_count,LessThan_Baseline,105,0 block_count,LessThan_Baseline,106,0 block_count,LessThan_Baseline,107,0 block_count,LessThan_Baseline,108,0 block_count,LessThan_Baseline,109,0 -block_count,LessThan_Baseline,110,40 +block_count,LessThan_Baseline,110,41 block_count,LessThan_Baseline,111,32 block_count,LessThan_Baseline,112,8 -block_count,LessThan_Baseline,113,147 -block_count,LessThan_Baseline,114,327 -block_count,LessThan_Baseline,115,475 +block_count,LessThan_Baseline,113,144 +block_count,LessThan_Baseline,114,321 +block_count,LessThan_Baseline,115,466 block_count,LessThan_Baseline,116,0 -block_count,LessThan_Baseline,117,475 -block_count,GreaterThan_Baseline,0,164 -block_count,GreaterThan_Baseline,1,165 +block_count,LessThan_Baseline,117,466 +block_count,GreaterThan_Baseline,0,162 +block_count,GreaterThan_Baseline,1,163 block_count,GreaterThan_Baseline,2,14 block_count,GreaterThan_Baseline,3,9 block_count,GreaterThan_Baseline,4,0 @@ -32612,7 +32607,7 @@ block_count,GreaterThan_Baseline,65,0 block_count,GreaterThan_Baseline,66,0 block_count,GreaterThan_Baseline,67,0 -block_count,GreaterThan_Baseline,68,8 +block_count,GreaterThan_Baseline,68,9 block_count,GreaterThan_Baseline,69,0 block_count,GreaterThan_Baseline,70,0 block_count,GreaterThan_Baseline,71,0 @@ -32634,7 +32629,7 @@ block_count,GreaterThan_Baseline,87,0 block_count,GreaterThan_Baseline,88,0 block_count,GreaterThan_Baseline,89,5 -block_count,GreaterThan_Baseline,90,150 +block_count,GreaterThan_Baseline,90,148 block_count,GreaterThan_Baseline,91,0 block_count,GreaterThan_Baseline,92,0 block_count,GreaterThan_Baseline,93,0 @@ -32646,8 +32641,8 @@ block_count,GreaterThan_Baseline,99,0 block_count,GreaterThan_Baseline,100,0 block_count,GreaterThan_Baseline,101,0 -block_count,GreaterThan_Baseline,102,150 -block_count,GreaterThan_Baseline,103,98 +block_count,GreaterThan_Baseline,102,148 +block_count,GreaterThan_Baseline,103,96 block_count,GreaterThan_Baseline,104,51 block_count,GreaterThan_Baseline,105,0 block_count,GreaterThan_Baseline,106,0 @@ -32657,13 +32652,13 @@ block_count,GreaterThan_Baseline,110,14 block_count,GreaterThan_Baseline,111,7 block_count,GreaterThan_Baseline,112,6 -block_count,GreaterThan_Baseline,113,106 +block_count,GreaterThan_Baseline,113,104 block_count,GreaterThan_Baseline,114,58 -block_count,GreaterThan_Baseline,115,164 +block_count,GreaterThan_Baseline,115,162 block_count,GreaterThan_Baseline,116,0 -block_count,GreaterThan_Baseline,117,164 -block_count,LessThanOrEqual_Baseline,0,62 -block_count,LessThanOrEqual_Baseline,1,62 +block_count,GreaterThan_Baseline,117,162 +block_count,LessThanOrEqual_Baseline,0,60 +block_count,LessThanOrEqual_Baseline,1,60 block_count,LessThanOrEqual_Baseline,2,6 block_count,LessThanOrEqual_Baseline,3,2 block_count,LessThanOrEqual_Baseline,4,0 @@ -32752,7 +32747,7 @@ block_count,LessThanOrEqual_Baseline,87,0 block_count,LessThanOrEqual_Baseline,88,0 block_count,LessThanOrEqual_Baseline,89,3 -block_count,LessThanOrEqual_Baseline,90,56 +block_count,LessThanOrEqual_Baseline,90,54 block_count,LessThanOrEqual_Baseline,91,1 block_count,LessThanOrEqual_Baseline,92,0 block_count,LessThanOrEqual_Baseline,93,0 @@ -32764,9 +32759,9 @@ block_count,LessThanOrEqual_Baseline,99,0 block_count,LessThanOrEqual_Baseline,100,0 block_count,LessThanOrEqual_Baseline,101,1 -block_count,LessThanOrEqual_Baseline,102,55 +block_count,LessThanOrEqual_Baseline,102,53 block_count,LessThanOrEqual_Baseline,103,5 -block_count,LessThanOrEqual_Baseline,104,49 +block_count,LessThanOrEqual_Baseline,104,47 block_count,LessThanOrEqual_Baseline,105,0 block_count,LessThanOrEqual_Baseline,106,0 block_count,LessThanOrEqual_Baseline,107,0 @@ -32776,14 +32771,14 @@ block_count,LessThanOrEqual_Baseline,111,2 block_count,LessThanOrEqual_Baseline,112,4 block_count,LessThanOrEqual_Baseline,113,8 -block_count,LessThanOrEqual_Baseline,114,54 -block_count,LessThanOrEqual_Baseline,115,62 +block_count,LessThanOrEqual_Baseline,114,52 +block_count,LessThanOrEqual_Baseline,115,60 block_count,LessThanOrEqual_Baseline,116,0 -block_count,LessThanOrEqual_Baseline,117,62 -block_count,GreaterThanOrEqual_Baseline,0,119 -block_count,GreaterThanOrEqual_Baseline,1,119 -block_count,GreaterThanOrEqual_Baseline,2,14 -block_count,GreaterThanOrEqual_Baseline,3,10 +block_count,LessThanOrEqual_Baseline,117,60 +block_count,GreaterThanOrEqual_Baseline,0,117 +block_count,GreaterThanOrEqual_Baseline,1,117 +block_count,GreaterThanOrEqual_Baseline,2,13 +block_count,GreaterThanOrEqual_Baseline,3,9 block_count,GreaterThanOrEqual_Baseline,4,0 block_count,GreaterThanOrEqual_Baseline,5,0 block_count,GreaterThanOrEqual_Baseline,6,0 @@ -32870,7 +32865,7 @@ block_count,GreaterThanOrEqual_Baseline,87,0 block_count,GreaterThanOrEqual_Baseline,88,0 block_count,GreaterThanOrEqual_Baseline,89,3 -block_count,GreaterThanOrEqual_Baseline,90,105 +block_count,GreaterThanOrEqual_Baseline,90,103 block_count,GreaterThanOrEqual_Baseline,91,0 block_count,GreaterThanOrEqual_Baseline,92,0 block_count,GreaterThanOrEqual_Baseline,93,0 @@ -32882,9 +32877,9 @@ block_count,GreaterThanOrEqual_Baseline,99,0 block_count,GreaterThanOrEqual_Baseline,100,0 block_count,GreaterThanOrEqual_Baseline,101,0 -block_count,GreaterThanOrEqual_Baseline,102,104 -block_count,GreaterThanOrEqual_Baseline,103,62 -block_count,GreaterThanOrEqual_Baseline,104,42 +block_count,GreaterThanOrEqual_Baseline,102,103 +block_count,GreaterThanOrEqual_Baseline,103,61 +block_count,GreaterThanOrEqual_Baseline,104,41 block_count,GreaterThanOrEqual_Baseline,105,0 block_count,GreaterThanOrEqual_Baseline,106,0 block_count,GreaterThanOrEqual_Baseline,107,0 @@ -32894,10 +32889,10 @@ block_count,GreaterThanOrEqual_Baseline,111,6 block_count,GreaterThanOrEqual_Baseline,112,7 block_count,GreaterThanOrEqual_Baseline,113,68 -block_count,GreaterThanOrEqual_Baseline,114,49 -block_count,GreaterThanOrEqual_Baseline,115,119 +block_count,GreaterThanOrEqual_Baseline,114,48 +block_count,GreaterThanOrEqual_Baseline,115,117 block_count,GreaterThanOrEqual_Baseline,116,0 -block_count,GreaterThanOrEqual_Baseline,117,119 +block_count,GreaterThanOrEqual_Baseline,117,117 block_count,BitwiseNot_Baseline,0,6 block_count,BitwiseNot_Baseline,1,5 block_count,BitwiseNot_Baseline,2,0 @@ -32959,8 +32954,8 @@ block_count,Decrement_Baseline,23,53 block_count,Decrement_Baseline,24,0 block_count,Decrement_Baseline,25,53 -block_count,Increment_Baseline,0,321 -block_count,Increment_Baseline,1,321 +block_count,Increment_Baseline,0,316 +block_count,Increment_Baseline,1,316 block_count,Increment_Baseline,2,0 block_count,Increment_Baseline,3,0 block_count,Increment_Baseline,4,0 @@ -32975,16 +32970,16 @@ block_count,Increment_Baseline,13,0 block_count,Increment_Baseline,14,0 block_count,Increment_Baseline,15,0 -block_count,Increment_Baseline,16,320 -block_count,Increment_Baseline,17,320 +block_count,Increment_Baseline,16,316 +block_count,Increment_Baseline,17,316 block_count,Increment_Baseline,18,0 block_count,Increment_Baseline,19,0 block_count,Increment_Baseline,20,0 block_count,Increment_Baseline,21,0 block_count,Increment_Baseline,22,0 -block_count,Increment_Baseline,23,321 +block_count,Increment_Baseline,23,316 block_count,Increment_Baseline,24,0 -block_count,Increment_Baseline,25,321 +block_count,Increment_Baseline,25,316 block_count,Negate_Baseline,0,13 block_count,Negate_Baseline,1,13 block_count,Negate_Baseline,2,11 @@ -33949,7 +33944,7 @@ block_count,ObjectPrototypeHasOwnProperty,21,0 block_count,ObjectPrototypeHasOwnProperty,22,0 block_count,ObjectPrototypeHasOwnProperty,23,191 -block_count,ObjectPrototypeHasOwnProperty,24,188 +block_count,ObjectPrototypeHasOwnProperty,24,187 block_count,ObjectPrototypeHasOwnProperty,25,3 block_count,ObjectPrototypeHasOwnProperty,26,0 block_count,ObjectPrototypeHasOwnProperty,27,0 @@ -34410,7 +34405,7 @@ block_count,ForInFilter,70,50 block_count,ForInFilter,71,98 block_count,ForInFilter,72,50 -block_count,ForInFilter,73,49 +block_count,ForInFilter,73,48 block_count,ForInFilter,74,1 block_count,ForInFilter,75,0 block_count,ForInFilter,76,0 @@ -34929,7 +34924,7 @@ block_count,FindOrderedHashSetEntry,52,41 block_count,FindOrderedHashSetEntry,53,44 block_count,FindOrderedHashSetEntry,54,85 -block_count,FindOrderedHashSetEntry,55,220 +block_count,FindOrderedHashSetEntry,55,219 block_count,FindOrderedHashSetEntry,56,150 block_count,FindOrderedHashSetEntry,57,150 block_count,FindOrderedHashSetEntry,58,0 @@ -34958,16 +34953,16 @@ block_count,FindOrderedHashSetEntry,81,0 block_count,FindOrderedHashSetEntry,82,0 block_count,FindOrderedHashSetEntry,83,0 -block_count,SetConstructor,0,115 +block_count,SetConstructor,0,114 block_count,SetConstructor,1,0 -block_count,SetConstructor,2,115 -block_count,SetConstructor,3,115 +block_count,SetConstructor,2,114 +block_count,SetConstructor,3,114 block_count,SetConstructor,4,30 block_count,SetConstructor,5,84 -block_count,SetConstructor,6,115 -block_count,SetConstructor,7,115 +block_count,SetConstructor,6,114 +block_count,SetConstructor,7,114 block_count,SetConstructor,8,0 -block_count,SetConstructor,9,115 +block_count,SetConstructor,9,114 block_count,SetConstructor,10,0 block_count,SetConstructor,11,0 block_count,SetConstructor,12,0 @@ -35049,25 +35044,25 @@ block_count,SetConstructor,88,0 block_count,SetConstructor,89,0 block_count,SetConstructor,90,0 -block_count,SetConstructor,91,115 -block_count,SetConstructor,92,115 +block_count,SetConstructor,91,114 +block_count,SetConstructor,92,114 block_count,SetConstructor,93,0 -block_count,SetConstructor,94,115 +block_count,SetConstructor,94,114 block_count,SetConstructor,95,0 block_count,SetConstructor,96,0 -block_count,SetConstructor,97,115 +block_count,SetConstructor,97,114 block_count,SetConstructor,98,0 -block_count,SetConstructor,99,115 -block_count,SetConstructor,100,115 +block_count,SetConstructor,99,114 +block_count,SetConstructor,100,114 block_count,SetConstructor,101,0 block_count,SetConstructor,102,0 block_count,SetConstructor,103,0 block_count,SetConstructor,104,0 -block_count,SetConstructor,105,115 +block_count,SetConstructor,105,114 block_count,SetConstructor,106,0 -block_count,SetConstructor,107,115 -block_count,SetConstructor,108,115 -block_count,SetConstructor,109,115 +block_count,SetConstructor,107,114 +block_count,SetConstructor,108,114 +block_count,SetConstructor,109,114 block_count,SetConstructor,110,22 block_count,SetConstructor,111,0 block_count,SetConstructor,112,22 @@ -35405,9 +35400,9 @@ block_count,SetPrototypeAdd,27,50 block_count,SetPrototypeAdd,28,71 block_count,SetPrototypeAdd,29,71 -block_count,SetPrototypeAdd,30,100 -block_count,SetPrototypeAdd,31,30 -block_count,SetPrototypeAdd,32,29 +block_count,SetPrototypeAdd,30,101 +block_count,SetPrototypeAdd,31,32 +block_count,SetPrototypeAdd,32,30 block_count,SetPrototypeAdd,33,1 block_count,SetPrototypeAdd,34,69 block_count,SetPrototypeAdd,35,0 @@ -35747,8 +35742,8 @@ block_count,StringFromCharCode,14,0 block_count,StringFromCharCode,15,8 block_count,StringFromCharCode,16,8 -block_count,StringFromCharCode,17,881 -block_count,StringFromCharCode,18,881 +block_count,StringFromCharCode,17,880 +block_count,StringFromCharCode,18,880 block_count,StringFromCharCode,19,0 block_count,StringFromCharCode,20,0 block_count,StringFromCharCode,21,0 @@ -35758,8 +35753,8 @@ block_count,StringFromCharCode,25,0 block_count,StringFromCharCode,26,0 block_count,StringFromCharCode,27,0 -block_count,StringFromCharCode,28,881 -block_count,StringFromCharCode,29,881 +block_count,StringFromCharCode,28,880 +block_count,StringFromCharCode,29,880 block_count,StringFromCharCode,30,872 block_count,StringFromCharCode,31,8 block_count,StringFromCharCode,32,0 @@ -36143,16 +36138,16 @@ block_count,TypedArrayPrototypeByteLength,10,0 block_count,TypedArrayPrototypeByteLength,11,0 block_count,TypedArrayPrototypeByteLength,12,0 -block_count,TypedArrayPrototypeLength,0,14 +block_count,TypedArrayPrototypeLength,0,13 block_count,TypedArrayPrototypeLength,1,0 -block_count,TypedArrayPrototypeLength,2,14 -block_count,TypedArrayPrototypeLength,3,14 -block_count,TypedArrayPrototypeLength,4,14 +block_count,TypedArrayPrototypeLength,2,13 +block_count,TypedArrayPrototypeLength,3,13 +block_count,TypedArrayPrototypeLength,4,13 block_count,TypedArrayPrototypeLength,5,0 -block_count,TypedArrayPrototypeLength,6,14 -block_count,TypedArrayPrototypeLength,7,14 -block_count,TypedArrayPrototypeLength,8,14 -block_count,TypedArrayPrototypeLength,9,14 +block_count,TypedArrayPrototypeLength,6,13 +block_count,TypedArrayPrototypeLength,7,13 +block_count,TypedArrayPrototypeLength,8,13 +block_count,TypedArrayPrototypeLength,9,13 block_count,TypedArrayPrototypeLength,10,0 block_count,TypedArrayPrototypeLength,11,0 block_count,TypedArrayPrototypeLength,12,0 @@ -36188,8 +36183,8 @@ block_count,TypedArrayPrototypeLength,42,0 block_count,TypedArrayPrototypeLength,43,0 block_count,TypedArrayPrototypeLength,44,0 -block_count,TypedArrayPrototypeLength,45,14 -block_count,TypedArrayPrototypeLength,46,14 +block_count,TypedArrayPrototypeLength,45,13 +block_count,TypedArrayPrototypeLength,46,13 block_count,TypedArrayPrototypeToStringTag,0,0 block_count,TypedArrayPrototypeToStringTag,1,0 block_count,TypedArrayPrototypeToStringTag,2,0 @@ -36994,9 +36989,9 @@ block_count,WeakMapLookupHashIndex,30,0 block_count,WeakMapLookupHashIndex,31,74 block_count,WeakMapLookupHashIndex,32,74 -block_count,WeakMapLookupHashIndex,33,111 -block_count,WeakMapLookupHashIndex,34,110 -block_count,WeakMapLookupHashIndex,35,37 +block_count,WeakMapLookupHashIndex,33,114 +block_count,WeakMapLookupHashIndex,34,114 +block_count,WeakMapLookupHashIndex,35,40 block_count,WeakMapLookupHashIndex,36,73 block_count,WeakMapLookupHashIndex,37,0 block_count,WeakMapGet,0,38 @@ -37537,26 +37532,26 @@ block_count,AsyncGeneratorYieldWithAwaitResolveClosure,3,8 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,4,0 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,5,8 -block_count,StringAdd_CheckNone,0,8653 -block_count,StringAdd_CheckNone,1,8228 -block_count,StringAdd_CheckNone,2,8180 -block_count,StringAdd_CheckNone,3,8180 -block_count,StringAdd_CheckNone,4,6456 -block_count,StringAdd_CheckNone,5,6428 -block_count,StringAdd_CheckNone,6,28 -block_count,StringAdd_CheckNone,7,6456 -block_count,StringAdd_CheckNone,8,6456 +block_count,StringAdd_CheckNone,0,8649 +block_count,StringAdd_CheckNone,1,8224 +block_count,StringAdd_CheckNone,2,8176 +block_count,StringAdd_CheckNone,3,8176 +block_count,StringAdd_CheckNone,4,6453 +block_count,StringAdd_CheckNone,5,6424 +block_count,StringAdd_CheckNone,6,29 +block_count,StringAdd_CheckNone,7,6453 +block_count,StringAdd_CheckNone,8,6452 block_count,StringAdd_CheckNone,9,0 -block_count,StringAdd_CheckNone,10,6456 +block_count,StringAdd_CheckNone,10,6453 block_count,StringAdd_CheckNone,11,2 -block_count,StringAdd_CheckNone,12,6454 -block_count,StringAdd_CheckNone,13,6456 +block_count,StringAdd_CheckNone,12,6450 +block_count,StringAdd_CheckNone,13,6453 block_count,StringAdd_CheckNone,14,0 -block_count,StringAdd_CheckNone,15,6456 -block_count,StringAdd_CheckNone,16,6456 -block_count,StringAdd_CheckNone,17,1723 -block_count,StringAdd_CheckNone,18,1724 -block_count,StringAdd_CheckNone,19,1724 +block_count,StringAdd_CheckNone,15,6453 +block_count,StringAdd_CheckNone,16,6453 +block_count,StringAdd_CheckNone,17,1722 +block_count,StringAdd_CheckNone,18,1723 +block_count,StringAdd_CheckNone,19,1723 block_count,StringAdd_CheckNone,20,1 block_count,StringAdd_CheckNone,21,1 block_count,StringAdd_CheckNone,22,0 @@ -37581,37 +37576,37 @@ block_count,StringAdd_CheckNone,41,0 block_count,StringAdd_CheckNone,42,0 block_count,StringAdd_CheckNone,43,1 -block_count,StringAdd_CheckNone,44,1722 -block_count,StringAdd_CheckNone,45,1713 -block_count,StringAdd_CheckNone,46,1713 -block_count,StringAdd_CheckNone,47,1713 +block_count,StringAdd_CheckNone,44,1721 +block_count,StringAdd_CheckNone,45,1712 +block_count,StringAdd_CheckNone,46,1712 +block_count,StringAdd_CheckNone,47,1712 block_count,StringAdd_CheckNone,48,0 -block_count,StringAdd_CheckNone,49,1713 +block_count,StringAdd_CheckNone,49,1712 block_count,StringAdd_CheckNone,50,0 block_count,StringAdd_CheckNone,51,0 -block_count,StringAdd_CheckNone,52,1713 +block_count,StringAdd_CheckNone,52,1712 block_count,StringAdd_CheckNone,53,0 -block_count,StringAdd_CheckNone,54,1713 -block_count,StringAdd_CheckNone,55,841 -block_count,StringAdd_CheckNone,56,872 -block_count,StringAdd_CheckNone,57,2010 +block_count,StringAdd_CheckNone,54,1712 +block_count,StringAdd_CheckNone,55,840 +block_count,StringAdd_CheckNone,56,871 +block_count,StringAdd_CheckNone,57,2009 block_count,StringAdd_CheckNone,58,1137 -block_count,StringAdd_CheckNone,59,872 -block_count,StringAdd_CheckNone,60,1713 +block_count,StringAdd_CheckNone,59,871 +block_count,StringAdd_CheckNone,60,1712 block_count,StringAdd_CheckNone,61,359 -block_count,StringAdd_CheckNone,62,1354 -block_count,StringAdd_CheckNone,63,1713 +block_count,StringAdd_CheckNone,62,1353 +block_count,StringAdd_CheckNone,63,1712 block_count,StringAdd_CheckNone,64,0 -block_count,StringAdd_CheckNone,65,1713 +block_count,StringAdd_CheckNone,65,1712 block_count,StringAdd_CheckNone,66,1024 block_count,StringAdd_CheckNone,67,688 block_count,StringAdd_CheckNone,68,1318 -block_count,StringAdd_CheckNone,69,630 +block_count,StringAdd_CheckNone,69,629 block_count,StringAdd_CheckNone,70,688 -block_count,StringAdd_CheckNone,71,1713 +block_count,StringAdd_CheckNone,71,1712 block_count,StringAdd_CheckNone,72,364 -block_count,StringAdd_CheckNone,73,1349 -block_count,StringAdd_CheckNone,74,1713 +block_count,StringAdd_CheckNone,73,1348 +block_count,StringAdd_CheckNone,74,1712 block_count,StringAdd_CheckNone,75,0 block_count,StringAdd_CheckNone,76,9 block_count,StringAdd_CheckNone,77,9 @@ -37650,33 +37645,33 @@ block_count,StringAdd_CheckNone,110,0 block_count,StringAdd_CheckNone,111,0 block_count,StringAdd_CheckNone,112,48 -block_count,StringAdd_CheckNone,113,425 -block_count,SubString,0,1671 -block_count,SubString,1,1439 -block_count,SubString,2,1326 +block_count,StringAdd_CheckNone,113,424 +block_count,SubString,0,1670 +block_count,SubString,1,1438 +block_count,SubString,2,1325 block_count,SubString,3,1053 block_count,SubString,4,197 block_count,SubString,5,395 -block_count,SubString,6,66 -block_count,SubString,7,66 +block_count,SubString,6,65 +block_count,SubString,7,65 block_count,SubString,8,0 -block_count,SubString,9,124 +block_count,SubString,9,123 block_count,SubString,10,7 block_count,SubString,11,197 block_count,SubString,12,0 block_count,SubString,13,197 block_count,SubString,14,0 -block_count,SubString,15,856 +block_count,SubString,15,855 block_count,SubString,16,1053 block_count,SubString,17,457 block_count,SubString,18,1 block_count,SubString,19,0 block_count,SubString,20,1 block_count,SubString,21,1 -block_count,SubString,22,456 +block_count,SubString,22,455 block_count,SubString,23,0 -block_count,SubString,24,456 -block_count,SubString,25,456 +block_count,SubString,24,455 +block_count,SubString,25,455 block_count,SubString,26,596 block_count,SubString,27,596 block_count,SubString,28,21 @@ -37749,7 +37744,7 @@ block_count,SubString,95,574 block_count,SubString,96,0 block_count,SubString,97,574 -block_count,SubString,98,1386 +block_count,SubString,98,1385 block_count,SubString,99,811 block_count,SubString,100,574 block_count,SubString,101,574 @@ -37841,16 +37836,16 @@ block_count,SubString,187,0 block_count,SubString,188,0 block_count,SubString,189,272 -block_count,SubString,190,137 -block_count,SubString,191,274 +block_count,SubString,190,136 +block_count,SubString,191,273 block_count,SubString,192,1 block_count,SubString,193,1 block_count,SubString,194,0 block_count,SubString,195,134 block_count,SubString,196,0 -block_count,SubString,197,137 +block_count,SubString,197,136 block_count,SubString,198,0 -block_count,SubString,199,137 +block_count,SubString,199,136 block_count,SubString,200,0 block_count,SubString,201,0 block_count,SubString,202,0 @@ -37879,7 +37874,7 @@ block_count,GetProperty,0,765 block_count,GetProperty,1,765 block_count,GetProperty,2,0 -block_count,GetProperty,3,765 +block_count,GetProperty,3,764 block_count,GetProperty,4,760 block_count,GetProperty,5,760 block_count,GetProperty,6,760 @@ -37907,21 +37902,21 @@ block_count,GetProperty,28,0 block_count,GetProperty,29,132 block_count,GetProperty,30,760 -block_count,GetProperty,31,1887 -block_count,GetProperty,32,1887 -block_count,GetProperty,33,1886 -block_count,GetProperty,34,1863 +block_count,GetProperty,31,1886 +block_count,GetProperty,32,1886 +block_count,GetProperty,33,1885 +block_count,GetProperty,34,1862 block_count,GetProperty,35,313 block_count,GetProperty,36,313 block_count,GetProperty,37,0 block_count,GetProperty,38,313 -block_count,GetProperty,39,1571 -block_count,GetProperty,40,1571 +block_count,GetProperty,39,1570 +block_count,GetProperty,40,1570 block_count,GetProperty,41,0 -block_count,GetProperty,42,1571 -block_count,GetProperty,43,936 -block_count,GetProperty,44,635 -block_count,GetProperty,45,1571 +block_count,GetProperty,42,1570 +block_count,GetProperty,43,935 +block_count,GetProperty,44,634 +block_count,GetProperty,45,1570 block_count,GetProperty,46,1257 block_count,GetProperty,47,313 block_count,GetProperty,48,313 @@ -37936,29 +37931,29 @@ block_count,GetProperty,57,252 block_count,GetProperty,58,60 block_count,GetProperty,59,0 -block_count,GetProperty,60,1550 +block_count,GetProperty,60,1549 block_count,GetProperty,61,0 -block_count,GetProperty,62,1550 +block_count,GetProperty,62,1549 block_count,GetProperty,63,326 -block_count,GetProperty,64,1223 +block_count,GetProperty,64,1222 block_count,GetProperty,65,3060 block_count,GetProperty,66,2693 block_count,GetProperty,67,2571 -block_count,GetProperty,68,1836 +block_count,GetProperty,68,1837 block_count,GetProperty,69,734 block_count,GetProperty,70,122 block_count,GetProperty,71,366 block_count,GetProperty,72,1061 block_count,GetProperty,73,474 -block_count,GetProperty,74,587 +block_count,GetProperty,74,586 block_count,GetProperty,75,577 block_count,GetProperty,76,9 block_count,GetProperty,77,750 block_count,GetProperty,78,2 block_count,GetProperty,79,748 -block_count,GetProperty,80,735 +block_count,GetProperty,80,734 block_count,GetProperty,81,0 -block_count,GetProperty,82,735 +block_count,GetProperty,82,734 block_count,GetProperty,83,13 block_count,GetProperty,84,0 block_count,GetProperty,85,13 @@ -38010,7 +38005,7 @@ block_count,GetProperty,131,0 block_count,GetProperty,132,0 block_count,GetProperty,133,1136 -block_count,GetProperty,134,1135 +block_count,GetProperty,134,1134 block_count,GetProperty,135,1 block_count,GetProperty,136,0 block_count,GetProperty,137,1 @@ -41570,13 +41565,13 @@ block_count,ArrayIsArray,3,5 block_count,ArrayIsArray,4,5 block_count,ArrayIsArray,5,3 -block_count,ArrayIsArray,6,2 +block_count,ArrayIsArray,6,1 block_count,ArrayIsArray,7,0 -block_count,ArrayIsArray,8,2 +block_count,ArrayIsArray,8,1 block_count,ArrayIsArray,9,0 -block_count,LoadJoinElement_FastSmiOrObjectElements_0,0,742 +block_count,LoadJoinElement_FastSmiOrObjectElements_0,0,741 block_count,LoadJoinElement_FastSmiOrObjectElements_0,1,0 -block_count,LoadJoinElement_FastSmiOrObjectElements_0,2,742 +block_count,LoadJoinElement_FastSmiOrObjectElements_0,2,741 block_count,LoadJoinElement_FastSmiOrObjectElements_0,3,740 block_count,LoadJoinElement_FastSmiOrObjectElements_0,4,1 block_count,LoadJoinElement_FastDoubleElements_0,0,103 @@ -41808,7 +41803,7 @@ block_count,ArrayPrototypeJoin,163,0 block_count,ArrayPrototypeJoin,164,0 block_count,ArrayPrototypeJoin,165,183 -block_count,ArrayPrototypeJoin,166,1029 +block_count,ArrayPrototypeJoin,166,1028 block_count,ArrayPrototypeJoin,167,845 block_count,ArrayPrototypeJoin,168,845 block_count,ArrayPrototypeJoin,169,845 @@ -41837,7 +41832,7 @@ block_count,ArrayPrototypeJoin,192,845 block_count,ArrayPrototypeJoin,193,845 block_count,ArrayPrototypeJoin,194,639 -block_count,ArrayPrototypeJoin,195,511 +block_count,ArrayPrototypeJoin,195,510 block_count,ArrayPrototypeJoin,196,509 block_count,ArrayPrototypeJoin,197,1 block_count,ArrayPrototypeJoin,198,128 @@ -42120,7 +42115,7 @@ block_count,ArrayPrototypeJoin,475,0 block_count,ArrayPrototypeJoin,476,0 block_count,ArrayPrototypeJoin,477,0 -block_count,ArrayPrototypeJoin,478,310 +block_count,ArrayPrototypeJoin,478,309 block_count,ArrayPrototypeJoin,479,334 block_count,ArrayPrototypeJoin,480,844 block_count,ArrayPrototypeJoin,481,661 @@ -42178,7 +42173,7 @@ block_count,ArrayPrototypeJoin,533,844 block_count,ArrayPrototypeJoin,534,844 block_count,ArrayPrototypeJoin,535,844 -block_count,ArrayPrototypeJoin,536,822 +block_count,ArrayPrototypeJoin,536,821 block_count,ArrayPrototypeJoin,537,0 block_count,ArrayPrototypeJoin,538,0 block_count,ArrayPrototypeJoin,539,0 @@ -42206,10 +42201,10 @@ block_count,ArrayPrototypeJoin,561,0 block_count,ArrayPrototypeJoin,562,0 block_count,ArrayPrototypeJoin,563,0 -block_count,ArrayPrototypeJoin,564,822 -block_count,ArrayPrototypeJoin,565,822 +block_count,ArrayPrototypeJoin,564,821 +block_count,ArrayPrototypeJoin,565,821 block_count,ArrayPrototypeJoin,566,0 -block_count,ArrayPrototypeJoin,567,822 +block_count,ArrayPrototypeJoin,567,821 block_count,ArrayPrototypeJoin,568,22 block_count,ArrayPrototypeJoin,569,22 block_count,ArrayPrototypeJoin,570,21 @@ -42308,11 +42303,11 @@ block_count,ArrayPrototypeJoin,663,0 block_count,ArrayPrototypeJoin,664,0 block_count,ArrayPrototypeJoin,665,0 -block_count,ArrayPrototypeJoin,666,183 -block_count,ArrayPrototypeJoin,667,183 +block_count,ArrayPrototypeJoin,666,182 +block_count,ArrayPrototypeJoin,667,182 block_count,ArrayPrototypeJoin,668,182 block_count,ArrayPrototypeJoin,669,0 -block_count,ArrayPrototypeJoin,670,183 +block_count,ArrayPrototypeJoin,670,182 block_count,ArrayPrototypeJoin,671,156 block_count,ArrayPrototypeJoin,672,38 block_count,ArrayPrototypeJoin,673,38 @@ -44174,9 +44169,9 @@ block_count,ArrayPrototypeSlice,156,0 block_count,ArrayPrototypeSlice,157,0 block_count,ArrayPrototypeSlice,158,27 -block_count,ArrayPrototypeSlice,159,13 +block_count,ArrayPrototypeSlice,159,12 block_count,ArrayPrototypeSlice,160,0 -block_count,ArrayPrototypeSlice,161,13 +block_count,ArrayPrototypeSlice,161,12 block_count,ArrayPrototypeSlice,162,2 block_count,ArrayPrototypeSlice,163,10 block_count,ArrayPrototypeSlice,164,14 @@ -44198,7 +44193,7 @@ block_count,ArrayPrototypeSlice,180,0 block_count,ArrayPrototypeSlice,181,2 block_count,ArrayPrototypeSlice,182,10 -block_count,ArrayPrototypeSlice,183,13 +block_count,ArrayPrototypeSlice,183,12 block_count,ArrayPrototypeSlice,184,14 block_count,ArrayPrototypeSlice,185,14 block_count,ArrayPrototypeSlice,186,14 @@ -45100,10 +45095,10 @@ block_count,ArrayPrototypeSplice,521,0 block_count,ArrayPrototypeSplice,522,2 block_count,ArrayPrototypeSplice,523,638 -block_count,ArrayPrototypeSplice,524,636 +block_count,ArrayPrototypeSplice,524,635 block_count,ArrayPrototypeSplice,525,219 block_count,ArrayPrototypeSplice,526,416 -block_count,ArrayPrototypeSplice,527,636 +block_count,ArrayPrototypeSplice,527,635 block_count,ArrayPrototypeSplice,528,2 block_count,ArrayPrototypeSplice,529,0 block_count,ArrayPrototypeSplice,530,0 @@ -45818,21 +45813,21 @@ block_count,StringPrototypeToString,7,19 block_count,StringPrototypeToString,8,0 block_count,StringPrototypeToString,9,19 -block_count,StringPrototypeCharAt,0,124 +block_count,StringPrototypeCharAt,0,123 block_count,StringPrototypeCharAt,1,0 -block_count,StringPrototypeCharAt,2,124 -block_count,StringPrototypeCharAt,3,124 -block_count,StringPrototypeCharAt,4,124 +block_count,StringPrototypeCharAt,2,123 +block_count,StringPrototypeCharAt,3,123 +block_count,StringPrototypeCharAt,4,123 block_count,StringPrototypeCharAt,5,0 block_count,StringPrototypeCharAt,6,0 block_count,StringPrototypeCharAt,7,0 -block_count,StringPrototypeCharAt,8,124 +block_count,StringPrototypeCharAt,8,123 block_count,StringPrototypeCharAt,9,0 -block_count,StringPrototypeCharAt,10,124 -block_count,StringPrototypeCharAt,11,124 +block_count,StringPrototypeCharAt,10,123 +block_count,StringPrototypeCharAt,11,123 block_count,StringPrototypeCharAt,12,0 -block_count,StringPrototypeCharAt,13,124 -block_count,StringPrototypeCharAt,14,124 +block_count,StringPrototypeCharAt,13,123 +block_count,StringPrototypeCharAt,14,123 block_count,StringPrototypeCharAt,15,121 block_count,StringPrototypeCharAt,16,67 block_count,StringPrototypeCharAt,17,135 @@ -45866,32 +45861,32 @@ block_count,StringPrototypeCharAt,45,0 block_count,StringPrototypeCharAt,46,121 block_count,StringPrototypeCharAt,47,2 -block_count,StringPrototypeCharCodeAt,0,117 +block_count,StringPrototypeCharCodeAt,0,116 block_count,StringPrototypeCharCodeAt,1,0 -block_count,StringPrototypeCharCodeAt,2,117 -block_count,StringPrototypeCharCodeAt,3,117 -block_count,StringPrototypeCharCodeAt,4,117 +block_count,StringPrototypeCharCodeAt,2,116 +block_count,StringPrototypeCharCodeAt,3,116 +block_count,StringPrototypeCharCodeAt,4,116 block_count,StringPrototypeCharCodeAt,5,0 block_count,StringPrototypeCharCodeAt,6,0 block_count,StringPrototypeCharCodeAt,7,0 -block_count,StringPrototypeCharCodeAt,8,117 +block_count,StringPrototypeCharCodeAt,8,116 block_count,StringPrototypeCharCodeAt,9,0 -block_count,StringPrototypeCharCodeAt,10,117 -block_count,StringPrototypeCharCodeAt,11,117 +block_count,StringPrototypeCharCodeAt,10,116 +block_count,StringPrototypeCharCodeAt,11,116 block_count,StringPrototypeCharCodeAt,12,0 -block_count,StringPrototypeCharCodeAt,13,117 -block_count,StringPrototypeCharCodeAt,14,117 -block_count,StringPrototypeCharCodeAt,15,117 -block_count,StringPrototypeCharCodeAt,16,41 -block_count,StringPrototypeCharCodeAt,17,83 -block_count,StringPrototypeCharCodeAt,18,40 -block_count,StringPrototypeCharCodeAt,19,40 +block_count,StringPrototypeCharCodeAt,13,116 +block_count,StringPrototypeCharCodeAt,14,116 +block_count,StringPrototypeCharCodeAt,15,116 +block_count,StringPrototypeCharCodeAt,16,26 +block_count,StringPrototypeCharCodeAt,17,53 +block_count,StringPrototypeCharCodeAt,18,25 +block_count,StringPrototypeCharCodeAt,19,25 block_count,StringPrototypeCharCodeAt,20,0 block_count,StringPrototypeCharCodeAt,21,1 block_count,StringPrototypeCharCodeAt,22,0 -block_count,StringPrototypeCharCodeAt,23,41 +block_count,StringPrototypeCharCodeAt,23,26 block_count,StringPrototypeCharCodeAt,24,0 -block_count,StringPrototypeCharCodeAt,25,41 +block_count,StringPrototypeCharCodeAt,25,26 block_count,StringPrototypeCharCodeAt,26,0 block_count,StringPrototypeCharCodeAt,27,0 block_count,StringPrototypeCharCodeAt,28,0 @@ -45902,9 +45897,9 @@ block_count,StringPrototypeCharCodeAt,33,0 block_count,StringPrototypeCharCodeAt,34,0 block_count,StringPrototypeCharCodeAt,35,0 -block_count,StringPrototypeCharCodeAt,36,75 -block_count,StringPrototypeCharCodeAt,37,117 -block_count,StringPrototypeCharCodeAt,38,117 +block_count,StringPrototypeCharCodeAt,36,90 +block_count,StringPrototypeCharCodeAt,37,116 +block_count,StringPrototypeCharCodeAt,38,116 block_count,StringPrototypeCharCodeAt,39,18 block_count,StringPrototypeCharCodeAt,40,98 block_count,StringPrototypeCharCodeAt,41,0 @@ -46291,7 +46286,7 @@ block_count,StringAddConvertRight,6,200 block_count,StringAddConvertRight,7,200 block_count,StringAddConvertRight,8,186 -block_count,StringAddConvertRight,9,186 +block_count,StringAddConvertRight,9,185 block_count,StringAddConvertRight,10,0 block_count,StringAddConvertRight,11,0 block_count,StringAddConvertRight,12,0 @@ -46386,7 +46381,7 @@ block_count,StringAddConvertRight,101,0 block_count,StringAddConvertRight,102,0 block_count,StringAddConvertRight,103,0 -block_count,StringAddConvertRight,104,186 +block_count,StringAddConvertRight,104,185 block_count,StringAddConvertRight,105,0 block_count,StringAddConvertRight,106,0 block_count,StringAddConvertRight,107,0 @@ -46408,7 +46403,7 @@ block_count,StringAddConvertRight,123,0 block_count,StringAddConvertRight,124,14 block_count,StringAddConvertRight,125,14 -block_count,StringAddConvertRight,126,14 +block_count,StringAddConvertRight,126,13 block_count,StringAddConvertRight,127,0 block_count,StringAddConvertRight,128,0 block_count,StringAddConvertRight,129,0 @@ -46489,35 +46484,35 @@ block_count,StringCharAt,29,0 block_count,StringCharAt,30,0 block_count,StringCharAt,31,9 -block_count,FastNewClosureBaseline,0,87 -block_count,FastNewFunctionContextFunction,0,93 -block_count,FastNewFunctionContextFunction,1,93 +block_count,FastNewClosureBaseline,0,88 +block_count,FastNewFunctionContextFunction,0,94 +block_count,FastNewFunctionContextFunction,1,94 block_count,FastNewFunctionContextFunction,2,0 -block_count,FastNewFunctionContextFunction,3,93 +block_count,FastNewFunctionContextFunction,3,94 block_count,FastNewFunctionContextFunction,4,0 block_count,FastNewFunctionContextFunction,5,0 -block_count,FastNewFunctionContextFunction,6,93 +block_count,FastNewFunctionContextFunction,6,94 block_count,FastNewFunctionContextFunction,7,0 -block_count,FastNewFunctionContextFunction,8,93 +block_count,FastNewFunctionContextFunction,8,94 block_count,FastNewFunctionContextFunction,9,0 -block_count,FastNewFunctionContextFunction,10,93 -block_count,FastNewFunctionContextFunction,11,25 +block_count,FastNewFunctionContextFunction,10,94 +block_count,FastNewFunctionContextFunction,11,27 block_count,FastNewFunctionContextFunction,12,67 -block_count,FastNewFunctionContextFunction,13,909 -block_count,FastNewFunctionContextFunction,14,841 +block_count,FastNewFunctionContextFunction,13,908 +block_count,FastNewFunctionContextFunction,14,840 block_count,FastNewFunctionContextFunction,15,67 -block_count,FastNewFunctionContextFunction,16,93 +block_count,FastNewFunctionContextFunction,16,94 block_count,FastNewFunctionContextFunction,17,57 -block_count,FastNewFunctionContextFunction,18,36 -block_count,CreateRegExpLiteral,0,41 -block_count,CreateRegExpLiteral,1,41 +block_count,FastNewFunctionContextFunction,18,37 +block_count,CreateRegExpLiteral,0,43 +block_count,CreateRegExpLiteral,1,43 block_count,CreateRegExpLiteral,2,0 -block_count,CreateRegExpLiteral,3,41 +block_count,CreateRegExpLiteral,3,43 block_count,CreateRegExpLiteral,4,0 -block_count,CreateRegExpLiteral,5,41 -block_count,CreateRegExpLiteral,6,41 +block_count,CreateRegExpLiteral,5,43 +block_count,CreateRegExpLiteral,6,43 block_count,CreateRegExpLiteral,7,0 -block_count,CreateRegExpLiteral,8,41 +block_count,CreateRegExpLiteral,8,43 block_count,CreateRegExpLiteral,9,0 block_count,CreateRegExpLiteral,10,0 block_count,CreateShallowArrayLiteral,0,20 @@ -46612,8 +46607,8 @@ block_count,CreateEmptyArrayLiteral,9,0 block_count,CreateEmptyArrayLiteral,10,29 block_count,CreateEmptyArrayLiteral,11,29 -block_count,CreateShallowObjectLiteral,0,32 -block_count,CreateShallowObjectLiteral,1,32 +block_count,CreateShallowObjectLiteral,0,31 +block_count,CreateShallowObjectLiteral,1,31 block_count,CreateShallowObjectLiteral,2,0 block_count,CreateShallowObjectLiteral,3,31 block_count,CreateShallowObjectLiteral,4,31 @@ -46741,7 +46736,7 @@ block_count,CreateShallowObjectLiteral,126,0 block_count,CreateShallowObjectLiteral,127,31 block_count,CreateShallowObjectLiteral,128,31 -block_count,CreateShallowObjectLiteral,129,91 +block_count,CreateShallowObjectLiteral,129,90 block_count,CreateShallowObjectLiteral,130,82 block_count,CreateShallowObjectLiteral,131,0 block_count,CreateShallowObjectLiteral,132,0 @@ -46769,11 +46764,11 @@ block_count,CreateShallowObjectLiteral,154,0 block_count,CreateShallowObjectLiteral,155,0 block_count,CreateShallowObjectLiteral,156,0 -block_count,CreateShallowObjectLiteral,157,82 +block_count,CreateShallowObjectLiteral,157,81 block_count,CreateShallowObjectLiteral,158,8 -block_count,CreateShallowObjectLiteral,159,91 +block_count,CreateShallowObjectLiteral,159,90 block_count,CreateShallowObjectLiteral,160,59 -block_count,CreateShallowObjectLiteral,161,31 +block_count,CreateShallowObjectLiteral,161,30 block_count,CreateShallowObjectLiteral,162,0 block_count,CreateShallowObjectLiteral,163,0 block_count,CreateShallowObjectLiteral,164,0 @@ -46900,11 +46895,11 @@ block_count,NonNumberToNumeric,9,0 block_count,NonNumberToNumeric,10,0 block_count,NonNumberToNumeric,11,1016 -block_count,NonNumberToNumeric,12,1011 +block_count,NonNumberToNumeric,12,1010 block_count,NonNumberToNumeric,13,0 block_count,NonNumberToNumeric,14,0 block_count,NonNumberToNumeric,15,0 -block_count,NonNumberToNumeric,16,1011 +block_count,NonNumberToNumeric,16,1010 block_count,NonNumberToNumeric,17,5 block_count,NonNumberToNumeric,18,2 block_count,NonNumberToNumeric,19,2 @@ -46936,7 +46931,7 @@ block_count,NumberToString,19,6 block_count,NumberToString,20,1478 block_count,NumberToString,21,1478 -block_count,NumberToString,22,1478 +block_count,NumberToString,22,1477 block_count,NumberToString,23,0 block_count,NumberToString,24,0 block_count,NumberToString,25,0 @@ -46982,10 +46977,10 @@ block_count,NumberToString,65,0 block_count,NumberToString,66,0 block_count,NumberToString,67,0 -block_count,NumberToString,68,1511 +block_count,NumberToString,68,1510 block_count,NumberToString,69,15 block_count,ToBoolean,0,36 -block_count,ToBoolean,1,35 +block_count,ToBoolean,1,36 block_count,ToBoolean,2,26 block_count,ToBoolean,3,25 block_count,ToBoolean,4,25 @@ -46998,7 +46993,7 @@ block_count,ToBoolean,11,0 block_count,ToBoolean,12,0 block_count,ToBoolean,13,0 -block_count,ToBoolean,14,22 +block_count,ToBoolean,14,23 block_count,ToBoolean,15,0 block_count,ToBoolean,16,1 block_count,ToBoolean,17,9 @@ -47008,9 +47003,9 @@ block_count,ToBooleanForBaselineJump,0,1091 block_count,ToBooleanForBaselineJump,1,1007 block_count,ToBooleanForBaselineJump,2,612 -block_count,ToBooleanForBaselineJump,3,384 -block_count,ToBooleanForBaselineJump,4,384 -block_count,ToBooleanForBaselineJump,5,185 +block_count,ToBooleanForBaselineJump,3,386 +block_count,ToBooleanForBaselineJump,4,385 +block_count,ToBooleanForBaselineJump,5,186 block_count,ToBooleanForBaselineJump,6,184 block_count,ToBooleanForBaselineJump,7,184 block_count,ToBooleanForBaselineJump,8,0 @@ -47019,12 +47014,12 @@ block_count,ToBooleanForBaselineJump,11,1 block_count,ToBooleanForBaselineJump,12,0 block_count,ToBooleanForBaselineJump,13,1 -block_count,ToBooleanForBaselineJump,14,198 +block_count,ToBooleanForBaselineJump,14,199 block_count,ToBooleanForBaselineJump,15,0 -block_count,ToBooleanForBaselineJump,16,228 +block_count,ToBooleanForBaselineJump,16,226 block_count,ToBooleanForBaselineJump,17,394 block_count,ToBooleanForBaselineJump,18,84 -block_count,ToBooleanForBaselineJump,19,51 +block_count,ToBooleanForBaselineJump,19,52 block_count,ToBooleanForBaselineJump,20,32 block_count,ToLength,0,2 block_count,ToLength,1,2 @@ -47075,10 +47070,10 @@ block_count,ToName,0,48 block_count,ToName,1,91 block_count,ToName,2,89 -block_count,ToName,3,43 -block_count,ToName,4,43 -block_count,ToName,5,43 -block_count,ToName,6,43 +block_count,ToName,3,42 +block_count,ToName,4,42 +block_count,ToName,5,42 +block_count,ToName,6,42 block_count,ToName,7,0 block_count,ToName,8,0 block_count,ToName,9,0 @@ -47206,7 +47201,7 @@ block_count,ToObject,53,0 block_count,ToObject,54,0 block_count,NonPrimitiveToPrimitive_Default,0,181 -block_count,NonPrimitiveToPrimitive_Default,1,850 +block_count,NonPrimitiveToPrimitive_Default,1,849 block_count,NonPrimitiveToPrimitive_Default,2,668 block_count,NonPrimitiveToPrimitive_Default,3,668 block_count,NonPrimitiveToPrimitive_Default,4,0 @@ -47281,10 +47276,10 @@ block_count,NonPrimitiveToPrimitive_Number,35,0 block_count,NonPrimitiveToPrimitive_Number,36,43 block_count,NonPrimitiveToPrimitive_Number,37,14 -block_count,NonPrimitiveToPrimitive_String,0,43 -block_count,NonPrimitiveToPrimitive_String,1,172 -block_count,NonPrimitiveToPrimitive_String,2,129 -block_count,NonPrimitiveToPrimitive_String,3,129 +block_count,NonPrimitiveToPrimitive_String,0,42 +block_count,NonPrimitiveToPrimitive_String,1,171 +block_count,NonPrimitiveToPrimitive_String,2,128 +block_count,NonPrimitiveToPrimitive_String,3,128 block_count,NonPrimitiveToPrimitive_String,4,0 block_count,NonPrimitiveToPrimitive_String,5,0 block_count,NonPrimitiveToPrimitive_String,6,0 @@ -47316,18 +47311,18 @@ block_count,NonPrimitiveToPrimitive_String,32,0 block_count,NonPrimitiveToPrimitive_String,33,0 block_count,NonPrimitiveToPrimitive_String,34,0 -block_count,NonPrimitiveToPrimitive_String,35,129 -block_count,NonPrimitiveToPrimitive_String,36,43 -block_count,NonPrimitiveToPrimitive_String,37,43 -block_count,NonPrimitiveToPrimitive_String,38,43 +block_count,NonPrimitiveToPrimitive_String,35,128 +block_count,NonPrimitiveToPrimitive_String,36,42 +block_count,NonPrimitiveToPrimitive_String,37,42 +block_count,NonPrimitiveToPrimitive_String,38,42 block_count,NonPrimitiveToPrimitive_String,39,0 -block_count,NonPrimitiveToPrimitive_String,40,43 +block_count,NonPrimitiveToPrimitive_String,40,42 block_count,NonPrimitiveToPrimitive_String,41,0 -block_count,NonPrimitiveToPrimitive_String,42,43 +block_count,NonPrimitiveToPrimitive_String,42,42 block_count,NonPrimitiveToPrimitive_String,43,0 -block_count,NonPrimitiveToPrimitive_String,44,43 -block_count,NonPrimitiveToPrimitive_String,45,43 -block_count,NonPrimitiveToPrimitive_String,46,43 +block_count,NonPrimitiveToPrimitive_String,44,42 +block_count,NonPrimitiveToPrimitive_String,45,42 +block_count,NonPrimitiveToPrimitive_String,46,42 block_count,NonPrimitiveToPrimitive_String,47,0 block_count,NonPrimitiveToPrimitive_String,48,0 block_count,NonPrimitiveToPrimitive_String,49,0 @@ -47340,7 +47335,7 @@ block_count,NonPrimitiveToPrimitive_String,56,0 block_count,NonPrimitiveToPrimitive_String,57,0 block_count,NonPrimitiveToPrimitive_String,58,0 -block_count,NonPrimitiveToPrimitive_String,59,43 +block_count,NonPrimitiveToPrimitive_String,59,42 block_count,NonPrimitiveToPrimitive_String,60,0 block_count,NonPrimitiveToPrimitive_String,61,0 block_count,NonPrimitiveToPrimitive_String,62,0 @@ -47367,7 +47362,7 @@ block_count,NonPrimitiveToPrimitive_String,83,0 block_count,NonPrimitiveToPrimitive_String,84,0 block_count,NonPrimitiveToPrimitive_String,85,0 -block_count,NonPrimitiveToPrimitive_String,86,43 +block_count,NonPrimitiveToPrimitive_String,86,42 block_count,OrdinaryToPrimitive_Number,0,0 block_count,OrdinaryToPrimitive_Number_Inline,0,196 block_count,OrdinaryToPrimitive_Number_Inline,1,196 @@ -47798,17 +47793,17 @@ block_count,FunctionPrototypeHasInstance,16,0 block_count,FunctionPrototypeHasInstance,17,84 block_count,FunctionPrototypeHasInstance,18,89 -block_count,FunctionPrototypeHasInstance,19,291 -block_count,FunctionPrototypeHasInstance,20,284 +block_count,FunctionPrototypeHasInstance,19,292 +block_count,FunctionPrototypeHasInstance,20,285 block_count,FunctionPrototypeHasInstance,21,6 block_count,FunctionPrototypeHasInstance,22,6 block_count,FunctionPrototypeHasInstance,23,6 block_count,FunctionPrototypeHasInstance,24,0 block_count,FunctionPrototypeHasInstance,25,0 block_count,FunctionPrototypeHasInstance,26,0 -block_count,FunctionPrototypeHasInstance,27,291 -block_count,FunctionPrototypeHasInstance,28,237 -block_count,FunctionPrototypeHasInstance,29,202 +block_count,FunctionPrototypeHasInstance,27,292 +block_count,FunctionPrototypeHasInstance,28,238 +block_count,FunctionPrototypeHasInstance,29,203 block_count,FunctionPrototypeHasInstance,30,35 block_count,FunctionPrototypeHasInstance,31,53 block_count,FunctionPrototypeHasInstance,32,89 @@ -48049,7 +48044,7 @@ block_count,MathFloor,15,0 block_count,MathFloor,16,3 block_count,MathFloor,17,3 -block_count,MathFloor,18,1 +block_count,MathFloor,18,2 block_count,MathFloor,19,1 block_count,MathFloor,20,0 block_count,MathFloor,21,3 @@ -48555,9 +48550,9 @@ block_count,NumberPrototypeToString,33,0 block_count,NumberPrototypeToString,34,0 block_count,NumberPrototypeToString,35,80 -block_count,NumberPrototypeToString,36,78 +block_count,NumberPrototypeToString,36,77 block_count,NumberPrototypeToString,37,2 -block_count,NumberPrototypeToString,38,78 +block_count,NumberPrototypeToString,38,77 block_count,NumberPrototypeToString,39,0 block_count,NumberPrototypeToString,40,0 block_count,NumberPrototypeToString,41,0 @@ -48742,7 +48737,7 @@ block_count,NumberParseFloat,14,3 block_count,NumberParseFloat,15,0 block_count,NumberParseFloat,16,3 -block_count,ParseInt,0,136 +block_count,ParseInt,0,135 block_count,ParseInt,1,69 block_count,ParseInt,2,66 block_count,ParseInt,3,66 @@ -48777,7 +48772,7 @@ block_count,NumberParseInt,1,0 block_count,NumberParseInt,2,6 block_count,Add,0,13 -block_count,Add,1,14 +block_count,Add,1,13 block_count,Add,2,0 block_count,Add,3,0 block_count,Add,4,0 @@ -48798,7 +48793,7 @@ block_count,Add,19,0 block_count,Add,20,0 block_count,Add,21,0 -block_count,Add,22,14 +block_count,Add,22,13 block_count,Add,23,0 block_count,Add,24,0 block_count,Add,25,0 @@ -48817,8 +48812,8 @@ block_count,Add,38,0 block_count,Add,39,0 block_count,Add,40,0 -block_count,Add,41,14 -block_count,Add,42,14 +block_count,Add,41,13 +block_count,Add,42,13 block_count,Add,43,0 block_count,Add,44,0 block_count,Add,45,0 @@ -48835,7 +48830,7 @@ block_count,Add,56,0 block_count,Add,57,0 block_count,Add,58,0 -block_count,Add,59,13 +block_count,Add,59,12 block_count,Add,60,0 block_count,Add,61,0 block_count,Add,62,0 @@ -49072,7 +49067,7 @@ block_count,LessThan,0,769 block_count,LessThan,1,1295 block_count,LessThan,2,1261 -block_count,LessThan,3,1261 +block_count,LessThan,3,1260 block_count,LessThan,4,10 block_count,LessThan,5,10 block_count,LessThan,6,3 @@ -49092,9 +49087,9 @@ block_count,LessThan,20,0 block_count,LessThan,21,0 block_count,LessThan,22,0 -block_count,LessThan,23,1251 -block_count,LessThan,24,519 -block_count,LessThan,25,519 +block_count,LessThan,23,1250 +block_count,LessThan,24,518 +block_count,LessThan,25,518 block_count,LessThan,26,0 block_count,LessThan,27,731 block_count,LessThan,28,0 @@ -49111,14 +49106,14 @@ block_count,LessThan,39,0 block_count,LessThan,40,0 block_count,LessThan,41,0 -block_count,LessThan,42,526 -block_count,LessThan,43,765 +block_count,LessThan,42,525 +block_count,LessThan,43,764 block_count,LessThan,44,631 block_count,LessThan,45,133 block_count,LessThan,46,631 block_count,LessThan,47,134 block_count,GreaterThan,0,668 -block_count,GreaterThan,1,1159 +block_count,GreaterThan,1,1158 block_count,GreaterThan,2,1140 block_count,GreaterThan,3,1036 block_count,GreaterThan,4,16 @@ -49140,7 +49135,7 @@ block_count,GreaterThan,20,0 block_count,GreaterThan,21,0 block_count,GreaterThan,22,0 -block_count,GreaterThan,23,1020 +block_count,GreaterThan,23,1019 block_count,GreaterThan,24,474 block_count,GreaterThan,25,474 block_count,GreaterThan,26,0 @@ -49159,11 +49154,11 @@ block_count,GreaterThan,39,1 block_count,GreaterThan,40,0 block_count,GreaterThan,41,0 -block_count,GreaterThan,42,491 -block_count,GreaterThan,43,667 +block_count,GreaterThan,42,490 +block_count,GreaterThan,43,666 block_count,GreaterThan,44,631 block_count,GreaterThan,45,35 -block_count,GreaterThan,46,632 +block_count,GreaterThan,46,631 block_count,GreaterThan,47,36 block_count,GreaterThanOrEqual,0,3 block_count,GreaterThanOrEqual,1,10 @@ -49266,7 +49261,7 @@ block_count,Equal,55,3 block_count,Equal,56,19 block_count,Equal,57,41 -block_count,Equal,58,62 +block_count,Equal,58,61 block_count,Equal,59,61 block_count,Equal,60,34 block_count,Equal,61,4 @@ -49296,8 +49291,8 @@ block_count,Equal,85,2 block_count,Equal,86,46 block_count,StrictEqual,0,1522 -block_count,StrictEqual,1,1353 -block_count,StrictEqual,2,1321 +block_count,StrictEqual,1,1352 +block_count,StrictEqual,2,1320 block_count,StrictEqual,3,1272 block_count,StrictEqual,4,1244 block_count,StrictEqual,5,187 @@ -49307,7 +49302,7 @@ block_count,StrictEqual,9,0 block_count,StrictEqual,10,1056 block_count,StrictEqual,11,50 -block_count,StrictEqual,12,1006 +block_count,StrictEqual,12,1005 block_count,StrictEqual,13,580 block_count,StrictEqual,14,425 block_count,StrictEqual,15,27 @@ -50791,7 +50786,7 @@ block_count,RegExpPrototypeExec,54,0 block_count,RegExpPrototypeExec,55,0 block_count,RegExpPrototypeExec,56,0 -block_count,RegExpPrototypeExec,57,384 +block_count,RegExpPrototypeExec,57,383 block_count,RegExpPrototypeExec,58,396 block_count,RegExpPrototypeExec,59,396 block_count,RegExpPrototypeExec,60,0 @@ -50858,8 +50853,8 @@ block_count,RegExpPrototypeExec,121,150 block_count,RegExpPrototypeExec,122,0 block_count,RegExpPrototypeExec,123,150 -block_count,RegExpPrototypeExec,124,246 -block_count,RegExpPrototypeExec,125,246 +block_count,RegExpPrototypeExec,124,245 +block_count,RegExpPrototypeExec,125,245 block_count,RegExpPrototypeExec,126,0 block_count,RegExpPrototypeExec,127,0 block_count,RegExpPrototypeExec,128,0 @@ -50880,7 +50875,7 @@ block_count,RegExpPrototypeExec,143,1 block_count,RegExpPrototypeExec,144,2 block_count,RegExpPrototypeExec,145,1 -block_count,RegExpPrototypeExec,146,1 +block_count,RegExpPrototypeExec,146,0 block_count,RegExpPrototypeExec,147,0 block_count,RegExpPrototypeExec,148,0 block_count,RegExpPrototypeExec,149,0 @@ -51057,18 +51052,18 @@ block_count,RegExpPrototypeExec,320,172 block_count,RegExpPrototypeExec,321,74 block_count,RegExpPrototypeExec,322,97 -block_count,RegExpPrototypeExec,323,471 +block_count,RegExpPrototypeExec,323,470 block_count,RegExpPrototypeExec,324,373 block_count,RegExpPrototypeExec,325,97 block_count,RegExpPrototypeExec,326,172 -block_count,RegExpPrototypeExec,327,84 +block_count,RegExpPrototypeExec,327,83 block_count,RegExpPrototypeExec,328,88 block_count,RegExpPrototypeExec,329,172 block_count,RegExpPrototypeExec,330,97 -block_count,RegExpPrototypeExec,331,858 +block_count,RegExpPrototypeExec,331,857 block_count,RegExpPrototypeExec,332,351 -block_count,RegExpPrototypeExec,333,506 -block_count,RegExpPrototypeExec,334,858 +block_count,RegExpPrototypeExec,333,505 +block_count,RegExpPrototypeExec,334,857 block_count,RegExpPrototypeExec,335,760 block_count,RegExpPrototypeExec,336,97 block_count,RegExpPrototypeExec,337,0 @@ -51183,7 +51178,7 @@ block_count,RegExpPrototypeExec,446,172 block_count,RegExpPrototypeExec,447,251 block_count,RegExpPrototypeExec,448,423 -block_count,RegExpMatchFast,0,1252 +block_count,RegExpMatchFast,0,1251 block_count,RegExpMatchFast,1,2 block_count,RegExpMatchFast,2,0 block_count,RegExpMatchFast,3,0 @@ -51650,27 +51645,27 @@ block_count,RegExpMatchFast,464,0 block_count,RegExpMatchFast,465,1 block_count,RegExpMatchFast,466,1 -block_count,RegExpMatchFast,467,1249 -block_count,RegExpMatchFast,468,1249 -block_count,RegExpMatchFast,469,1249 +block_count,RegExpMatchFast,467,1248 +block_count,RegExpMatchFast,468,1248 +block_count,RegExpMatchFast,469,1248 block_count,RegExpMatchFast,470,0 -block_count,RegExpMatchFast,471,1249 -block_count,RegExpMatchFast,472,1249 -block_count,RegExpMatchFast,473,1249 +block_count,RegExpMatchFast,471,1248 +block_count,RegExpMatchFast,472,1248 +block_count,RegExpMatchFast,473,1248 block_count,RegExpMatchFast,474,0 block_count,RegExpMatchFast,475,0 block_count,RegExpMatchFast,476,0 -block_count,RegExpMatchFast,477,1249 -block_count,RegExpMatchFast,478,1092 -block_count,RegExpMatchFast,479,2184 +block_count,RegExpMatchFast,477,1248 +block_count,RegExpMatchFast,478,1091 +block_count,RegExpMatchFast,479,2183 block_count,RegExpMatchFast,480,0 block_count,RegExpMatchFast,481,0 block_count,RegExpMatchFast,482,0 -block_count,RegExpMatchFast,483,1071 +block_count,RegExpMatchFast,483,1070 block_count,RegExpMatchFast,484,20 -block_count,RegExpMatchFast,485,1092 +block_count,RegExpMatchFast,485,1091 block_count,RegExpMatchFast,486,0 -block_count,RegExpMatchFast,487,1092 +block_count,RegExpMatchFast,487,1091 block_count,RegExpMatchFast,488,0 block_count,RegExpMatchFast,489,0 block_count,RegExpMatchFast,490,0 @@ -51691,24 +51686,24 @@ block_count,RegExpMatchFast,505,0 block_count,RegExpMatchFast,506,0 block_count,RegExpMatchFast,507,157 -block_count,RegExpMatchFast,508,1249 -block_count,RegExpMatchFast,509,1249 +block_count,RegExpMatchFast,508,1248 +block_count,RegExpMatchFast,509,1248 block_count,RegExpMatchFast,510,0 -block_count,RegExpMatchFast,511,1249 +block_count,RegExpMatchFast,511,1248 block_count,RegExpMatchFast,512,0 block_count,RegExpMatchFast,513,0 block_count,RegExpMatchFast,514,0 block_count,RegExpMatchFast,515,0 -block_count,RegExpMatchFast,516,1249 -block_count,RegExpMatchFast,517,1249 +block_count,RegExpMatchFast,516,1248 +block_count,RegExpMatchFast,517,1248 block_count,RegExpMatchFast,518,0 block_count,RegExpMatchFast,519,0 block_count,RegExpMatchFast,520,0 -block_count,RegExpMatchFast,521,1249 +block_count,RegExpMatchFast,521,1248 block_count,RegExpMatchFast,522,127 -block_count,RegExpMatchFast,523,1122 -block_count,RegExpMatchFast,524,1249 -block_count,RegExpMatchFast,525,1249 +block_count,RegExpMatchFast,523,1121 +block_count,RegExpMatchFast,524,1248 +block_count,RegExpMatchFast,525,1248 block_count,RegExpMatchFast,526,0 block_count,RegExpMatchFast,527,0 block_count,RegExpMatchFast,528,0 @@ -51724,9 +51719,9 @@ block_count,RegExpMatchFast,538,0 block_count,RegExpMatchFast,539,0 block_count,RegExpMatchFast,540,0 -block_count,RegExpMatchFast,541,1249 -block_count,RegExpMatchFast,542,194 -block_count,RegExpMatchFast,543,1055 +block_count,RegExpMatchFast,541,1248 +block_count,RegExpMatchFast,542,193 +block_count,RegExpMatchFast,543,1054 block_count,RegExpMatchFast,544,0 block_count,RegExpMatchFast,545,0 block_count,RegExpMatchFast,546,0 @@ -51734,31 +51729,31 @@ block_count,RegExpMatchFast,548,0 block_count,RegExpMatchFast,549,0 block_count,RegExpMatchFast,550,0 -block_count,RegExpMatchFast,551,194 +block_count,RegExpMatchFast,551,193 block_count,RegExpMatchFast,552,0 -block_count,RegExpMatchFast,553,194 +block_count,RegExpMatchFast,553,193 block_count,RegExpMatchFast,554,0 block_count,RegExpMatchFast,555,0 block_count,RegExpMatchFast,556,0 block_count,RegExpMatchFast,557,0 -block_count,RegExpMatchFast,558,194 -block_count,RegExpMatchFast,559,194 +block_count,RegExpMatchFast,558,193 +block_count,RegExpMatchFast,559,193 block_count,RegExpMatchFast,560,0 -block_count,RegExpMatchFast,561,194 +block_count,RegExpMatchFast,561,193 block_count,RegExpMatchFast,562,0 -block_count,RegExpMatchFast,563,194 +block_count,RegExpMatchFast,563,193 block_count,RegExpMatchFast,564,324 block_count,RegExpMatchFast,565,130 -block_count,RegExpMatchFast,566,194 -block_count,RegExpMatchFast,567,194 -block_count,RegExpMatchFast,568,194 +block_count,RegExpMatchFast,566,193 +block_count,RegExpMatchFast,567,193 +block_count,RegExpMatchFast,568,193 block_count,RegExpMatchFast,569,0 -block_count,RegExpMatchFast,570,194 -block_count,RegExpMatchFast,571,194 +block_count,RegExpMatchFast,570,193 +block_count,RegExpMatchFast,571,193 block_count,RegExpMatchFast,572,0 -block_count,RegExpMatchFast,573,194 -block_count,RegExpMatchFast,574,1055 -block_count,RegExpMatchFast,575,1055 +block_count,RegExpMatchFast,573,193 +block_count,RegExpMatchFast,574,1054 +block_count,RegExpMatchFast,575,1054 block_count,RegExpMatchFast,576,0 block_count,RegExpMatchFast,577,0 block_count,RegExpMatchFast,578,0 @@ -51884,11 +51879,11 @@ block_count,RegExpMatchFast,698,0 block_count,RegExpMatchFast,699,0 block_count,RegExpMatchFast,700,0 -block_count,RegExpMatchFast,701,194 -block_count,RegExpMatchFast,702,194 +block_count,RegExpMatchFast,701,193 +block_count,RegExpMatchFast,702,193 block_count,RegExpMatchFast,703,0 -block_count,RegExpMatchFast,704,194 -block_count,RegExpMatchFast,705,194 +block_count,RegExpMatchFast,704,193 +block_count,RegExpMatchFast,705,193 block_count,RegExpMatchFast,706,0 block_count,RegExpMatchFast,707,0 block_count,RegExpMatchFast,708,0 @@ -51903,18 +51898,18 @@ block_count,RegExpMatchFast,717,0 block_count,RegExpMatchFast,718,0 block_count,RegExpMatchFast,719,0 -block_count,RegExpMatchFast,720,194 -block_count,RegExpMatchFast,721,194 +block_count,RegExpMatchFast,720,193 +block_count,RegExpMatchFast,721,193 block_count,RegExpMatchFast,722,0 -block_count,RegExpMatchFast,723,194 +block_count,RegExpMatchFast,723,193 block_count,RegExpMatchFast,724,0 block_count,RegExpMatchFast,725,0 -block_count,RegExpMatchFast,726,194 +block_count,RegExpMatchFast,726,193 block_count,RegExpMatchFast,727,0 block_count,RegExpMatchFast,728,0 block_count,RegExpMatchFast,729,0 block_count,RegExpMatchFast,730,0 -block_count,RegExpMatchFast,731,194 +block_count,RegExpMatchFast,731,193 block_count,RegExpMatchFast,732,0 block_count,RegExpMatchFast,733,0 block_count,RegExpMatchFast,734,0 @@ -51945,24 +51940,24 @@ block_count,RegExpMatchFast,759,0 block_count,RegExpMatchFast,760,0 block_count,RegExpMatchFast,761,0 -block_count,RegExpMatchFast,762,194 +block_count,RegExpMatchFast,762,193 block_count,RegExpMatchFast,763,0 -block_count,RegExpMatchFast,764,194 -block_count,RegExpMatchFast,765,194 -block_count,RegExpMatchFast,766,194 +block_count,RegExpMatchFast,764,193 +block_count,RegExpMatchFast,765,193 +block_count,RegExpMatchFast,766,193 block_count,RegExpMatchFast,767,0 -block_count,RegExpMatchFast,768,194 +block_count,RegExpMatchFast,768,193 block_count,RegExpMatchFast,769,0 -block_count,RegExpMatchFast,770,194 +block_count,RegExpMatchFast,770,193 block_count,RegExpMatchFast,771,86 block_count,RegExpMatchFast,772,107 block_count,RegExpMatchFast,773,117 block_count,RegExpMatchFast,774,9 block_count,RegExpMatchFast,775,107 -block_count,RegExpMatchFast,776,194 +block_count,RegExpMatchFast,776,193 block_count,RegExpMatchFast,777,104 block_count,RegExpMatchFast,778,89 -block_count,RegExpMatchFast,779,194 +block_count,RegExpMatchFast,779,193 block_count,RegExpMatchFast,780,107 block_count,RegExpMatchFast,781,130 block_count,RegExpMatchFast,782,116 @@ -52076,12 +52071,12 @@ block_count,RegExpMatchFast,890,0 block_count,RegExpMatchFast,891,107 block_count,RegExpMatchFast,892,86 -block_count,RegExpMatchFast,893,194 -block_count,RegExpMatchFast,894,194 +block_count,RegExpMatchFast,893,193 +block_count,RegExpMatchFast,894,193 block_count,RegExpMatchFast,895,0 -block_count,RegExpMatchFast,896,194 -block_count,RegExpMatchFast,897,1055 -block_count,RegExpMatchFast,898,1249 +block_count,RegExpMatchFast,896,193 +block_count,RegExpMatchFast,897,1054 +block_count,RegExpMatchFast,898,1248 block_count,RegExpReplace,0,199 block_count,RegExpReplace,1,199 block_count,RegExpReplace,2,184 @@ -52121,16 +52116,16 @@ block_count,RegExpReplace,36,0 block_count,RegExpReplace,37,0 block_count,RegExpReplace,38,3 -block_count,RegExpReplace,39,797 -block_count,RegExpReplace,40,797 -block_count,RegExpReplace,41,797 -block_count,RegExpReplace,42,398 +block_count,RegExpReplace,39,796 +block_count,RegExpReplace,40,796 +block_count,RegExpReplace,41,796 +block_count,RegExpReplace,42,397 block_count,RegExpReplace,43,0 block_count,RegExpReplace,44,0 block_count,RegExpReplace,45,0 -block_count,RegExpReplace,46,398 -block_count,RegExpReplace,47,398 -block_count,RegExpReplace,48,399 +block_count,RegExpReplace,46,397 +block_count,RegExpReplace,47,397 +block_count,RegExpReplace,48,398 block_count,RegExpReplace,49,395 block_count,RegExpReplace,50,395 block_count,RegExpReplace,51,0 @@ -52411,19 +52406,19 @@ block_count,RegExpReplace,326,0 block_count,RegExpReplace,327,32 block_count,RegExpReplace,328,13 -block_count,RegExpReplace,329,138 +block_count,RegExpReplace,329,137 block_count,RegExpReplace,330,85 block_count,RegExpReplace,331,52 -block_count,RegExpReplace,332,138 +block_count,RegExpReplace,332,137 block_count,RegExpReplace,333,0 -block_count,RegExpReplace,334,138 -block_count,RegExpReplace,335,138 -block_count,RegExpReplace,336,138 -block_count,RegExpReplace,337,138 +block_count,RegExpReplace,334,137 +block_count,RegExpReplace,335,137 +block_count,RegExpReplace,336,137 +block_count,RegExpReplace,337,137 block_count,RegExpReplace,338,0 block_count,RegExpReplace,339,0 block_count,RegExpReplace,340,0 -block_count,RegExpReplace,341,138 +block_count,RegExpReplace,341,137 block_count,RegExpReplace,342,196 block_count,RegExpReplace,343,145 block_count,RegExpReplace,344,145 @@ -52506,27 +52501,27 @@ block_count,RegExpReplace,421,58 block_count,RegExpReplace,422,15 block_count,RegExpReplace,423,42 -block_count,RegExpReplace,424,280 -block_count,RegExpReplace,425,280 -block_count,RegExpReplace,426,280 -block_count,RegExpReplace,427,280 -block_count,RegExpReplace,428,280 +block_count,RegExpReplace,424,279 +block_count,RegExpReplace,425,279 +block_count,RegExpReplace,426,279 +block_count,RegExpReplace,427,279 +block_count,RegExpReplace,428,279 block_count,RegExpReplace,429,96 block_count,RegExpReplace,430,96 block_count,RegExpReplace,431,96 block_count,RegExpReplace,432,0 block_count,RegExpReplace,433,183 -block_count,RegExpReplace,434,280 -block_count,RegExpReplace,435,280 -block_count,RegExpReplace,436,280 -block_count,RegExpReplace,437,280 -block_count,RegExpReplace,438,280 +block_count,RegExpReplace,434,279 +block_count,RegExpReplace,435,279 +block_count,RegExpReplace,436,279 +block_count,RegExpReplace,437,279 +block_count,RegExpReplace,438,279 block_count,RegExpReplace,439,96 block_count,RegExpReplace,440,96 block_count,RegExpReplace,441,96 block_count,RegExpReplace,442,0 block_count,RegExpReplace,443,183 -block_count,RegExpReplace,444,280 +block_count,RegExpReplace,444,279 block_count,RegExpReplace,445,237 block_count,RegExpReplace,446,42 block_count,RegExpReplace,447,0 @@ -52646,7 +52641,7 @@ block_count,RegExpReplace,561,0 block_count,RegExpReplace,562,0 block_count,RegExpReplace,563,50 -block_count,RegExpReplace,564,138 +block_count,RegExpReplace,564,137 block_count,RegExpReplace,565,50 block_count,RegExpReplace,566,0 block_count,RegExpReplace,567,50 @@ -52664,10 +52659,10 @@ block_count,RegExpReplace,579,50 block_count,RegExpReplace,580,0 block_count,RegExpReplace,581,87 -block_count,RegExpReplace,582,138 -block_count,RegExpReplace,583,138 +block_count,RegExpReplace,582,137 +block_count,RegExpReplace,583,137 block_count,RegExpReplace,584,0 -block_count,RegExpReplace,585,138 +block_count,RegExpReplace,585,137 block_count,RegExpReplace,586,0 block_count,RegExpPrototypeReplace,0,0 block_count,RegExpPrototypeReplace,1,0 @@ -53006,7 +53001,7 @@ block_count,RegExpSplit,63,0 block_count,RegExpSplit,64,52 block_count,RegExpSplit,65,0 -block_count,RegExpSplit,66,52 +block_count,RegExpSplit,66,51 block_count,RegExpSplit,67,52 block_count,RegExpSplit,68,52 block_count,RegExpSplit,69,0 @@ -53467,31 +53462,31 @@ block_count,RegExpSplit,524,0 block_count,RegExpSplit,525,14 block_count,RegExpSplit,526,14 -block_count,RegExpPrototypeTest,0,96 +block_count,RegExpPrototypeTest,0,97 block_count,RegExpPrototypeTest,1,0 -block_count,RegExpPrototypeTest,2,96 -block_count,RegExpPrototypeTest,3,96 -block_count,RegExpPrototypeTest,4,96 -block_count,RegExpPrototypeTest,5,96 -block_count,RegExpPrototypeTest,6,96 +block_count,RegExpPrototypeTest,2,97 +block_count,RegExpPrototypeTest,3,97 +block_count,RegExpPrototypeTest,4,97 +block_count,RegExpPrototypeTest,5,97 +block_count,RegExpPrototypeTest,6,97 block_count,RegExpPrototypeTest,7,39 -block_count,RegExpPrototypeTest,8,56 +block_count,RegExpPrototypeTest,8,58 block_count,RegExpPrototypeTest,9,0 block_count,RegExpPrototypeTest,10,39 -block_count,RegExpPrototypeTest,11,96 -block_count,RegExpPrototypeTest,12,96 +block_count,RegExpPrototypeTest,11,97 +block_count,RegExpPrototypeTest,12,97 block_count,RegExpPrototypeTest,13,0 -block_count,RegExpPrototypeTest,14,96 +block_count,RegExpPrototypeTest,14,97 block_count,RegExpPrototypeTest,15,0 -block_count,RegExpPrototypeTest,16,96 +block_count,RegExpPrototypeTest,16,97 block_count,RegExpPrototypeTest,17,0 -block_count,RegExpPrototypeTest,18,96 +block_count,RegExpPrototypeTest,18,97 block_count,RegExpPrototypeTest,19,0 -block_count,RegExpPrototypeTest,20,96 +block_count,RegExpPrototypeTest,20,97 block_count,RegExpPrototypeTest,21,0 -block_count,RegExpPrototypeTest,22,96 +block_count,RegExpPrototypeTest,22,97 block_count,RegExpPrototypeTest,23,0 -block_count,RegExpPrototypeTest,24,96 +block_count,RegExpPrototypeTest,24,97 block_count,RegExpPrototypeTest,25,0 block_count,RegExpPrototypeTest,26,0 block_count,RegExpPrototypeTest,27,0 @@ -53520,27 +53515,27 @@ block_count,RegExpPrototypeTest,50,0 block_count,RegExpPrototypeTest,51,0 block_count,RegExpPrototypeTest,52,0 -block_count,RegExpPrototypeTest,53,96 -block_count,RegExpPrototypeTest,54,96 -block_count,RegExpPrototypeTest,55,95 +block_count,RegExpPrototypeTest,53,97 +block_count,RegExpPrototypeTest,54,97 +block_count,RegExpPrototypeTest,55,96 block_count,RegExpPrototypeTest,56,0 -block_count,RegExpPrototypeTest,57,96 -block_count,RegExpPrototypeTest,58,96 -block_count,RegExpPrototypeTest,59,96 +block_count,RegExpPrototypeTest,57,97 +block_count,RegExpPrototypeTest,58,97 +block_count,RegExpPrototypeTest,59,97 block_count,RegExpPrototypeTest,60,0 block_count,RegExpPrototypeTest,61,0 block_count,RegExpPrototypeTest,62,0 -block_count,RegExpPrototypeTest,63,96 -block_count,RegExpPrototypeTest,64,50 -block_count,RegExpPrototypeTest,65,62 +block_count,RegExpPrototypeTest,63,97 +block_count,RegExpPrototypeTest,64,52 +block_count,RegExpPrototypeTest,65,64 block_count,RegExpPrototypeTest,66,39 block_count,RegExpPrototypeTest,67,0 block_count,RegExpPrototypeTest,68,39 -block_count,RegExpPrototypeTest,69,11 +block_count,RegExpPrototypeTest,69,12 block_count,RegExpPrototypeTest,70,0 -block_count,RegExpPrototypeTest,71,11 +block_count,RegExpPrototypeTest,71,12 block_count,RegExpPrototypeTest,72,0 -block_count,RegExpPrototypeTest,73,11 +block_count,RegExpPrototypeTest,73,12 block_count,RegExpPrototypeTest,74,39 block_count,RegExpPrototypeTest,75,39 block_count,RegExpPrototypeTest,76,39 @@ -53561,24 +53556,24 @@ block_count,RegExpPrototypeTest,91,0 block_count,RegExpPrototypeTest,92,0 block_count,RegExpPrototypeTest,93,45 -block_count,RegExpPrototypeTest,94,57 -block_count,RegExpPrototypeTest,95,96 +block_count,RegExpPrototypeTest,94,58 +block_count,RegExpPrototypeTest,95,97 block_count,RegExpPrototypeTest,96,0 -block_count,RegExpPrototypeTest,97,95 +block_count,RegExpPrototypeTest,97,96 block_count,RegExpPrototypeTest,98,0 block_count,RegExpPrototypeTest,99,0 block_count,RegExpPrototypeTest,100,0 block_count,RegExpPrototypeTest,101,0 -block_count,RegExpPrototypeTest,102,95 -block_count,RegExpPrototypeTest,103,95 +block_count,RegExpPrototypeTest,102,96 +block_count,RegExpPrototypeTest,103,96 block_count,RegExpPrototypeTest,104,0 block_count,RegExpPrototypeTest,105,0 block_count,RegExpPrototypeTest,106,0 -block_count,RegExpPrototypeTest,107,95 +block_count,RegExpPrototypeTest,107,96 block_count,RegExpPrototypeTest,108,0 -block_count,RegExpPrototypeTest,109,95 -block_count,RegExpPrototypeTest,110,95 -block_count,RegExpPrototypeTest,111,95 +block_count,RegExpPrototypeTest,109,96 +block_count,RegExpPrototypeTest,110,96 +block_count,RegExpPrototypeTest,111,96 block_count,RegExpPrototypeTest,112,0 block_count,RegExpPrototypeTest,113,0 block_count,RegExpPrototypeTest,114,0 @@ -53594,9 +53589,9 @@ block_count,RegExpPrototypeTest,124,0 block_count,RegExpPrototypeTest,125,0 block_count,RegExpPrototypeTest,126,0 -block_count,RegExpPrototypeTest,127,95 +block_count,RegExpPrototypeTest,127,96 block_count,RegExpPrototypeTest,128,9 -block_count,RegExpPrototypeTest,129,85 +block_count,RegExpPrototypeTest,129,86 block_count,RegExpPrototypeTest,130,0 block_count,RegExpPrototypeTest,131,0 block_count,RegExpPrototypeTest,132,0 @@ -53617,7 +53612,7 @@ block_count,RegExpPrototypeTest,147,10 block_count,RegExpPrototypeTest,148,0 block_count,RegExpPrototypeTest,149,10 -block_count,RegExpPrototypeTest,150,14 +block_count,RegExpPrototypeTest,150,15 block_count,RegExpPrototypeTest,151,4 block_count,RegExpPrototypeTest,152,10 block_count,RegExpPrototypeTest,153,10 @@ -53627,31 +53622,31 @@ block_count,RegExpPrototypeTest,157,10 block_count,RegExpPrototypeTest,158,0 block_count,RegExpPrototypeTest,159,10 -block_count,RegExpPrototypeTest,160,85 -block_count,RegExpPrototypeTest,161,85 +block_count,RegExpPrototypeTest,160,87 +block_count,RegExpPrototypeTest,161,87 block_count,RegExpPrototypeTest,162,0 -block_count,RegExpPrototypeTest,163,85 -block_count,RegExpPrototypeTestFast,0,452 -block_count,RegExpPrototypeTestFast,1,452 -block_count,RegExpPrototypeTestFast,2,447 +block_count,RegExpPrototypeTest,163,87 +block_count,RegExpPrototypeTestFast,0,451 +block_count,RegExpPrototypeTestFast,1,451 +block_count,RegExpPrototypeTestFast,2,445 block_count,RegExpPrototypeTestFast,3,5 -block_count,RegExpPrototypeTestFast,4,452 -block_count,RegExpPrototypeTestFast,5,452 -block_count,RegExpPrototypeTestFast,6,452 +block_count,RegExpPrototypeTestFast,4,451 +block_count,RegExpPrototypeTestFast,5,451 +block_count,RegExpPrototypeTestFast,6,451 block_count,RegExpPrototypeTestFast,7,0 block_count,RegExpPrototypeTestFast,8,0 block_count,RegExpPrototypeTestFast,9,0 -block_count,RegExpPrototypeTestFast,10,452 -block_count,RegExpPrototypeTestFast,11,128 -block_count,RegExpPrototypeTestFast,12,256 +block_count,RegExpPrototypeTestFast,10,451 +block_count,RegExpPrototypeTestFast,11,126 +block_count,RegExpPrototypeTestFast,12,253 block_count,RegExpPrototypeTestFast,13,0 block_count,RegExpPrototypeTestFast,14,0 block_count,RegExpPrototypeTestFast,15,0 -block_count,RegExpPrototypeTestFast,16,91 +block_count,RegExpPrototypeTestFast,16,90 block_count,RegExpPrototypeTestFast,17,36 -block_count,RegExpPrototypeTestFast,18,128 +block_count,RegExpPrototypeTestFast,18,126 block_count,RegExpPrototypeTestFast,19,0 -block_count,RegExpPrototypeTestFast,20,128 +block_count,RegExpPrototypeTestFast,20,126 block_count,RegExpPrototypeTestFast,21,0 block_count,RegExpPrototypeTestFast,22,0 block_count,RegExpPrototypeTestFast,23,0 @@ -53672,24 +53667,24 @@ block_count,RegExpPrototypeTestFast,38,0 block_count,RegExpPrototypeTestFast,39,0 block_count,RegExpPrototypeTestFast,40,324 -block_count,RegExpPrototypeTestFast,41,452 -block_count,RegExpPrototypeTestFast,42,452 +block_count,RegExpPrototypeTestFast,41,451 +block_count,RegExpPrototypeTestFast,42,451 block_count,RegExpPrototypeTestFast,43,0 -block_count,RegExpPrototypeTestFast,44,447 +block_count,RegExpPrototypeTestFast,44,445 block_count,RegExpPrototypeTestFast,45,5 block_count,RegExpPrototypeTestFast,46,5 block_count,RegExpPrototypeTestFast,47,0 block_count,RegExpPrototypeTestFast,48,0 -block_count,RegExpPrototypeTestFast,49,447 -block_count,RegExpPrototypeTestFast,50,447 +block_count,RegExpPrototypeTestFast,49,445 +block_count,RegExpPrototypeTestFast,50,445 block_count,RegExpPrototypeTestFast,51,0 block_count,RegExpPrototypeTestFast,52,0 block_count,RegExpPrototypeTestFast,53,0 -block_count,RegExpPrototypeTestFast,54,447 +block_count,RegExpPrototypeTestFast,54,445 block_count,RegExpPrototypeTestFast,55,0 -block_count,RegExpPrototypeTestFast,56,446 -block_count,RegExpPrototypeTestFast,57,447 -block_count,RegExpPrototypeTestFast,58,447 +block_count,RegExpPrototypeTestFast,56,445 +block_count,RegExpPrototypeTestFast,57,445 +block_count,RegExpPrototypeTestFast,58,445 block_count,RegExpPrototypeTestFast,59,0 block_count,RegExpPrototypeTestFast,60,0 block_count,RegExpPrototypeTestFast,61,0 @@ -53705,9 +53700,9 @@ block_count,RegExpPrototypeTestFast,71,0 block_count,RegExpPrototypeTestFast,72,0 block_count,RegExpPrototypeTestFast,73,0 -block_count,RegExpPrototypeTestFast,74,447 +block_count,RegExpPrototypeTestFast,74,445 block_count,RegExpPrototypeTestFast,75,130 -block_count,RegExpPrototypeTestFast,76,316 +block_count,RegExpPrototypeTestFast,76,314 block_count,RegExpPrototypeTestFast,77,0 block_count,RegExpPrototypeTestFast,78,0 block_count,RegExpPrototypeTestFast,79,0 @@ -53728,8 +53723,8 @@ block_count,RegExpPrototypeTestFast,94,136 block_count,RegExpPrototypeTestFast,95,0 block_count,RegExpPrototypeTestFast,96,136 -block_count,RegExpPrototypeTestFast,97,1715 -block_count,RegExpPrototypeTestFast,98,1579 +block_count,RegExpPrototypeTestFast,97,1714 +block_count,RegExpPrototypeTestFast,98,1578 block_count,RegExpPrototypeTestFast,99,136 block_count,RegExpPrototypeTestFast,100,136 block_count,RegExpPrototypeTestFast,101,136 @@ -53738,10 +53733,10 @@ block_count,RegExpPrototypeTestFast,104,136 block_count,RegExpPrototypeTestFast,105,0 block_count,RegExpPrototypeTestFast,106,136 -block_count,RegExpPrototypeTestFast,107,316 -block_count,RegExpPrototypeTestFast,108,316 +block_count,RegExpPrototypeTestFast,107,314 +block_count,RegExpPrototypeTestFast,108,314 block_count,RegExpPrototypeTestFast,109,0 -block_count,RegExpPrototypeTestFast,110,316 +block_count,RegExpPrototypeTestFast,110,314 block_count,RegExpPrototypeGlobalGetter,0,0 block_count,RegExpPrototypeGlobalGetter,1,0 block_count,RegExpPrototypeGlobalGetter,2,0 @@ -54644,27 +54639,27 @@ block_count,StringIteratorPrototypeNext,86,0 block_count,StringIteratorPrototypeNext,87,0 block_count,StringIteratorPrototypeNext,88,0 -block_count,StringPrototypeMatch,0,1252 +block_count,StringPrototypeMatch,0,1251 block_count,StringPrototypeMatch,1,0 -block_count,StringPrototypeMatch,2,1252 -block_count,StringPrototypeMatch,3,1252 -block_count,StringPrototypeMatch,4,1252 -block_count,StringPrototypeMatch,5,1252 -block_count,StringPrototypeMatch,6,1252 -block_count,StringPrototypeMatch,7,1252 -block_count,StringPrototypeMatch,8,1252 +block_count,StringPrototypeMatch,2,1251 +block_count,StringPrototypeMatch,3,1251 +block_count,StringPrototypeMatch,4,1251 +block_count,StringPrototypeMatch,5,1251 +block_count,StringPrototypeMatch,6,1251 +block_count,StringPrototypeMatch,7,1251 +block_count,StringPrototypeMatch,8,1251 block_count,StringPrototypeMatch,9,0 -block_count,StringPrototypeMatch,10,1252 +block_count,StringPrototypeMatch,10,1251 block_count,StringPrototypeMatch,11,0 -block_count,StringPrototypeMatch,12,1252 +block_count,StringPrototypeMatch,12,1251 block_count,StringPrototypeMatch,13,0 -block_count,StringPrototypeMatch,14,1252 +block_count,StringPrototypeMatch,14,1251 block_count,StringPrototypeMatch,15,0 -block_count,StringPrototypeMatch,16,1252 +block_count,StringPrototypeMatch,16,1251 block_count,StringPrototypeMatch,17,0 -block_count,StringPrototypeMatch,18,1252 +block_count,StringPrototypeMatch,18,1251 block_count,StringPrototypeMatch,19,0 -block_count,StringPrototypeMatch,20,1252 +block_count,StringPrototypeMatch,20,1251 block_count,StringPrototypeSearch,0,1 block_count,StringPrototypeSearch,1,0 block_count,StringPrototypeSearch,2,1 @@ -54715,7 +54710,7 @@ block_count,StringPrototypeSlice,19,11 block_count,StringPrototypeSlice,20,11 block_count,StringPrototypeSlice,21,0 -block_count,StringPrototypeSlice,22,11 +block_count,StringPrototypeSlice,22,10 block_count,StringPrototypeSlice,23,0 block_count,StringPrototypeSlice,24,0 block_count,StringPrototypeSlice,25,0 @@ -54762,16 +54757,16 @@ block_count,StringPrototypeSlice,66,10 block_count,StringPrototypeSlice,67,10 block_count,StringPrototypeSlice,68,7 -block_count,StringPrototypeSlice,69,5 -block_count,StringPrototypeSlice,70,10 -block_count,StringPrototypeSlice,71,1 -block_count,StringPrototypeSlice,72,1 +block_count,StringPrototypeSlice,69,4 +block_count,StringPrototypeSlice,70,9 +block_count,StringPrototypeSlice,71,0 +block_count,StringPrototypeSlice,72,0 block_count,StringPrototypeSlice,73,0 block_count,StringPrototypeSlice,74,3 block_count,StringPrototypeSlice,75,0 -block_count,StringPrototypeSlice,76,5 +block_count,StringPrototypeSlice,76,4 block_count,StringPrototypeSlice,77,0 -block_count,StringPrototypeSlice,78,5 +block_count,StringPrototypeSlice,78,4 block_count,StringPrototypeSlice,79,0 block_count,StringPrototypeSlice,80,2 block_count,StringPrototypeSlice,81,7 @@ -54949,7 +54944,7 @@ block_count,StringPrototypeSlice,253,0 block_count,StringPrototypeSlice,254,2 block_count,StringPrototypeSlice,255,1 -block_count,StringPrototypeSlice,256,3 +block_count,StringPrototypeSlice,256,2 block_count,StringPrototypeSlice,257,1 block_count,StringPrototypeSlice,258,1 block_count,StringPrototypeSlice,259,0 @@ -55614,15 +55609,15 @@ block_count,StringPrototypeSubstring,67,0 block_count,StringPrototypeSubstring,68,1 block_count,StringPrototypeSubstring,69,2 -block_count,StringPrototypeSubstring,70,0 +block_count,StringPrototypeSubstring,70,1 block_count,StringPrototypeSubstring,71,0 block_count,StringPrototypeSubstring,72,0 block_count,StringPrototypeSubstring,73,0 block_count,StringPrototypeSubstring,74,0 -block_count,StringPrototypeSubstring,75,0 +block_count,StringPrototypeSubstring,75,1 block_count,StringPrototypeSubstring,76,0 -block_count,StringPrototypeSubstring,77,0 -block_count,StringPrototypeSubstring,78,0 +block_count,StringPrototypeSubstring,77,1 +block_count,StringPrototypeSubstring,78,1 block_count,StringPrototypeSubstring,79,1 block_count,StringPrototypeSubstring,80,1 block_count,StringPrototypeSubstring,81,0 @@ -56862,7 +56857,7 @@ block_count,CreateTypedArray,370,41 block_count,CreateTypedArray,371,0 block_count,CreateTypedArray,372,41 -block_count,CreateTypedArray,373,165 +block_count,CreateTypedArray,373,164 block_count,CreateTypedArray,374,123 block_count,CreateTypedArray,375,41 block_count,CreateTypedArray,376,41 @@ -58096,27 +58091,27 @@ block_count,NewStrictArgumentsElements,16,0 block_count,NewStrictArgumentsElements,17,0 block_count,NewStrictArgumentsElements,18,0 -block_count,NewRestArgumentsElements,0,14 -block_count,NewRestArgumentsElements,1,14 +block_count,NewRestArgumentsElements,0,13 +block_count,NewRestArgumentsElements,1,13 block_count,NewRestArgumentsElements,2,0 -block_count,NewRestArgumentsElements,3,14 -block_count,NewRestArgumentsElements,4,14 -block_count,NewRestArgumentsElements,5,14 -block_count,NewRestArgumentsElements,6,14 -block_count,NewRestArgumentsElements,7,14 +block_count,NewRestArgumentsElements,3,13 +block_count,NewRestArgumentsElements,4,13 +block_count,NewRestArgumentsElements,5,13 +block_count,NewRestArgumentsElements,6,13 +block_count,NewRestArgumentsElements,7,13 block_count,NewRestArgumentsElements,8,0 -block_count,NewRestArgumentsElements,9,14 +block_count,NewRestArgumentsElements,9,13 block_count,NewRestArgumentsElements,10,0 block_count,NewRestArgumentsElements,11,0 -block_count,NewRestArgumentsElements,12,14 -block_count,NewRestArgumentsElements,13,44 -block_count,NewRestArgumentsElements,14,29 -block_count,NewRestArgumentsElements,15,29 -block_count,NewRestArgumentsElements,16,29 +block_count,NewRestArgumentsElements,12,13 +block_count,NewRestArgumentsElements,13,41 +block_count,NewRestArgumentsElements,14,27 +block_count,NewRestArgumentsElements,15,27 +block_count,NewRestArgumentsElements,16,27 block_count,NewRestArgumentsElements,17,0 -block_count,NewRestArgumentsElements,18,29 +block_count,NewRestArgumentsElements,18,27 block_count,NewRestArgumentsElements,19,0 -block_count,NewRestArgumentsElements,20,14 +block_count,NewRestArgumentsElements,20,13 block_count,NewRestArgumentsElements,21,0 block_count,NewRestArgumentsElements,22,0 block_count,NewRestArgumentsElements,23,0 @@ -58252,37 +58247,37 @@ block_count,FastNewStrictArguments,28,0 block_count,FastNewStrictArguments,29,3 block_count,FastNewStrictArguments,30,3 -block_count,FastNewRestArguments,0,1 -block_count,FastNewRestArguments,1,1 -block_count,FastNewRestArguments,2,1 +block_count,FastNewRestArguments,0,2 +block_count,FastNewRestArguments,1,2 +block_count,FastNewRestArguments,2,2 block_count,FastNewRestArguments,3,0 -block_count,FastNewRestArguments,4,1 -block_count,FastNewRestArguments,5,1 +block_count,FastNewRestArguments,4,2 +block_count,FastNewRestArguments,5,2 block_count,FastNewRestArguments,6,0 -block_count,FastNewRestArguments,7,1 -block_count,FastNewRestArguments,8,1 +block_count,FastNewRestArguments,7,2 +block_count,FastNewRestArguments,8,2 block_count,FastNewRestArguments,9,0 -block_count,FastNewRestArguments,10,1 -block_count,FastNewRestArguments,11,1 -block_count,FastNewRestArguments,12,1 -block_count,FastNewRestArguments,13,1 -block_count,FastNewRestArguments,14,1 +block_count,FastNewRestArguments,10,2 +block_count,FastNewRestArguments,11,2 +block_count,FastNewRestArguments,12,2 +block_count,FastNewRestArguments,13,2 +block_count,FastNewRestArguments,14,2 block_count,FastNewRestArguments,15,0 -block_count,FastNewRestArguments,16,1 +block_count,FastNewRestArguments,16,2 block_count,FastNewRestArguments,17,0 block_count,FastNewRestArguments,18,0 -block_count,FastNewRestArguments,19,1 -block_count,FastNewRestArguments,20,4 -block_count,FastNewRestArguments,21,3 -block_count,FastNewRestArguments,22,3 -block_count,FastNewRestArguments,23,3 +block_count,FastNewRestArguments,19,2 +block_count,FastNewRestArguments,20,8 +block_count,FastNewRestArguments,21,5 +block_count,FastNewRestArguments,22,5 +block_count,FastNewRestArguments,23,5 block_count,FastNewRestArguments,24,0 -block_count,FastNewRestArguments,25,3 +block_count,FastNewRestArguments,25,5 block_count,FastNewRestArguments,26,0 -block_count,FastNewRestArguments,27,1 +block_count,FastNewRestArguments,27,2 block_count,FastNewRestArguments,28,0 -block_count,FastNewRestArguments,29,1 -block_count,FastNewRestArguments,30,1 +block_count,FastNewRestArguments,29,2 +block_count,FastNewRestArguments,30,2 block_count,FastNewRestArguments,31,0 block_count,FastNewRestArguments,32,0 block_count,FastNewRestArguments,33,0 @@ -58702,7 +58697,7 @@ block_count,StringIndexOf,9,184 block_count,StringIndexOf,10,214 block_count,StringIndexOf,11,49 -block_count,StringIndexOf,12,29 +block_count,StringIndexOf,12,30 block_count,StringIndexOf,13,28 block_count,StringIndexOf,14,1 block_count,StringIndexOf,15,0 @@ -58739,7 +58734,7 @@ block_count,StringIndexOf,46,0 block_count,StringIndexOf,47,0 block_count,StringIndexOf,48,1 -block_count,StringIndexOf,49,29 +block_count,StringIndexOf,49,30 block_count,StringIndexOf,50,19 block_count,StringIndexOf,51,19 block_count,StringIndexOf,52,19 @@ -58906,14 +58901,14 @@ block_count,SortCompareDefault,9,3 block_count,SortCompareDefault,10,0 block_count,SortCompareDefault,11,3 -block_count,SortCompareUserFn,0,781 +block_count,SortCompareUserFn,0,780 block_count,SortCompareUserFn,1,0 block_count,SortCompareUserFn,2,0 block_count,SortCompareUserFn,3,0 block_count,SortCompareUserFn,4,0 -block_count,SortCompareUserFn,5,781 -block_count,SortCompareUserFn,6,781 -block_count,SortCompareUserFn,7,781 +block_count,SortCompareUserFn,5,780 +block_count,SortCompareUserFn,6,780 +block_count,SortCompareUserFn,7,780 block_count,Copy,0,2 block_count,Copy,1,1 block_count,Copy,2,141 @@ -59085,16 +59080,16 @@ block_count,MergeAt,151,0 block_count,MergeAt,152,0 block_count,MergeAt,153,0 -block_count,MergeAt,154,112 -block_count,MergeAt,155,112 -block_count,MergeAt,156,112 +block_count,MergeAt,154,111 +block_count,MergeAt,155,111 +block_count,MergeAt,156,111 block_count,MergeAt,157,0 block_count,MergeAt,158,111 -block_count,MergeAt,159,112 +block_count,MergeAt,159,111 block_count,MergeAt,160,0 block_count,MergeAt,161,0 block_count,MergeAt,162,0 -block_count,MergeAt,163,112 +block_count,MergeAt,163,111 block_count,MergeAt,164,55 block_count,MergeAt,165,56 block_count,MergeAt,166,55 @@ -59427,30 +59422,30 @@ block_count,ArrayTimSort,103,39 block_count,ArrayTimSort,104,0 block_count,ArrayTimSort,105,39 -block_count,ArrayTimSort,106,184 +block_count,ArrayTimSort,106,183 block_count,ArrayTimSort,107,144 block_count,ArrayTimSort,108,144 -block_count,ArrayTimSort,109,546 +block_count,ArrayTimSort,109,545 block_count,ArrayTimSort,110,401 block_count,ArrayTimSort,111,401 block_count,ArrayTimSort,112,3 -block_count,ArrayTimSort,113,398 +block_count,ArrayTimSort,113,397 block_count,ArrayTimSort,114,401 block_count,ArrayTimSort,115,0 block_count,ArrayTimSort,116,0 block_count,ArrayTimSort,117,0 block_count,ArrayTimSort,118,401 block_count,ArrayTimSort,119,187 -block_count,ArrayTimSort,120,214 +block_count,ArrayTimSort,120,213 block_count,ArrayTimSort,121,187 -block_count,ArrayTimSort,122,214 +block_count,ArrayTimSort,122,213 block_count,ArrayTimSort,123,401 block_count,ArrayTimSort,124,0 block_count,ArrayTimSort,125,144 -block_count,ArrayTimSort,126,767 -block_count,ArrayTimSort,127,622 -block_count,ArrayTimSort,128,622 -block_count,ArrayTimSort,129,622 +block_count,ArrayTimSort,126,766 +block_count,ArrayTimSort,127,621 +block_count,ArrayTimSort,128,621 +block_count,ArrayTimSort,129,621 block_count,ArrayTimSort,130,0 block_count,ArrayTimSort,131,0 block_count,ArrayTimSort,132,144 @@ -59749,11 +59744,11 @@ block_count,ArrayPrototypeSort,116,0 block_count,ArrayPrototypeSort,117,38 block_count,ArrayPrototypeSort,118,38 -block_count,StringFastLocaleCompare,0,1431 -block_count,StringFastLocaleCompare,1,1431 -block_count,StringFastLocaleCompare,2,1431 -block_count,StringFastLocaleCompare,3,1347 -block_count,StringFastLocaleCompare,4,1347 +block_count,StringFastLocaleCompare,0,1430 +block_count,StringFastLocaleCompare,1,1430 +block_count,StringFastLocaleCompare,2,1430 +block_count,StringFastLocaleCompare,3,1346 +block_count,StringFastLocaleCompare,4,1346 block_count,StringFastLocaleCompare,5,0 block_count,StringFastLocaleCompare,6,0 block_count,StringFastLocaleCompare,7,0 @@ -59956,16 +59951,16 @@ block_count,StringFastLocaleCompare,204,0 block_count,StringFastLocaleCompare,205,0 block_count,StringFastLocaleCompare,206,0 -block_count,StringFastLocaleCompare,207,1347 -block_count,StringFastLocaleCompare,208,1347 -block_count,StringFastLocaleCompare,209,1347 +block_count,StringFastLocaleCompare,207,1346 +block_count,StringFastLocaleCompare,208,1346 +block_count,StringFastLocaleCompare,209,1346 block_count,StringFastLocaleCompare,210,0 block_count,StringFastLocaleCompare,211,0 block_count,StringFastLocaleCompare,212,0 -block_count,StringFastLocaleCompare,213,1347 -block_count,StringFastLocaleCompare,214,1347 -block_count,StringFastLocaleCompare,215,1347 -block_count,StringFastLocaleCompare,216,1347 +block_count,StringFastLocaleCompare,213,1346 +block_count,StringFastLocaleCompare,214,1346 +block_count,StringFastLocaleCompare,215,1346 +block_count,StringFastLocaleCompare,216,1346 block_count,StringFastLocaleCompare,217,0 block_count,StringFastLocaleCompare,218,0 block_count,StringFastLocaleCompare,219,0 @@ -60057,33 +60052,33 @@ block_count,StringFastLocaleCompare,305,0 block_count,StringFastLocaleCompare,306,0 block_count,StringFastLocaleCompare,307,0 -block_count,StringFastLocaleCompare,308,1347 -block_count,StringFastLocaleCompare,309,1347 -block_count,StringFastLocaleCompare,310,1347 +block_count,StringFastLocaleCompare,308,1346 +block_count,StringFastLocaleCompare,309,1346 +block_count,StringFastLocaleCompare,310,1346 block_count,StringFastLocaleCompare,311,0 block_count,StringFastLocaleCompare,312,0 block_count,StringFastLocaleCompare,313,0 -block_count,StringFastLocaleCompare,314,1347 -block_count,StringFastLocaleCompare,315,922 -block_count,StringFastLocaleCompare,316,922 +block_count,StringFastLocaleCompare,314,1346 +block_count,StringFastLocaleCompare,315,921 +block_count,StringFastLocaleCompare,316,921 block_count,StringFastLocaleCompare,317,982 block_count,StringFastLocaleCompare,318,982 block_count,StringFastLocaleCompare,319,982 block_count,StringFastLocaleCompare,320,60 -block_count,StringFastLocaleCompare,321,922 +block_count,StringFastLocaleCompare,321,921 block_count,StringFastLocaleCompare,322,0 block_count,StringFastLocaleCompare,323,0 block_count,StringFastLocaleCompare,324,0 block_count,StringFastLocaleCompare,325,0 block_count,StringFastLocaleCompare,326,425 -block_count,StringFastLocaleCompare,327,1347 -block_count,StringFastLocaleCompare,328,6597 -block_count,StringFastLocaleCompare,329,6586 -block_count,StringFastLocaleCompare,330,6586 -block_count,StringFastLocaleCompare,331,6529 -block_count,StringFastLocaleCompare,332,6529 -block_count,StringFastLocaleCompare,333,5249 -block_count,StringFastLocaleCompare,334,1279 +block_count,StringFastLocaleCompare,327,1346 +block_count,StringFastLocaleCompare,328,6593 +block_count,StringFastLocaleCompare,329,6583 +block_count,StringFastLocaleCompare,330,6583 +block_count,StringFastLocaleCompare,331,6526 +block_count,StringFastLocaleCompare,332,6526 +block_count,StringFastLocaleCompare,333,5247 +block_count,StringFastLocaleCompare,334,1278 block_count,StringFastLocaleCompare,335,842 block_count,StringFastLocaleCompare,336,436 block_count,StringFastLocaleCompare,337,0 @@ -60766,7 +60761,7 @@ block_count,StringToLowerCaseIntl,30,143 block_count,StringToLowerCaseIntl,31,143 block_count,StringToLowerCaseIntl,32,608 -block_count,StringToLowerCaseIntl,33,465 +block_count,StringToLowerCaseIntl,33,464 block_count,StringToLowerCaseIntl,34,143 block_count,StringToLowerCaseIntl,35,135 block_count,StringToLowerCaseIntl,36,7 @@ -60777,7 +60772,7 @@ block_count,StringToLowerCaseIntl,41,0 block_count,WideHandler,0,74 block_count,ExtraWideHandler,0,18 -block_count,LdarHandler,0,243 +block_count,LdarHandler,0,244 block_count,LdaZeroHandler,0,26 block_count,LdaZeroHandler,1,19 block_count,LdaZeroHandler,2,6 @@ -60795,13 +60790,13 @@ block_count,LdaTheHoleHandler,2,0 block_count,LdaTrueHandler,0,4 block_count,LdaFalseHandler,0,6 -block_count,LdaConstantHandler,0,23 +block_count,LdaConstantHandler,0,24 block_count,LdaConstantHandler,1,13 block_count,LdaConstantHandler,2,10 block_count,LdaContextSlotHandler,0,1 block_count,LdaContextSlotHandler,1,1 -block_count,LdaContextSlotHandler,2,1 -block_count,LdaContextSlotHandler,3,1 +block_count,LdaContextSlotHandler,2,2 +block_count,LdaContextSlotHandler,3,2 block_count,LdaContextSlotHandler,4,0 block_count,LdaContextSlotHandler,5,1 block_count,LdaContextSlotHandler,6,0 @@ -60862,24 +60857,24 @@ block_count,LdaScriptContextSlotHandler,48,0 block_count,LdaScriptContextSlotHandler,49,0 block_count,LdaScriptContextSlotHandler,50,0 -block_count,LdaImmutableContextSlotHandler,0,9 -block_count,LdaImmutableContextSlotHandler,1,6 -block_count,LdaImmutableContextSlotHandler,2,8 -block_count,LdaImmutableContextSlotHandler,3,8 -block_count,LdaImmutableContextSlotHandler,4,1 -block_count,LdaImmutableContextSlotHandler,5,6 +block_count,LdaImmutableContextSlotHandler,0,10 +block_count,LdaImmutableContextSlotHandler,1,7 +block_count,LdaImmutableContextSlotHandler,2,9 +block_count,LdaImmutableContextSlotHandler,3,9 +block_count,LdaImmutableContextSlotHandler,4,2 +block_count,LdaImmutableContextSlotHandler,5,7 block_count,LdaImmutableContextSlotHandler,6,0 block_count,LdaImmutableContextSlotHandler,7,3 -block_count,LdaImmutableContextSlotHandler,8,9 +block_count,LdaImmutableContextSlotHandler,8,10 block_count,LdaImmutableContextSlotHandler,9,0 -block_count,LdaImmutableContextSlotHandler,10,9 +block_count,LdaImmutableContextSlotHandler,10,10 block_count,LdaImmutableContextSlotHandler,11,2 -block_count,LdaImmutableContextSlotHandler,12,7 -block_count,LdaCurrentContextSlotHandler,0,19 +block_count,LdaImmutableContextSlotHandler,12,8 +block_count,LdaCurrentContextSlotHandler,0,20 block_count,LdaCurrentContextSlotHandler,1,0 -block_count,LdaCurrentContextSlotHandler,2,19 +block_count,LdaCurrentContextSlotHandler,2,20 block_count,LdaCurrentContextSlotHandler,3,8 -block_count,LdaCurrentContextSlotHandler,4,10 +block_count,LdaCurrentContextSlotHandler,4,11 block_count,LdaCurrentScriptContextSlotHandler,0,0 block_count,LdaCurrentScriptContextSlotHandler,1,0 block_count,LdaCurrentScriptContextSlotHandler,2,0 @@ -60927,7 +60922,7 @@ block_count,LdaImmutableCurrentContextSlotHandler,1,0 block_count,LdaImmutableCurrentContextSlotHandler,2,34 block_count,LdaImmutableCurrentContextSlotHandler,3,5 -block_count,LdaImmutableCurrentContextSlotHandler,4,28 +block_count,LdaImmutableCurrentContextSlotHandler,4,29 block_count,StarHandler,0,35 block_count,MovHandler,0,44 block_count,PushContextHandler,0,3 @@ -60936,13 +60931,13 @@ block_count,TestReferenceEqualHandler,1,1 block_count,TestReferenceEqualHandler,2,0 block_count,TestReferenceEqualHandler,3,1 -block_count,TestUndetectableHandler,0,2 +block_count,TestUndetectableHandler,0,1 block_count,TestUndetectableHandler,1,1 block_count,TestUndetectableHandler,2,1 block_count,TestUndetectableHandler,3,0 block_count,TestUndetectableHandler,4,1 block_count,TestUndetectableHandler,5,0 -block_count,TestUndetectableHandler,6,2 +block_count,TestUndetectableHandler,6,1 block_count,TestNullHandler,0,0 block_count,TestNullHandler,1,0 block_count,TestNullHandler,2,0 @@ -61002,13 +60997,13 @@ block_count,TestTypeOfHandler,48,1 block_count,TestTypeOfHandler,49,0 block_count,TestTypeOfHandler,50,1 -block_count,LdaGlobalHandler,0,55 -block_count,LdaGlobalHandler,1,45 -block_count,LdaGlobalHandler,2,44 +block_count,LdaGlobalHandler,0,54 +block_count,LdaGlobalHandler,1,44 +block_count,LdaGlobalHandler,2,43 block_count,LdaGlobalHandler,3,43 block_count,LdaGlobalHandler,4,43 block_count,LdaGlobalHandler,5,13 -block_count,LdaGlobalHandler,6,30 +block_count,LdaGlobalHandler,6,29 block_count,LdaGlobalHandler,7,0 block_count,LdaGlobalHandler,8,0 block_count,LdaGlobalHandler,9,0 @@ -61528,9 +61523,9 @@ block_count,StaContextSlotHandler,8,0 block_count,StaContextSlotHandler,9,0 block_count,StaContextSlotHandler,10,0 -block_count,StaCurrentContextSlotHandler,0,10 +block_count,StaCurrentContextSlotHandler,0,12 block_count,StaCurrentContextSlotHandler,1,0 -block_count,StaCurrentContextSlotHandler,2,10 +block_count,StaCurrentContextSlotHandler,2,12 block_count,StaScriptContextSlotHandler,0,0 block_count,StaScriptContextSlotHandler,1,0 block_count,StaScriptContextSlotHandler,2,0 @@ -62389,7 +62384,7 @@ block_count,StaLookupSlotHandler,3,0 block_count,StaLookupSlotHandler,4,0 block_count,StaLookupSlotHandler,5,0 -block_count,GetNamedPropertyHandler,0,164 +block_count,GetNamedPropertyHandler,0,163 block_count,GetNamedPropertyHandler,1,135 block_count,GetNamedPropertyHandler,2,135 block_count,GetNamedPropertyHandler,3,0 @@ -62398,16 +62393,16 @@ block_count,GetNamedPropertyHandler,6,0 block_count,GetNamedPropertyHandler,7,11 block_count,GetNamedPropertyHandler,8,5 -block_count,GetNamedPropertyHandler,9,5 +block_count,GetNamedPropertyHandler,9,6 block_count,GetNamedPropertyHandler,10,10 -block_count,GetNamedPropertyHandler,11,4 +block_count,GetNamedPropertyHandler,11,5 block_count,GetNamedPropertyHandler,12,4 block_count,GetNamedPropertyHandler,13,0 block_count,GetNamedPropertyHandler,14,5 -block_count,GetNamedPropertyHandler,15,124 +block_count,GetNamedPropertyHandler,15,123 block_count,GetNamedPropertyHandler,16,129 -block_count,GetNamedPropertyHandler,17,41 -block_count,GetNamedPropertyHandler,18,41 +block_count,GetNamedPropertyHandler,17,42 +block_count,GetNamedPropertyHandler,18,42 block_count,GetNamedPropertyHandler,19,38 block_count,GetNamedPropertyHandler,20,38 block_count,GetNamedPropertyHandler,21,0 @@ -62472,8 +62467,8 @@ block_count,GetNamedPropertyHandler,80,0 block_count,GetNamedPropertyHandler,81,0 block_count,GetNamedPropertyHandler,82,0 -block_count,GetNamedPropertyHandler,83,7 -block_count,GetNamedPropertyHandler,84,7 +block_count,GetNamedPropertyHandler,83,8 +block_count,GetNamedPropertyHandler,84,8 block_count,GetNamedPropertyHandler,85,0 block_count,GetNamedPropertyHandler,86,0 block_count,GetNamedPropertyHandler,87,0 @@ -62485,7 +62480,7 @@ block_count,GetNamedPropertyHandler,93,0 block_count,GetNamedPropertyHandler,94,0 block_count,GetNamedPropertyHandler,95,0 -block_count,GetNamedPropertyHandler,96,7 +block_count,GetNamedPropertyHandler,96,8 block_count,GetNamedPropertyHandler,97,0 block_count,GetNamedPropertyHandler,98,30 block_count,GetNamedPropertyHandler,99,38 @@ -62496,12 +62491,12 @@ block_count,GetNamedPropertyHandler,104,1 block_count,GetNamedPropertyHandler,105,38 block_count,GetNamedPropertyHandler,106,0 -block_count,GetNamedPropertyHandler,107,3 +block_count,GetNamedPropertyHandler,107,4 block_count,GetNamedPropertyHandler,108,0 block_count,GetNamedPropertyHandler,109,0 block_count,GetNamedPropertyHandler,110,0 -block_count,GetNamedPropertyHandler,111,87 -block_count,GetNamedPropertyHandler,112,126 +block_count,GetNamedPropertyHandler,111,86 +block_count,GetNamedPropertyHandler,112,125 block_count,GetNamedPropertyHandler,113,39 block_count,GetNamedPropertyHandler,114,6 block_count,GetNamedPropertyHandler,115,5 @@ -62637,12 +62632,12 @@ block_count,GetNamedPropertyHandler,245,0 block_count,GetNamedPropertyHandler,246,1 block_count,GetNamedPropertyHandler,247,32 -block_count,GetNamedPropertyHandler,248,87 -block_count,GetNamedPropertyHandler,249,87 +block_count,GetNamedPropertyHandler,248,85 +block_count,GetNamedPropertyHandler,249,85 block_count,GetNamedPropertyHandler,250,16 -block_count,GetNamedPropertyHandler,251,70 -block_count,GetNamedPropertyHandler,252,87 -block_count,GetNamedPropertyHandler,253,81 +block_count,GetNamedPropertyHandler,251,69 +block_count,GetNamedPropertyHandler,252,85 +block_count,GetNamedPropertyHandler,253,79 block_count,GetNamedPropertyHandler,254,5 block_count,GetNamedPropertyHandler,255,5 block_count,GetNamedPropertyHandler,256,5 @@ -62702,30 +62697,30 @@ block_count,GetNamedPropertyHandler,310,5 block_count,GetNamedPropertyHandler,311,0 block_count,GetNamedPropertyHandler,312,28 -block_count,GetNamedPropertyHandler,313,164 -block_count,GetNamedPropertyHandler,314,43 -block_count,GetNamedPropertyHandler,315,121 +block_count,GetNamedPropertyHandler,313,163 +block_count,GetNamedPropertyHandler,314,42 +block_count,GetNamedPropertyHandler,315,120 block_count,GetNamedPropertyFromSuperHandler,0,0 block_count,GetKeyedPropertyHandler,0,62 block_count,GetKeyedPropertyHandler,1,29 block_count,GetKeyedPropertyHandler,2,33 block_count,GetEnumeratedKeyedPropertyHandler,0,1 -block_count,SetNamedPropertyHandler,0,19 +block_count,SetNamedPropertyHandler,0,18 block_count,DefineNamedOwnPropertyHandler,0,4 -block_count,SetKeyedPropertyHandler,0,44 +block_count,SetKeyedPropertyHandler,0,43 block_count,DefineKeyedOwnPropertyHandler,0,0 block_count,StaInArrayLiteralHandler,0,4 block_count,DefineKeyedOwnPropertyInLiteralHandler,0,0 block_count,AddHandler,0,37 -block_count,AddHandler,1,15 +block_count,AddHandler,1,14 block_count,AddHandler,2,0 block_count,AddHandler,3,0 block_count,AddHandler,4,0 block_count,AddHandler,5,14 block_count,AddHandler,6,14 -block_count,AddHandler,7,14 +block_count,AddHandler,7,13 block_count,AddHandler,8,0 -block_count,AddHandler,9,14 +block_count,AddHandler,9,13 block_count,AddHandler,10,0 block_count,AddHandler,11,14 block_count,AddHandler,12,0 @@ -62735,9 +62730,9 @@ block_count,AddHandler,16,11 block_count,AddHandler,17,0 block_count,AddHandler,18,0 -block_count,AddHandler,19,9 -block_count,AddHandler,20,9 -block_count,AddHandler,21,8 +block_count,AddHandler,19,10 +block_count,AddHandler,20,10 +block_count,AddHandler,21,9 block_count,AddHandler,22,0 block_count,AddHandler,23,0 block_count,AddHandler,24,0 @@ -62755,7 +62750,7 @@ block_count,AddHandler,36,0 block_count,AddHandler,37,0 block_count,AddHandler,38,0 -block_count,AddHandler,39,8 +block_count,AddHandler,39,9 block_count,AddHandler,40,0 block_count,AddHandler,41,0 block_count,AddHandler,42,0 @@ -62767,9 +62762,9 @@ block_count,AddHandler,48,0 block_count,AddHandler,49,0 block_count,AddHandler,50,8 -block_count,AddHandler,51,7 +block_count,AddHandler,51,8 block_count,AddHandler,52,0 -block_count,AddHandler,53,7 +block_count,AddHandler,53,8 block_count,AddHandler,54,0 block_count,AddHandler,55,8 block_count,AddHandler,56,0 @@ -63367,8 +63362,8 @@ block_count,BitwiseXorHandler,93,3 block_count,BitwiseAndHandler,0,2 block_count,BitwiseAndHandler,1,1 -block_count,BitwiseAndHandler,2,1 -block_count,BitwiseAndHandler,3,1 +block_count,BitwiseAndHandler,2,0 +block_count,BitwiseAndHandler,3,0 block_count,BitwiseAndHandler,4,0 block_count,BitwiseAndHandler,5,0 block_count,BitwiseAndHandler,6,0 @@ -63416,7 +63411,7 @@ block_count,BitwiseAndHandler,48,0 block_count,BitwiseAndHandler,49,0 block_count,BitwiseAndHandler,50,0 -block_count,BitwiseAndHandler,51,1 +block_count,BitwiseAndHandler,51,0 block_count,BitwiseAndHandler,52,2 block_count,BitwiseAndHandler,53,1 block_count,BitwiseAndHandler,54,1 @@ -64209,9 +64204,9 @@ block_count,BitwiseAndSmiHandler,34,0 block_count,BitwiseAndSmiHandler,35,3 block_count,BitwiseAndSmiHandler,36,3 -block_count,BitwiseAndSmiHandler,37,3 +block_count,BitwiseAndSmiHandler,37,2 block_count,BitwiseAndSmiHandler,38,0 -block_count,BitwiseAndSmiHandler,39,3 +block_count,BitwiseAndSmiHandler,39,2 block_count,BitwiseAndSmiHandler,40,0 block_count,BitwiseAndSmiHandler,41,3 block_count,ShiftLeftSmiHandler,0,5 @@ -64390,7 +64385,7 @@ block_count,IncHandler,29,0 block_count,IncHandler,30,46 block_count,IncHandler,31,3 -block_count,IncHandler,32,42 +block_count,IncHandler,32,43 block_count,DecHandler,0,8 block_count,DecHandler,1,8 block_count,DecHandler,2,0 @@ -64816,10 +64811,10 @@ block_count,CallProperty0Handler,63,0 block_count,CallProperty0Handler,64,0 block_count,CallProperty0Handler,65,0 -block_count,CallProperty0Handler,66,12 +block_count,CallProperty0Handler,66,11 block_count,CallProperty0Handler,67,1 block_count,CallProperty0Handler,68,14 -block_count,CallProperty1Handler,0,29 +block_count,CallProperty1Handler,0,30 block_count,CallProperty1Handler,1,25 block_count,CallProperty1Handler,2,0 block_count,CallProperty1Handler,3,0 @@ -64887,7 +64882,7 @@ block_count,CallProperty1Handler,65,0 block_count,CallProperty1Handler,66,25 block_count,CallProperty1Handler,67,4 -block_count,CallProperty1Handler,68,29 +block_count,CallProperty1Handler,68,30 block_count,CallProperty2Handler,0,7 block_count,CallProperty2Handler,1,5 block_count,CallProperty2Handler,2,0 @@ -65230,7 +65225,7 @@ block_count,CallUndefinedReceiver2Handler,63,0 block_count,CallUndefinedReceiver2Handler,64,0 block_count,CallUndefinedReceiver2Handler,65,0 -block_count,CallUndefinedReceiver2Handler,66,5 +block_count,CallUndefinedReceiver2Handler,66,4 block_count,CallUndefinedReceiver2Handler,67,1 block_count,CallUndefinedReceiver2Handler,68,7 block_count,CallWithSpreadHandler,0,0 @@ -65495,8 +65490,8 @@ block_count,TestEqualHandler,0,13 block_count,TestEqualHandler,1,13 block_count,TestEqualHandler,2,11 -block_count,TestEqualHandler,3,7 -block_count,TestEqualHandler,4,7 +block_count,TestEqualHandler,3,6 +block_count,TestEqualHandler,4,6 block_count,TestEqualHandler,5,0 block_count,TestEqualHandler,6,0 block_count,TestEqualHandler,7,0 @@ -65640,16 +65635,16 @@ block_count,TestEqualHandler,145,2 block_count,TestEqualHandler,146,4 block_count,TestEqualHandler,147,13 -block_count,TestEqualHandler,148,13 +block_count,TestEqualHandler,148,12 block_count,TestEqualHandler,149,0 -block_count,TestEqualHandler,150,13 +block_count,TestEqualHandler,150,12 block_count,TestEqualHandler,151,0 block_count,TestEqualHandler,152,13 block_count,TestEqualStrictHandler,0,12 block_count,TestEqualStrictHandler,1,10 block_count,TestEqualStrictHandler,2,8 -block_count,TestEqualStrictHandler,3,7 -block_count,TestEqualStrictHandler,4,7 +block_count,TestEqualStrictHandler,3,8 +block_count,TestEqualStrictHandler,4,8 block_count,TestEqualStrictHandler,5,2 block_count,TestEqualStrictHandler,6,2 block_count,TestEqualStrictHandler,7,1 @@ -65739,13 +65734,13 @@ block_count,TestEqualStrictHandler,91,12 block_count,TestEqualStrictHandler,92,10 block_count,TestEqualStrictHandler,93,0 -block_count,TestEqualStrictHandler,94,9 +block_count,TestEqualStrictHandler,94,10 block_count,TestEqualStrictHandler,95,2 block_count,TestEqualStrictHandler,96,12 -block_count,TestLessThanHandler,0,38 -block_count,TestLessThanHandler,1,38 +block_count,TestLessThanHandler,0,39 +block_count,TestLessThanHandler,1,39 block_count,TestLessThanHandler,2,1 -block_count,TestLessThanHandler,3,1 +block_count,TestLessThanHandler,3,0 block_count,TestLessThanHandler,4,0 block_count,TestLessThanHandler,5,0 block_count,TestLessThanHandler,6,0 @@ -65832,7 +65827,7 @@ block_count,TestLessThanHandler,87,0 block_count,TestLessThanHandler,88,0 block_count,TestLessThanHandler,89,0 -block_count,TestLessThanHandler,90,37 +block_count,TestLessThanHandler,90,38 block_count,TestLessThanHandler,91,0 block_count,TestLessThanHandler,92,0 block_count,TestLessThanHandler,93,0 @@ -65844,7 +65839,7 @@ block_count,TestLessThanHandler,99,0 block_count,TestLessThanHandler,100,0 block_count,TestLessThanHandler,101,0 -block_count,TestLessThanHandler,102,37 +block_count,TestLessThanHandler,102,38 block_count,TestLessThanHandler,103,3 block_count,TestLessThanHandler,104,34 block_count,TestLessThanHandler,105,0 @@ -65857,14 +65852,14 @@ block_count,TestLessThanHandler,112,0 block_count,TestLessThanHandler,113,0 block_count,TestLessThanHandler,114,0 -block_count,TestLessThanHandler,115,3 +block_count,TestLessThanHandler,115,4 block_count,TestLessThanHandler,116,34 -block_count,TestLessThanHandler,117,38 -block_count,TestLessThanHandler,118,37 +block_count,TestLessThanHandler,117,39 +block_count,TestLessThanHandler,118,38 block_count,TestLessThanHandler,119,0 -block_count,TestLessThanHandler,120,37 +block_count,TestLessThanHandler,120,38 block_count,TestLessThanHandler,121,1 -block_count,TestLessThanHandler,122,38 +block_count,TestLessThanHandler,122,39 block_count,TestGreaterThanHandler,0,5 block_count,TestGreaterThanHandler,1,5 block_count,TestGreaterThanHandler,2,1 @@ -65981,11 +65976,11 @@ block_count,TestGreaterThanHandler,113,1 block_count,TestGreaterThanHandler,114,0 block_count,TestGreaterThanHandler,115,2 -block_count,TestGreaterThanHandler,116,3 +block_count,TestGreaterThanHandler,116,2 block_count,TestGreaterThanHandler,117,5 -block_count,TestGreaterThanHandler,118,5 +block_count,TestGreaterThanHandler,118,4 block_count,TestGreaterThanHandler,119,0 -block_count,TestGreaterThanHandler,120,5 +block_count,TestGreaterThanHandler,120,4 block_count,TestGreaterThanHandler,121,0 block_count,TestGreaterThanHandler,122,5 block_count,TestLessThanOrEqualHandler,0,2 @@ -66201,7 +66196,7 @@ block_count,TestGreaterThanOrEqualHandler,87,0 block_count,TestGreaterThanOrEqualHandler,88,0 block_count,TestGreaterThanOrEqualHandler,89,0 -block_count,TestGreaterThanOrEqualHandler,90,4 +block_count,TestGreaterThanOrEqualHandler,90,5 block_count,TestGreaterThanOrEqualHandler,91,0 block_count,TestGreaterThanOrEqualHandler,92,0 block_count,TestGreaterThanOrEqualHandler,93,0 @@ -66213,7 +66208,7 @@ block_count,TestGreaterThanOrEqualHandler,99,0 block_count,TestGreaterThanOrEqualHandler,100,0 block_count,TestGreaterThanOrEqualHandler,101,0 -block_count,TestGreaterThanOrEqualHandler,102,4 +block_count,TestGreaterThanOrEqualHandler,102,5 block_count,TestGreaterThanOrEqualHandler,103,3 block_count,TestGreaterThanOrEqualHandler,104,1 block_count,TestGreaterThanOrEqualHandler,105,0 @@ -66229,9 +66224,9 @@ block_count,TestGreaterThanOrEqualHandler,115,3 block_count,TestGreaterThanOrEqualHandler,116,1 block_count,TestGreaterThanOrEqualHandler,117,5 -block_count,TestGreaterThanOrEqualHandler,118,4 +block_count,TestGreaterThanOrEqualHandler,118,5 block_count,TestGreaterThanOrEqualHandler,119,0 -block_count,TestGreaterThanOrEqualHandler,120,4 +block_count,TestGreaterThanOrEqualHandler,120,5 block_count,TestGreaterThanOrEqualHandler,121,0 block_count,TestGreaterThanOrEqualHandler,122,5 block_count,TestInstanceOfHandler,0,2 @@ -66309,19 +66304,19 @@ block_count,ToNumberHandler,8,0 block_count,ToNumberHandler,9,0 block_count,ToNumberHandler,10,0 -block_count,ToNumericHandler,0,17 +block_count,ToNumericHandler,0,16 block_count,ToNumericHandler,1,0 block_count,ToNumericHandler,2,0 block_count,ToNumericHandler,3,0 block_count,ToNumericHandler,4,0 block_count,ToNumericHandler,5,0 -block_count,ToNumericHandler,6,17 -block_count,ToNumericHandler,7,17 +block_count,ToNumericHandler,6,16 +block_count,ToNumericHandler,7,16 block_count,ToNumericHandler,8,16 block_count,ToNumericHandler,9,0 block_count,ToNumericHandler,10,16 block_count,ToNumericHandler,11,0 -block_count,ToNumericHandler,12,17 +block_count,ToNumericHandler,12,16 block_count,ToObjectHandler,0,0 block_count,ToStringHandler,0,0 block_count,ToStringHandler,1,0 @@ -66679,26 +66674,26 @@ block_count,CreateClosureHandler,7,6 block_count,CreateBlockContextHandler,0,0 block_count,CreateCatchContextHandler,0,0 -block_count,CreateFunctionContextHandler,0,2 -block_count,CreateFunctionContextHandler,1,2 +block_count,CreateFunctionContextHandler,0,3 +block_count,CreateFunctionContextHandler,1,3 block_count,CreateFunctionContextHandler,2,0 -block_count,CreateFunctionContextHandler,3,2 +block_count,CreateFunctionContextHandler,3,3 block_count,CreateFunctionContextHandler,4,0 block_count,CreateFunctionContextHandler,5,0 -block_count,CreateFunctionContextHandler,6,2 +block_count,CreateFunctionContextHandler,6,3 block_count,CreateFunctionContextHandler,7,0 -block_count,CreateFunctionContextHandler,8,2 +block_count,CreateFunctionContextHandler,8,3 block_count,CreateFunctionContextHandler,9,0 -block_count,CreateFunctionContextHandler,10,2 +block_count,CreateFunctionContextHandler,10,3 block_count,CreateFunctionContextHandler,11,1 block_count,CreateFunctionContextHandler,12,1 -block_count,CreateFunctionContextHandler,13,2 -block_count,CreateFunctionContextHandler,14,1 +block_count,CreateFunctionContextHandler,13,3 +block_count,CreateFunctionContextHandler,14,2 block_count,CreateFunctionContextHandler,15,1 -block_count,CreateFunctionContextHandler,16,2 -block_count,CreateFunctionContextHandler,17,0 +block_count,CreateFunctionContextHandler,16,3 +block_count,CreateFunctionContextHandler,17,1 block_count,CreateFunctionContextHandler,18,2 -block_count,CreateFunctionContextHandler,19,2 +block_count,CreateFunctionContextHandler,19,3 block_count,CreateMappedArgumentsHandler,0,0 block_count,CreateMappedArgumentsHandler,1,0 block_count,CreateMappedArgumentsHandler,2,0 @@ -66868,27 +66863,27 @@ block_count,CreateRestParameterHandler,34,0 block_count,CreateRestParameterHandler,35,0 block_count,CreateRestParameterHandler,36,0 -block_count,JumpLoopHandler,0,52 +block_count,JumpLoopHandler,0,53 block_count,JumpLoopHandler,1,51 block_count,JumpLoopHandler,2,1 block_count,JumpLoopHandler,3,0 block_count,JumpLoopHandler,4,1 block_count,JumpLoopHandler,5,51 -block_count,JumpLoopHandler,6,3 +block_count,JumpLoopHandler,6,4 block_count,JumpLoopHandler,7,0 block_count,JumpLoopHandler,8,0 block_count,JumpLoopHandler,9,0 -block_count,JumpLoopHandler,10,3 -block_count,JumpLoopHandler,11,3 -block_count,JumpLoopHandler,12,3 -block_count,JumpLoopHandler,13,3 +block_count,JumpLoopHandler,10,4 +block_count,JumpLoopHandler,11,4 +block_count,JumpLoopHandler,12,4 +block_count,JumpLoopHandler,13,4 block_count,JumpLoopHandler,14,0 block_count,JumpLoopHandler,15,0 -block_count,JumpLoopHandler,16,3 -block_count,JumpLoopHandler,17,3 +block_count,JumpLoopHandler,16,4 +block_count,JumpLoopHandler,17,4 block_count,JumpLoopHandler,18,0 -block_count,JumpLoopHandler,19,3 -block_count,JumpLoopHandler,20,3 +block_count,JumpLoopHandler,19,4 +block_count,JumpLoopHandler,20,4 block_count,JumpLoopHandler,21,0 block_count,JumpLoopHandler,22,0 block_count,JumpLoopHandler,23,0 @@ -66913,10 +66908,10 @@ block_count,JumpLoopHandler,42,0 block_count,JumpLoopHandler,43,0 block_count,JumpLoopHandler,44,0 -block_count,JumpLoopHandler,45,48 +block_count,JumpLoopHandler,45,49 block_count,JumpLoopHandler,46,0 -block_count,JumpLoopHandler,47,48 -block_count,JumpLoopHandler,48,48 +block_count,JumpLoopHandler,47,49 +block_count,JumpLoopHandler,48,49 block_count,JumpHandler,0,9 block_count,JumpConstantHandler,0,0 block_count,JumpIfUndefinedConstantHandler,0,0 @@ -67029,12 +67024,12 @@ block_count,JumpIfToBooleanFalseHandler,20,0 block_count,JumpIfToBooleanFalseHandler,21,21 block_count,JumpIfToBooleanFalseHandler,22,8 -block_count,JumpIfTrueHandler,0,12 -block_count,JumpIfTrueHandler,1,8 +block_count,JumpIfTrueHandler,0,13 +block_count,JumpIfTrueHandler,1,9 block_count,JumpIfTrueHandler,2,3 -block_count,JumpIfFalseHandler,0,67 +block_count,JumpIfFalseHandler,0,68 block_count,JumpIfFalseHandler,1,43 -block_count,JumpIfFalseHandler,2,24 +block_count,JumpIfFalseHandler,2,25 block_count,JumpIfNullHandler,0,0 block_count,JumpIfNullHandler,1,0 block_count,JumpIfNullHandler,2,0 @@ -67140,7 +67135,7 @@ block_count,ReThrowHandler,0,0 block_count,ReturnHandler,0,43 block_count,ReturnHandler,1,0 -block_count,ReturnHandler,2,43 +block_count,ReturnHandler,2,42 block_count,ThrowReferenceErrorIfHoleHandler,0,1 block_count,ThrowReferenceErrorIfHoleHandler,1,1 block_count,ThrowReferenceErrorIfHoleHandler,2,0 @@ -67175,7 +67170,7 @@ block_count,ResumeGeneratorHandler,6,0 block_count,ResumeGeneratorHandler,7,0 block_count,GetIteratorHandler,0,0 -block_count,ShortStarHandler,0,122 +block_count,ShortStarHandler,0,123 block_count,LdarWideHandler,0,0 block_count,LdaSmiWideHandler,0,12 block_count,LdaConstantWideHandler,0,1 diff -Nru chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x86.profile chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86.profile --- chromium-134.0.6998.35/v8/tools/builtins-pgo/profiles/x86.profile 2025-02-25 19:55:16.000000000 +0000 +++ chromium-134.0.6998.88/v8/tools/builtins-pgo/profiles/x86.profile 2025-03-07 21:29:53.000000000 +0000 @@ -13,6 +13,7 @@ block_hint,RecordWriteIgnoreFP,4,9,1 block_hint,RecordWriteIgnoreFP,6,5,1 block_hint,RecordWriteIgnoreFP,7,8,1 +block_hint,RecordWriteIgnoreFP,25,13,1 block_hint,RecordWriteIgnoreFP,28,27,0 block_hint,RecordWriteIgnoreFP,53,45,0 block_hint,RecordWriteIgnoreFP,48,47,0 @@ -520,7 +521,6 @@ block_hint,StoreIC_NoFeedback,160,159,1 block_hint,StoreIC_NoFeedback,166,165,1 block_hint,StoreIC_NoFeedback,171,170,0 -block_hint,StoreIC_NoFeedback,192,189,1 block_hint,StoreIC_NoFeedback,191,190,0 block_hint,StoreIC_NoFeedback,287,194,0 block_hint,StoreIC_NoFeedback,197,200,0 @@ -753,6 +753,18 @@ block_hint,ElementsTransitionAndStore_InBounds,633,632,0 block_hint,ElementsTransitionAndStore_InBounds,635,634,0 block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,396,386,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,399,404,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,401,400,1 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,403,402,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,442,414,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,440,416,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,419,418,1 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,428,429,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,437,436,0 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,454,444,1 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,452,453,1 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,487,463,1 +block_hint,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,485,481,1 block_hint,KeyedHasIC_PolymorphicName,1,2,1 block_hint,KeyedHasIC_PolymorphicName,6,7,1 block_hint,KeyedHasIC_PolymorphicName,56,10,0 @@ -1080,6 +1092,7 @@ block_hint,ExtractFastJSArray,11,10,1 block_hint,ExtractFastJSArray,16,15,0 block_hint,ExtractFastJSArray,27,26,0 +block_hint,ExtractFastJSArray,29,28,1 block_hint,ExtractFastJSArray,33,34,1 block_hint,ExtractFastJSArray,47,46,0 block_hint,ExtractFastJSArray,68,67,1 @@ -1545,6 +1558,7 @@ block_hint,StoreGlobalIC,20,3,0 block_hint,StoreGlobalIC,19,4,0 block_hint,StoreGlobalIC,16,5,0 +block_hint,StoreGlobalIC,6,15,0 block_hint,StoreGlobalIC,8,11,1 block_hint,StoreGlobalIC,10,9,1 block_hint,StoreGlobalIC,13,14,0 @@ -1557,7 +1571,6 @@ block_hint,StoreIC,7,8,0 block_hint,StoreIC,11,10,1 block_hint,StoreIC,13,12,0 -block_hint,StoreIC,16,17,1 block_hint,StoreIC,27,28,1 block_hint,StoreIC,172,34,0 block_hint,StoreIC,38,35,0 @@ -1707,6 +1720,7 @@ block_hint,KeyedStoreIC,442,4,0 block_hint,KeyedStoreIC,440,5,0 block_hint,KeyedStoreIC,7,8,0 +block_hint,KeyedStoreIC,15,16,1 block_hint,KeyedStoreIC,22,23,1 block_hint,KeyedStoreIC,27,313,1 block_hint,KeyedStoreIC,203,28,0 @@ -2087,6 +2101,7 @@ block_hint,Equal_Baseline,82,83,0 block_hint,Equal_Baseline,98,92,0 block_hint,Equal_Baseline,93,97,1 +block_hint,Equal_Baseline,103,104,0 block_hint,Equal_Baseline,109,110,0 block_hint,Equal_Baseline,139,125,0 block_hint,Equal_Baseline,130,129,0 @@ -2648,10 +2663,12 @@ block_hint,StringAdd_CheckNone,12,11,1 block_hint,StringAdd_CheckNone,110,20,0 block_hint,StringAdd_CheckNone,21,45,0 +block_hint,StringAdd_CheckNone,35,22,1 block_hint,StringAdd_CheckNone,23,26,0 block_hint,StringAdd_CheckNone,25,24,1 block_hint,StringAdd_CheckNone,33,28,1 block_hint,StringAdd_CheckNone,29,32,0 +block_hint,StringAdd_CheckNone,40,39,1 block_hint,StringAdd_CheckNone,46,77,1 block_hint,StringAdd_CheckNone,76,47,0 block_hint,StringAdd_CheckNone,48,51,0 @@ -3361,6 +3378,7 @@ block_hint,ArrayPrototypeSplice,524,509,1 block_hint,ArrayPrototypeSplice,511,514,0 block_hint,ArrayPrototypeSplice,522,518,1 +block_hint,ArrayPrototypeSplice,556,545,0 block_hint,ArrayPrototypeSplice,591,590,0 block_hint,ArrayPrototypeSplice,594,597,0 block_hint,ArrayPrototypeSplice,600,599,1 @@ -3719,7 +3737,6 @@ block_hint,MathPow,2,1,1 block_hint,MathPow,6,7,1 block_hint,MathPow,12,13,1 -block_hint,MathPow,21,20,0 block_hint,MathPow,24,23,0 block_hint,MathMax,2,1,1 block_hint,MathMax,7,6,0 @@ -5262,7 +5279,6 @@ block_hint,DivSmiHandler,15,2,0 block_hint,DivSmiHandler,4,3,0 block_hint,DivSmiHandler,9,8,0 -block_hint,DivSmiHandler,13,14,1 block_hint,DivSmiHandler,25,22,1 block_hint,DivSmiHandler,24,23,0 block_hint,DivSmiHandler,28,38,1 @@ -5431,7 +5447,6 @@ block_hint,TestEqualStrictHandler,11,10,1 block_hint,TestEqualStrictHandler,13,12,1 block_hint,TestEqualStrictHandler,24,19,0 -block_hint,TestEqualStrictHandler,33,32,1 block_hint,TestEqualStrictHandler,37,38,0 block_hint,TestEqualStrictHandler,55,54,0 block_hint,TestEqualStrictHandler,85,71,0 @@ -5470,7 +5485,9 @@ block_hint,CreateArrayLiteralHandler,12,15,1 block_hint,CreateArrayLiteralHandler,14,13,1 block_hint,CreateArrayLiteralHandler,19,18,0 -block_hint,CreateArrayLiteralHandler,30,29,0 +block_hint,CreateArrayLiteralHandler,32,31,1 +block_hint,CreateArrayLiteralHandler,34,33,0 +block_hint,CreateArrayLiteralHandler,40,39,1 block_hint,CreateArrayLiteralHandler,71,46,0 block_hint,CreateArrayLiteralHandler,48,47,1 block_hint,CreateArrayLiteralHandler,50,49,1 @@ -5589,7 +5606,6 @@ block_hint,GetNamedPropertyWideHandler,259,249,0 block_hint,AddWideHandler,2,5,0 block_hint,AddWideHandler,12,6,0 -block_hint,AddWideHandler,16,17,1 block_hint,AddWideHandler,57,20,0 block_hint,AddWideHandler,21,56,1 block_hint,AddWideHandler,50,40,1 @@ -5691,15 +5707,15 @@ block_hint,BitwiseAndSmiExtraWideHandler,27,26,0 block_hint,BitwiseAndSmiExtraWideHandler,41,38,1 block_hint,CallUndefinedReceiver1ExtraWideHandler,1,67,0 -builtin_count,RecordWriteSaveFP,2045 -builtin_count,RecordWriteIgnoreFP,0 +builtin_count,RecordWriteSaveFP,2023 +builtin_count,RecordWriteIgnoreFP,1 builtin_count,EphemeronKeyBarrierSaveFP,0 builtin_count,AdaptorWithBuiltinExitFrame0,116 builtin_count,AdaptorWithBuiltinExitFrame1,4 builtin_count,AdaptorWithBuiltinExitFrame2,0 builtin_count,AdaptorWithBuiltinExitFrame3,8 -builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,385 -builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1432 +builtin_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,387 +builtin_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1436 builtin_count,Call_ReceiverIsAny_Baseline_Compact,5 builtin_count,CallProxy,0 builtin_count,CallWithSpread,19 @@ -5710,7 +5726,7 @@ builtin_count,ConstructWithSpread_Baseline,0 builtin_count,ConstructForwardAllArgs_Baseline,1 builtin_count,Construct_Baseline,123 -builtin_count,FastNewObject,369 +builtin_count,FastNewObject,389 builtin_count,FastNewClosure,97 builtin_count,StringEqual,780 builtin_count,StringGreaterThan,0 @@ -5734,7 +5750,7 @@ builtin_count,GrowFastSmiOrObjectElements,351 builtin_count,ToNumber,0 builtin_count,ToNumber_Baseline,0 -builtin_count,ToNumeric_Baseline,86 +builtin_count,ToNumeric_Baseline,87 builtin_count,ToNumberConvertBigInt,3 builtin_count,Typeof,30 builtin_count,Typeof_Baseline,2 @@ -5749,8 +5765,8 @@ builtin_count,StoreIC_NoFeedback,6 builtin_count,DefineNamedOwnIC_NoFeedback,4 builtin_count,KeyedLoadIC_SloppyArguments,2 -builtin_count,StoreFastElementIC_InBounds,460 -builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,49 +builtin_count,StoreFastElementIC_InBounds,463 +builtin_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,47 builtin_count,StoreFastElementIC_NoTransitionHandleCOW,0 builtin_count,ElementsTransitionAndStore_InBounds,1 builtin_count,ElementsTransitionAndStore_NoTransitionGrowAndHandleCOW,0 @@ -5792,7 +5808,7 @@ builtin_count,ArrayPrototypeEntries,0 builtin_count,ArrayPrototypeKeys,0 builtin_count,ArrayPrototypeValues,33 -builtin_count,ArrayIteratorPrototypeNext,77 +builtin_count,ArrayIteratorPrototypeNext,79 builtin_count,AsyncFunctionEnter,0 builtin_count,AsyncFunctionResolve,0 builtin_count,AsyncFunctionAwait,4 @@ -5817,47 +5833,47 @@ builtin_count,CallIteratorWithFeedbackLazyDeoptContinuation,0 builtin_count,GlobalIsFinite,0 builtin_count,GlobalIsNaN,0 -builtin_count,LoadIC,5696 +builtin_count,LoadIC,5684 builtin_count,LoadIC_Megamorphic,10000 -builtin_count,LoadIC_Noninlined,5 -builtin_count,LoadICTrampoline,340 -builtin_count,LoadICBaseline,5112 -builtin_count,LoadICTrampoline_Megamorphic,6354 +builtin_count,LoadIC_Noninlined,6 +builtin_count,LoadICTrampoline,339 +builtin_count,LoadICBaseline,5101 +builtin_count,LoadICTrampoline_Megamorphic,6353 builtin_count,LoadSuperIC,5 builtin_count,LoadSuperICBaseline,5 -builtin_count,KeyedLoadIC,954 +builtin_count,KeyedLoadIC,960 builtin_count,EnumeratedKeyedLoadIC,7 builtin_count,KeyedLoadIC_Megamorphic,2428 builtin_count,KeyedLoadICTrampoline,1 -builtin_count,KeyedLoadICBaseline,888 +builtin_count,KeyedLoadICBaseline,895 builtin_count,EnumeratedKeyedLoadICBaseline,5 -builtin_count,KeyedLoadICTrampoline_Megamorphic,1221 -builtin_count,StoreGlobalIC,97 -builtin_count,StoreGlobalICTrampoline,0 -builtin_count,StoreGlobalICBaseline,7 -builtin_count,StoreIC,682 -builtin_count,StoreIC_Megamorphic,1306 +builtin_count,KeyedLoadICTrampoline_Megamorphic,1220 +builtin_count,StoreGlobalIC,321 +builtin_count,StoreGlobalICTrampoline,224 +builtin_count,StoreGlobalICBaseline,6 +builtin_count,StoreIC,686 +builtin_count,StoreIC_Megamorphic,1305 builtin_count,StoreICTrampoline,19 -builtin_count,StoreICTrampoline_Megamorphic,630 -builtin_count,StoreICBaseline,619 -builtin_count,DefineNamedOwnIC,80 -builtin_count,DefineNamedOwnICBaseline,73 +builtin_count,StoreICTrampoline_Megamorphic,629 +builtin_count,StoreICBaseline,623 +builtin_count,DefineNamedOwnIC,81 +builtin_count,DefineNamedOwnICBaseline,75 builtin_count,KeyedStoreIC,497 builtin_count,KeyedStoreICTrampoline,1 -builtin_count,KeyedStoreICTrampoline_Megamorphic,309 -builtin_count,KeyedStoreICBaseline,451 +builtin_count,KeyedStoreICTrampoline_Megamorphic,310 +builtin_count,KeyedStoreICBaseline,450 builtin_count,DefineKeyedOwnIC,2 -builtin_count,StoreInArrayLiteralIC,42 -builtin_count,StoreInArrayLiteralICBaseline,37 -builtin_count,LoadGlobalIC,1043 +builtin_count,StoreInArrayLiteralIC,44 +builtin_count,StoreInArrayLiteralICBaseline,39 +builtin_count,LoadGlobalIC,1204 builtin_count,LoadGlobalICInsideTypeof,2 -builtin_count,LoadGlobalICTrampoline,97 -builtin_count,LoadGlobalICBaseline,880 +builtin_count,LoadGlobalICTrampoline,277 +builtin_count,LoadGlobalICBaseline,881 builtin_count,LoadGlobalICInsideTypeofTrampoline,0 builtin_count,LoadGlobalICInsideTypeofBaseline,2 builtin_count,LookupGlobalICBaseline,2 builtin_count,LookupGlobalICInsideTypeofBaseline,0 -builtin_count,KeyedHasIC,727 +builtin_count,KeyedHasIC,726 builtin_count,KeyedHasICBaseline,6 builtin_count,KeyedHasIC_Megamorphic,725 builtin_count,IterableToList,0 @@ -5877,11 +5893,11 @@ builtin_count,MapPrototypeValues,0 builtin_count,MapIteratorPrototypeNext,9 builtin_count,MapIteratorToList,0 -builtin_count,Add_Baseline,571 -builtin_count,AddSmi_Baseline,553 -builtin_count,Subtract_Baseline,123 -builtin_count,SubtractSmi_Baseline,71 -builtin_count,Multiply_Baseline,181 +builtin_count,Add_Baseline,574 +builtin_count,AddSmi_Baseline,555 +builtin_count,Subtract_Baseline,124 +builtin_count,SubtractSmi_Baseline,72 +builtin_count,Multiply_Baseline,185 builtin_count,MultiplySmi_Baseline,29 builtin_count,Divide_Baseline,15 builtin_count,DivideSmi_Baseline,5 @@ -5889,26 +5905,26 @@ builtin_count,ModulusSmi_Baseline,4 builtin_count,Exponentiate_Baseline,0 builtin_count,BitwiseAnd_Baseline,32 -builtin_count,BitwiseAndSmi_Baseline,114 -builtin_count,BitwiseOr_Baseline,58 -builtin_count,BitwiseOrSmi_Baseline,284 -builtin_count,BitwiseXor_Baseline,40 +builtin_count,BitwiseAndSmi_Baseline,116 +builtin_count,BitwiseOr_Baseline,59 +builtin_count,BitwiseOrSmi_Baseline,285 +builtin_count,BitwiseXor_Baseline,41 builtin_count,BitwiseXorSmi_Baseline,1 builtin_count,ShiftLeft_Baseline,5 -builtin_count,ShiftLeftSmi_Baseline,76 +builtin_count,ShiftLeftSmi_Baseline,78 builtin_count,ShiftRight_Baseline,7 -builtin_count,ShiftRightSmi_Baseline,236 +builtin_count,ShiftRightSmi_Baseline,238 builtin_count,ShiftRightLogical_Baseline,1 builtin_count,ShiftRightLogicalSmi_Baseline,18 -builtin_count,Equal_Baseline,337 -builtin_count,StrictEqual_Baseline,502 -builtin_count,LessThan_Baseline,487 -builtin_count,GreaterThan_Baseline,166 -builtin_count,LessThanOrEqual_Baseline,65 -builtin_count,GreaterThanOrEqual_Baseline,121 +builtin_count,Equal_Baseline,334 +builtin_count,StrictEqual_Baseline,497 +builtin_count,LessThan_Baseline,478 +builtin_count,GreaterThan_Baseline,164 +builtin_count,LessThanOrEqual_Baseline,62 +builtin_count,GreaterThanOrEqual_Baseline,119 builtin_count,BitwiseNot_Baseline,6 -builtin_count,Decrement_Baseline,51 -builtin_count,Increment_Baseline,324 +builtin_count,Decrement_Baseline,54 +builtin_count,Increment_Baseline,322 builtin_count,Negate_Baseline,13 builtin_count,ObjectAssign,2 builtin_count,ObjectCreate,3 @@ -5920,7 +5936,7 @@ builtin_count,ObjectPrototypeHasOwnProperty,242 builtin_count,ObjectToString,63 builtin_count,InstanceOf,11 -builtin_count,InstanceOf_Baseline,76 +builtin_count,InstanceOf_Baseline,77 builtin_count,ForInEnumerate,59 builtin_count,ForInPrepare,1 builtin_count,ForInFilter,223 @@ -5941,7 +5957,7 @@ builtin_count,StringPrototypeSplit,54 builtin_count,TypedArrayConstructor,2 builtin_count,TypedArrayPrototypeByteLength,0 -builtin_count,TypedArrayPrototypeLength,13 +builtin_count,TypedArrayPrototypeLength,14 builtin_count,TypedArrayPrototypeToStringTag,0 builtin_count,WasmToJsWrapperCSA,0 builtin_count,WeakMapConstructor,0 @@ -5960,14 +5976,14 @@ builtin_count,AsyncGeneratorAwait,7 builtin_count,AsyncGeneratorAwaitResolveClosure,7 builtin_count,AsyncGeneratorYieldWithAwaitResolveClosure,8 -builtin_count,StringAdd_CheckNone,8654 +builtin_count,StringAdd_CheckNone,8652 builtin_count,SubString,1671 -builtin_count,GetProperty,765 +builtin_count,GetProperty,767 builtin_count,GetPropertyWithReceiver,17 builtin_count,SetProperty,0 builtin_count,CreateDataProperty,1 builtin_count,GetOwnPropertyDescriptor,0 -builtin_count,FindNonDefaultConstructorOrConstruct,16 +builtin_count,FindNonDefaultConstructorOrConstruct,17 builtin_count,OrdinaryGetOwnPropertyDescriptor,0 builtin_count,ArrayPrototypeConcat,100 builtin_count,ArrayEvery,0 @@ -6005,18 +6021,18 @@ builtin_count,BooleanPrototypeToString,0 builtin_count,ToString,74 builtin_count,StringPrototypeToString,19 -builtin_count,StringPrototypeCharAt,123 +builtin_count,StringPrototypeCharAt,124 builtin_count,StringPrototypeCharCodeAt,117 builtin_count,StringPrototypeCodePointAt,0 builtin_count,StringPrototypeConcat,0 builtin_count,StringConstructor,33 builtin_count,StringAddConvertLeft,17 -builtin_count,StringAddConvertRight,201 +builtin_count,StringAddConvertRight,200 builtin_count,StringCharAt,9 -builtin_count,FastNewClosureBaseline,87 +builtin_count,FastNewClosureBaseline,88 builtin_count,FastNewFunctionContextFunction,93 builtin_count,CreateRegExpLiteral,41 -builtin_count,CreateShallowArrayLiteral,19 +builtin_count,CreateShallowArrayLiteral,20 builtin_count,CreateEmptyArrayLiteral,29 builtin_count,CreateShallowObjectLiteral,32 builtin_count,ObjectConstructor,24 @@ -6028,7 +6044,7 @@ builtin_count,ToNumeric,16 builtin_count,NumberToString,1526 builtin_count,ToBoolean,36 -builtin_count,ToBooleanForBaselineJump,1093 +builtin_count,ToBooleanForBaselineJump,1103 builtin_count,ToLength,2 builtin_count,ToName,48 builtin_count,ToObject,248 @@ -6042,12 +6058,12 @@ builtin_count,DataViewPrototypeGetFloat64,0 builtin_count,DataViewPrototypeSetUint32,0 builtin_count,DataViewPrototypeSetFloat64,0 -builtin_count,FunctionPrototypeHasInstance,90 +builtin_count,FunctionPrototypeHasInstance,92 builtin_count,FastFunctionPrototypeBind,2 builtin_count,ForInNext,7 builtin_count,GetIteratorWithFeedback,0 builtin_count,GetIteratorBaseline,34 -builtin_count,CallIteratorWithFeedback,34 +builtin_count,CallIteratorWithFeedback,35 builtin_count,MathAbs,2 builtin_count,MathCeil,0 builtin_count,MathFloor,4 @@ -6074,7 +6090,7 @@ builtin_count,NumberParseFloat,12 builtin_count,ParseInt,136 builtin_count,NumberParseInt,5 -builtin_count,Add,14 +builtin_count,Add,13 builtin_count,Subtract,0 builtin_count,Multiply,0 builtin_count,Divide,0 @@ -6113,7 +6129,7 @@ builtin_count,ReflectGet,0 builtin_count,ReflectHas,0 builtin_count,RegExpPrototypeExec,423 -builtin_count,RegExpMatchFast,1252 +builtin_count,RegExpMatchFast,1251 builtin_count,RegExpReplace,199 builtin_count,RegExpPrototypeReplace,0 builtin_count,RegExpSearchFast,1 @@ -6135,7 +6151,7 @@ builtin_count,StringPrototypeIndexOf,5 builtin_count,StringPrototypeIterator,0 builtin_count,StringIteratorPrototypeNext,0 -builtin_count,StringPrototypeMatch,1252 +builtin_count,StringPrototypeMatch,1251 builtin_count,StringPrototypeSearch,1 builtin_count,StringRepeat,0 builtin_count,StringPrototypeSlice,11 @@ -6150,8 +6166,8 @@ builtin_count,TypedArrayPrototypeSubArray,1 builtin_count,NewSloppyArgumentsElements,40 builtin_count,NewStrictArgumentsElements,0 -builtin_count,NewRestArgumentsElements,15 -builtin_count,FastNewSloppyArguments,5 +builtin_count,NewRestArgumentsElements,14 +builtin_count,FastNewSloppyArguments,6 builtin_count,FastNewStrictArguments,3 builtin_count,FastNewRestArguments,1 builtin_count,AllocateIfMutableHeapNumberScriptContextSlot,1 @@ -6166,7 +6182,7 @@ builtin_count,Store_FastObjectElements_0,243 builtin_count,Store_FastDoubleElements_0,0 builtin_count,SortCompareDefault,3 -builtin_count,SortCompareUserFn,781 +builtin_count,SortCompareUserFn,780 builtin_count,Copy,2 builtin_count,MergeAt,1 builtin_count,GallopLeft,1 @@ -6194,15 +6210,15 @@ builtin_count,LdaNullHandler,2 builtin_count,LdaTheHoleHandler,0 builtin_count,LdaTrueHandler,4 -builtin_count,LdaFalseHandler,6 +builtin_count,LdaFalseHandler,5 builtin_count,LdaConstantHandler,24 builtin_count,LdaContextSlotHandler,1 builtin_count,LdaScriptContextSlotHandler,0 -builtin_count,LdaImmutableContextSlotHandler,10 -builtin_count,LdaCurrentContextSlotHandler,20 +builtin_count,LdaImmutableContextSlotHandler,9 +builtin_count,LdaCurrentContextSlotHandler,19 builtin_count,LdaCurrentScriptContextSlotHandler,0 -builtin_count,LdaImmutableCurrentContextSlotHandler,34 -builtin_count,StarHandler,35 +builtin_count,LdaImmutableCurrentContextSlotHandler,35 +builtin_count,StarHandler,34 builtin_count,MovHandler,45 builtin_count,PushContextHandler,3 builtin_count,PopContextHandler,0 @@ -6215,23 +6231,23 @@ builtin_count,LdaGlobalInsideTypeofHandler,0 builtin_count,StaGlobalHandler,2 builtin_count,StaContextSlotHandler,0 -builtin_count,StaCurrentContextSlotHandler,12 +builtin_count,StaCurrentContextSlotHandler,10 builtin_count,StaScriptContextSlotHandler,0 builtin_count,StaCurrentScriptContextSlotHandler,0 builtin_count,LdaLookupGlobalSlotHandler,1 builtin_count,LdaLookupGlobalSlotInsideTypeofHandler,0 builtin_count,StaLookupSlotHandler,0 -builtin_count,GetNamedPropertyHandler,167 +builtin_count,GetNamedPropertyHandler,168 builtin_count,GetNamedPropertyFromSuperHandler,0 builtin_count,GetKeyedPropertyHandler,63 builtin_count,GetEnumeratedKeyedPropertyHandler,1 builtin_count,SetNamedPropertyHandler,20 builtin_count,DefineNamedOwnPropertyHandler,4 -builtin_count,SetKeyedPropertyHandler,43 +builtin_count,SetKeyedPropertyHandler,44 builtin_count,DefineKeyedOwnPropertyHandler,0 builtin_count,StaInArrayLiteralHandler,4 builtin_count,DefineKeyedOwnPropertyInLiteralHandler,0 -builtin_count,AddHandler,37 +builtin_count,AddHandler,38 builtin_count,SubHandler,7 builtin_count,MulHandler,17 builtin_count,DivHandler,1 @@ -6254,7 +6270,7 @@ builtin_count,ShiftLeftSmiHandler,5 builtin_count,ShiftRightSmiHandler,9 builtin_count,ShiftRightLogicalSmiHandler,1 -builtin_count,IncHandler,46 +builtin_count,IncHandler,47 builtin_count,DecHandler,8 builtin_count,NegateHandler,0 builtin_count,BitwiseNotHandler,0 @@ -6280,7 +6296,7 @@ builtin_count,ConstructHandler,7 builtin_count,ConstructWithSpreadHandler,0 builtin_count,ConstructForwardAllArgsHandler,0 -builtin_count,TestEqualHandler,13 +builtin_count,TestEqualHandler,14 builtin_count,TestEqualStrictHandler,12 builtin_count,TestLessThanHandler,40 builtin_count,TestGreaterThanHandler,5 @@ -6290,7 +6306,7 @@ builtin_count,TestInHandler,0 builtin_count,ToNameHandler,0 builtin_count,ToNumberHandler,0 -builtin_count,ToNumericHandler,16 +builtin_count,ToNumericHandler,17 builtin_count,ToObjectHandler,0 builtin_count,ToStringHandler,0 builtin_count,ToBooleanHandler,0 @@ -6303,7 +6319,7 @@ builtin_count,CreateClosureHandler,8 builtin_count,CreateBlockContextHandler,0 builtin_count,CreateCatchContextHandler,0 -builtin_count,CreateFunctionContextHandler,3 +builtin_count,CreateFunctionContextHandler,2 builtin_count,CreateMappedArgumentsHandler,0 builtin_count,CreateUnmappedArgumentsHandler,0 builtin_count,CreateRestParameterHandler,0 @@ -6444,34 +6460,34 @@ builtin_count,CallUndefinedReceiverExtraWideHandler,0 builtin_count,CallUndefinedReceiver1ExtraWideHandler,4 builtin_count,CallUndefinedReceiver2ExtraWideHandler,0 -block_count,RecordWriteSaveFP,0,2045 -block_count,RecordWriteSaveFP,1,1956 +block_count,RecordWriteSaveFP,0,2023 +block_count,RecordWriteSaveFP,1,1960 block_count,RecordWriteSaveFP,2,0 -block_count,RecordWriteSaveFP,3,1956 -block_count,RecordWriteSaveFP,4,1955 +block_count,RecordWriteSaveFP,3,1960 +block_count,RecordWriteSaveFP,4,1959 block_count,RecordWriteSaveFP,5,0 -block_count,RecordWriteSaveFP,6,1955 -block_count,RecordWriteSaveFP,7,1954 +block_count,RecordWriteSaveFP,6,1959 +block_count,RecordWriteSaveFP,7,1958 block_count,RecordWriteSaveFP,8,1 block_count,RecordWriteSaveFP,9,0 block_count,RecordWriteSaveFP,10,1 -block_count,RecordWriteSaveFP,11,1956 -block_count,RecordWriteSaveFP,12,89 -block_count,RecordWriteSaveFP,13,14 -block_count,RecordWriteSaveFP,14,3 -block_count,RecordWriteSaveFP,15,3 +block_count,RecordWriteSaveFP,11,1960 +block_count,RecordWriteSaveFP,12,63 +block_count,RecordWriteSaveFP,13,8 +block_count,RecordWriteSaveFP,14,2 +block_count,RecordWriteSaveFP,15,2 block_count,RecordWriteSaveFP,16,0 -block_count,RecordWriteSaveFP,17,10 -block_count,RecordWriteSaveFP,18,10 +block_count,RecordWriteSaveFP,17,6 +block_count,RecordWriteSaveFP,18,6 block_count,RecordWriteSaveFP,19,0 -block_count,RecordWriteSaveFP,20,10 -block_count,RecordWriteSaveFP,21,10 +block_count,RecordWriteSaveFP,20,6 +block_count,RecordWriteSaveFP,21,6 block_count,RecordWriteSaveFP,22,0 block_count,RecordWriteSaveFP,23,0 block_count,RecordWriteSaveFP,24,0 -block_count,RecordWriteSaveFP,25,75 -block_count,RecordWriteSaveFP,26,89 -block_count,RecordWriteSaveFP,27,89 +block_count,RecordWriteSaveFP,25,54 +block_count,RecordWriteSaveFP,26,63 +block_count,RecordWriteSaveFP,27,63 block_count,RecordWriteSaveFP,28,0 block_count,RecordWriteSaveFP,29,0 block_count,RecordWriteSaveFP,30,0 @@ -6488,22 +6504,22 @@ block_count,RecordWriteSaveFP,41,0 block_count,RecordWriteSaveFP,42,0 block_count,RecordWriteSaveFP,43,0 -block_count,RecordWriteSaveFP,44,89 -block_count,RecordWriteSaveFP,45,89 -block_count,RecordWriteSaveFP,46,49 -block_count,RecordWriteSaveFP,47,49 +block_count,RecordWriteSaveFP,44,63 +block_count,RecordWriteSaveFP,45,63 +block_count,RecordWriteSaveFP,46,38 +block_count,RecordWriteSaveFP,47,38 block_count,RecordWriteSaveFP,48,0 block_count,RecordWriteSaveFP,49,0 block_count,RecordWriteSaveFP,50,0 -block_count,RecordWriteSaveFP,51,40 -block_count,RecordWriteSaveFP,52,40 +block_count,RecordWriteSaveFP,51,24 +block_count,RecordWriteSaveFP,52,24 block_count,RecordWriteSaveFP,53,0 block_count,RecordWriteSaveFP,54,0 block_count,RecordWriteSaveFP,55,0 block_count,RecordWriteSaveFP,56,0 block_count,RecordWriteSaveFP,57,0 -block_count,RecordWriteSaveFP,58,89 -block_count,RecordWriteIgnoreFP,0,0 +block_count,RecordWriteSaveFP,58,63 +block_count,RecordWriteIgnoreFP,0,1 block_count,RecordWriteIgnoreFP,1,0 block_count,RecordWriteIgnoreFP,2,0 block_count,RecordWriteIgnoreFP,3,0 @@ -6576,10 +6592,10 @@ block_count,AdaptorWithBuiltinExitFrame3,1,6 block_count,AdaptorWithBuiltinExitFrame3,2,1 block_count,AdaptorWithBuiltinExitFrame3,3,8 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,385 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,385 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,0,387 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,1,387 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,2,89 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,77 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,3,78 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,4,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,5,77 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,6,0 @@ -6642,18 +6658,18 @@ block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,64,0 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,65,11 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,295 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,66,297 block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,385 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,1432 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,1432 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,84 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,3,32 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,4,31 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,5,31 +block_count,Call_ReceiverIsNullOrUndefined_Baseline_Compact,68,387 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,0,1436 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,1,1436 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,2,85 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,3,33 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,4,32 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,5,32 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,6,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,7,31 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,8,31 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,7,32 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,8,32 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,9,25 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,10,6 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,11,0 @@ -6711,9 +6727,9 @@ block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,63,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,64,0 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,65,52 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,1347 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,66,1351 block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,67,0 -block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,1432 +block_count,Call_ReceiverIsNotNullOrUndefined_Baseline_Compact,68,1436 block_count,Call_ReceiverIsAny_Baseline_Compact,0,5 block_count,Call_ReceiverIsAny_Baseline_Compact,1,5 block_count,Call_ReceiverIsAny_Baseline_Compact,2,0 @@ -6970,7 +6986,7 @@ block_count,CallWithSpread_Baseline,80,0 block_count,CallWithSpread_Baseline,81,0 block_count,CallWithSpread_Baseline,82,0 -block_count,CallWithSpread_Baseline,83,2 +block_count,CallWithSpread_Baseline,83,1 block_count,CallWithSpread_Baseline,84,0 block_count,CallWithSpread_Baseline,85,0 block_count,CallWithSpread_Baseline,86,0 @@ -7030,10 +7046,10 @@ block_count,CallWithArrayLike,7,31 block_count,CallWithArrayLike,8,0 block_count,CallWithArrayLike,9,31 -block_count,CallWithArrayLike,10,30 +block_count,CallWithArrayLike,10,31 block_count,CallWithArrayLike,11,0 -block_count,CallWithArrayLike,12,30 -block_count,CallWithArrayLike,13,30 +block_count,CallWithArrayLike,12,31 +block_count,CallWithArrayLike,13,31 block_count,CallWithArrayLike,14,10 block_count,CallWithArrayLike,15,10 block_count,CallWithArrayLike,16,0 @@ -7387,13 +7403,13 @@ block_count,Construct_Baseline,42,3 block_count,Construct_Baseline,43,115 block_count,Construct_Baseline,44,119 -block_count,FastNewObject,0,369 +block_count,FastNewObject,0,389 block_count,FastNewObject,1,0 -block_count,FastNewObject,2,369 -block_count,FastNewObject,3,369 -block_count,FastNewObject,4,366 -block_count,FastNewObject,5,366 -block_count,FastNewObject,6,366 +block_count,FastNewObject,2,389 +block_count,FastNewObject,3,389 +block_count,FastNewObject,4,386 +block_count,FastNewObject,5,386 +block_count,FastNewObject,6,386 block_count,FastNewObject,7,0 block_count,FastNewObject,8,0 block_count,FastNewObject,9,0 @@ -7419,25 +7435,25 @@ block_count,FastNewObject,29,0 block_count,FastNewObject,30,0 block_count,FastNewObject,31,0 -block_count,FastNewObject,32,366 -block_count,FastNewObject,33,366 +block_count,FastNewObject,32,386 +block_count,FastNewObject,33,386 block_count,FastNewObject,34,0 -block_count,FastNewObject,35,366 +block_count,FastNewObject,35,386 block_count,FastNewObject,36,0 block_count,FastNewObject,37,0 -block_count,FastNewObject,38,366 -block_count,FastNewObject,39,366 +block_count,FastNewObject,38,386 +block_count,FastNewObject,39,385 block_count,FastNewObject,40,1 -block_count,FastNewObject,41,365 +block_count,FastNewObject,41,384 block_count,FastNewObject,42,46 -block_count,FastNewObject,43,318 -block_count,FastNewObject,44,514 -block_count,FastNewObject,45,195 -block_count,FastNewObject,46,318 -block_count,FastNewObject,47,365 -block_count,FastNewObject,48,260 -block_count,FastNewObject,49,104 -block_count,FastNewObject,50,366 +block_count,FastNewObject,43,338 +block_count,FastNewObject,44,548 +block_count,FastNewObject,45,210 +block_count,FastNewObject,46,338 +block_count,FastNewObject,47,384 +block_count,FastNewObject,48,270 +block_count,FastNewObject,49,114 +block_count,FastNewObject,50,385 block_count,FastNewObject,51,0 block_count,FastNewObject,52,0 block_count,FastNewObject,53,0 @@ -7497,7 +7513,7 @@ block_count,StringEqual,0,780 block_count,StringEqual,1,794 block_count,StringEqual,2,307 -block_count,StringEqual,3,18 +block_count,StringEqual,3,17 block_count,StringEqual,4,13 block_count,StringEqual,5,8 block_count,StringEqual,6,2 @@ -7512,7 +7528,7 @@ block_count,StringEqual,15,2 block_count,StringEqual,16,0 block_count,StringEqual,17,4 -block_count,StringEqual,18,4 +block_count,StringEqual,18,3 block_count,StringEqual,19,10 block_count,StringEqual,20,10 block_count,StringEqual,21,3 @@ -7521,7 +7537,7 @@ block_count,StringEqual,24,6 block_count,StringEqual,25,0 block_count,StringEqual,26,4 -block_count,StringEqual,27,15 +block_count,StringEqual,27,14 block_count,StringEqual,28,13 block_count,StringEqual,29,1 block_count,StringEqual,30,289 @@ -7529,16 +7545,16 @@ block_count,StringEqual,32,12 block_count,StringEqual,33,12 block_count,StringEqual,34,0 -block_count,StringEqual,35,277 -block_count,StringEqual,36,277 +block_count,StringEqual,35,276 +block_count,StringEqual,36,276 block_count,StringEqual,37,0 -block_count,StringEqual,38,277 -block_count,StringEqual,39,277 +block_count,StringEqual,38,276 +block_count,StringEqual,39,276 block_count,StringEqual,40,0 -block_count,StringEqual,41,277 -block_count,StringEqual,42,277 +block_count,StringEqual,41,276 +block_count,StringEqual,42,276 block_count,StringEqual,43,0 -block_count,StringEqual,44,277 +block_count,StringEqual,44,276 block_count,StringEqual,45,79 block_count,StringEqual,46,197 block_count,StringEqual,47,220 @@ -7771,7 +7787,7 @@ block_count,StringLessThan,42,459 block_count,StringLessThan,43,479 block_count,StringLessThan,44,901 -block_count,StringLessThan,45,901 +block_count,StringLessThan,45,900 block_count,StringLessThan,46,421 block_count,StringLessThan,47,479 block_count,StringLessThan,48,229 @@ -7899,14 +7915,14 @@ block_count,StringCompare,56,0 block_count,StringSubstring,0,576 block_count,StringSubstring,1,564 -block_count,StringSubstring,2,564 +block_count,StringSubstring,2,563 block_count,StringSubstring,3,456 block_count,StringSubstring,4,197 -block_count,StringSubstring,5,395 +block_count,StringSubstring,5,394 block_count,StringSubstring,6,10 block_count,StringSubstring,7,10 block_count,StringSubstring,8,0 -block_count,StringSubstring,9,180 +block_count,StringSubstring,9,179 block_count,StringSubstring,10,6 block_count,StringSubstring,11,197 block_count,StringSubstring,12,0 @@ -7914,7 +7930,7 @@ block_count,StringSubstring,14,0 block_count,StringSubstring,15,258 block_count,StringSubstring,16,456 -block_count,StringSubstring,17,201 +block_count,StringSubstring,17,200 block_count,StringSubstring,18,5 block_count,StringSubstring,19,0 block_count,StringSubstring,20,5 @@ -7926,7 +7942,7 @@ block_count,StringSubstring,26,255 block_count,StringSubstring,27,255 block_count,StringSubstring,28,38 -block_count,StringSubstring,29,37 +block_count,StringSubstring,29,36 block_count,StringSubstring,30,1 block_count,StringSubstring,31,1 block_count,StringSubstring,32,1 @@ -7940,25 +7956,25 @@ block_count,StringSubstring,40,37 block_count,StringSubstring,41,0 block_count,StringSubstring,42,38 -block_count,StringSubstring,43,6 -block_count,StringSubstring,44,6 -block_count,StringSubstring,45,6 +block_count,StringSubstring,43,5 +block_count,StringSubstring,44,5 +block_count,StringSubstring,45,5 block_count,StringSubstring,46,0 -block_count,StringSubstring,47,6 +block_count,StringSubstring,47,5 block_count,StringSubstring,48,0 block_count,StringSubstring,49,0 -block_count,StringSubstring,50,6 +block_count,StringSubstring,50,5 block_count,StringSubstring,51,0 -block_count,StringSubstring,52,6 +block_count,StringSubstring,52,5 block_count,StringSubstring,53,0 -block_count,StringSubstring,54,6 +block_count,StringSubstring,54,5 block_count,StringSubstring,55,15 block_count,StringSubstring,56,9 -block_count,StringSubstring,57,6 -block_count,StringSubstring,58,6 +block_count,StringSubstring,57,5 +block_count,StringSubstring,58,5 block_count,StringSubstring,59,3 block_count,StringSubstring,60,2 -block_count,StringSubstring,61,6 +block_count,StringSubstring,61,5 block_count,StringSubstring,62,0 block_count,StringSubstring,63,32 block_count,StringSubstring,64,32 @@ -8086,13 +8102,13 @@ block_count,StringSubstring,186,0 block_count,StringSubstring,187,0 block_count,StringSubstring,188,0 -block_count,StringSubstring,189,108 +block_count,StringSubstring,189,107 block_count,StringSubstring,190,6 block_count,StringSubstring,191,13 block_count,StringSubstring,192,4 block_count,StringSubstring,193,4 block_count,StringSubstring,194,0 -block_count,StringSubstring,195,2 +block_count,StringSubstring,195,1 block_count,StringSubstring,196,0 block_count,StringSubstring,197,6 block_count,StringSubstring,198,0 @@ -8108,17 +8124,17 @@ block_count,StringSubstring,208,0 block_count,StringSubstring,209,0 block_count,StringSubstring,210,101 -block_count,StringSubstring,211,108 -block_count,StringSubstring,212,108 +block_count,StringSubstring,211,107 +block_count,StringSubstring,212,107 block_count,StringSubstring,213,4 block_count,StringSubstring,214,103 -block_count,StringSubstring,215,108 +block_count,StringSubstring,215,107 block_count,StringSubstring,216,0 block_count,StringSubstring,217,0 block_count,StringSubstring,218,0 block_count,StringSubstring,219,0 -block_count,StringSubstring,220,108 -block_count,StringSubstring,221,108 +block_count,StringSubstring,220,107 +block_count,StringSubstring,221,107 block_count,StringSubstring,222,0 block_count,StringSubstring,223,12 block_count,StringSubstring,224,12 @@ -8246,19 +8262,19 @@ block_count,GrowFastDoubleElements,18,383 block_count,GrowFastDoubleElements,19,0 block_count,GrowFastDoubleElements,20,383 -block_count,GrowFastDoubleElements,21,4376 -block_count,GrowFastDoubleElements,22,3992 +block_count,GrowFastDoubleElements,21,4375 +block_count,GrowFastDoubleElements,22,3991 block_count,GrowFastDoubleElements,23,383 block_count,GrowFastDoubleElements,24,383 block_count,GrowFastDoubleElements,25,102 block_count,GrowFastDoubleElements,26,281 block_count,GrowFastDoubleElements,27,383 block_count,GrowFastDoubleElements,28,164 -block_count,GrowFastDoubleElements,29,4893 -block_count,GrowFastDoubleElements,30,4892 +block_count,GrowFastDoubleElements,29,4892 +block_count,GrowFastDoubleElements,30,4891 block_count,GrowFastDoubleElements,31,0 -block_count,GrowFastDoubleElements,32,4893 -block_count,GrowFastDoubleElements,33,4728 +block_count,GrowFastDoubleElements,32,4892 +block_count,GrowFastDoubleElements,33,4727 block_count,GrowFastDoubleElements,34,164 block_count,GrowFastDoubleElements,35,219 block_count,GrowFastDoubleElements,36,0 @@ -8267,28 +8283,28 @@ block_count,GrowFastDoubleElements,39,0 block_count,GrowFastSmiOrObjectElements,0,351 block_count,GrowFastSmiOrObjectElements,1,351 -block_count,GrowFastSmiOrObjectElements,2,351 -block_count,GrowFastSmiOrObjectElements,3,351 +block_count,GrowFastSmiOrObjectElements,2,350 +block_count,GrowFastSmiOrObjectElements,3,350 block_count,GrowFastSmiOrObjectElements,4,350 block_count,GrowFastSmiOrObjectElements,5,0 block_count,GrowFastSmiOrObjectElements,6,350 block_count,GrowFastSmiOrObjectElements,7,0 block_count,GrowFastSmiOrObjectElements,8,0 -block_count,GrowFastSmiOrObjectElements,9,351 +block_count,GrowFastSmiOrObjectElements,9,350 block_count,GrowFastSmiOrObjectElements,10,0 -block_count,GrowFastSmiOrObjectElements,11,351 +block_count,GrowFastSmiOrObjectElements,11,350 block_count,GrowFastSmiOrObjectElements,12,0 -block_count,GrowFastSmiOrObjectElements,13,351 +block_count,GrowFastSmiOrObjectElements,13,350 block_count,GrowFastSmiOrObjectElements,14,4632 block_count,GrowFastSmiOrObjectElements,15,4281 -block_count,GrowFastSmiOrObjectElements,16,351 -block_count,GrowFastSmiOrObjectElements,17,351 +block_count,GrowFastSmiOrObjectElements,16,350 +block_count,GrowFastSmiOrObjectElements,17,350 block_count,GrowFastSmiOrObjectElements,18,17 block_count,GrowFastSmiOrObjectElements,19,333 -block_count,GrowFastSmiOrObjectElements,20,351 +block_count,GrowFastSmiOrObjectElements,20,350 block_count,GrowFastSmiOrObjectElements,21,46 -block_count,GrowFastSmiOrObjectElements,22,7140 -block_count,GrowFastSmiOrObjectElements,23,7094 +block_count,GrowFastSmiOrObjectElements,22,7144 +block_count,GrowFastSmiOrObjectElements,23,7098 block_count,GrowFastSmiOrObjectElements,24,46 block_count,GrowFastSmiOrObjectElements,25,304 block_count,GrowFastSmiOrObjectElements,26,0 @@ -8341,7 +8357,7 @@ block_count,ToNumber_Baseline,22,0 block_count,ToNumber_Baseline,23,0 block_count,ToNumber_Baseline,24,0 -block_count,ToNumeric_Baseline,0,86 +block_count,ToNumeric_Baseline,0,87 block_count,ToNumeric_Baseline,1,0 block_count,ToNumeric_Baseline,2,0 block_count,ToNumeric_Baseline,3,0 @@ -8369,10 +8385,10 @@ block_count,ToNumeric_Baseline,25,0 block_count,ToNumeric_Baseline,26,0 block_count,ToNumeric_Baseline,27,0 -block_count,ToNumeric_Baseline,28,85 -block_count,ToNumeric_Baseline,29,86 +block_count,ToNumeric_Baseline,28,87 +block_count,ToNumeric_Baseline,29,87 block_count,ToNumeric_Baseline,30,0 -block_count,ToNumeric_Baseline,31,86 +block_count,ToNumeric_Baseline,31,87 block_count,ToNumberConvertBigInt,0,3 block_count,ToNumberConvertBigInt,1,3 block_count,ToNumberConvertBigInt,2,0 @@ -8795,11 +8811,11 @@ block_count,KeyedStoreIC_Megamorphic,14,304 block_count,KeyedStoreIC_Megamorphic,15,256 block_count,KeyedStoreIC_Megamorphic,16,256 -block_count,KeyedStoreIC_Megamorphic,17,241 +block_count,KeyedStoreIC_Megamorphic,17,240 block_count,KeyedStoreIC_Megamorphic,18,0 block_count,KeyedStoreIC_Megamorphic,19,0 block_count,KeyedStoreIC_Megamorphic,20,0 -block_count,KeyedStoreIC_Megamorphic,21,241 +block_count,KeyedStoreIC_Megamorphic,21,240 block_count,KeyedStoreIC_Megamorphic,22,189 block_count,KeyedStoreIC_Megamorphic,23,51 block_count,KeyedStoreIC_Megamorphic,24,3 @@ -8840,9 +8856,9 @@ block_count,KeyedStoreIC_Megamorphic,59,1 block_count,KeyedStoreIC_Megamorphic,60,0 block_count,KeyedStoreIC_Megamorphic,61,0 -block_count,KeyedStoreIC_Megamorphic,62,163 +block_count,KeyedStoreIC_Megamorphic,62,162 block_count,KeyedStoreIC_Megamorphic,63,0 -block_count,KeyedStoreIC_Megamorphic,64,163 +block_count,KeyedStoreIC_Megamorphic,64,162 block_count,KeyedStoreIC_Megamorphic,65,8 block_count,KeyedStoreIC_Megamorphic,66,154 block_count,KeyedStoreIC_Megamorphic,67,344 @@ -8957,13 +8973,13 @@ block_count,KeyedStoreIC_Megamorphic,176,11 block_count,KeyedStoreIC_Megamorphic,177,0 block_count,KeyedStoreIC_Megamorphic,178,11 -block_count,KeyedStoreIC_Megamorphic,179,99 -block_count,KeyedStoreIC_Megamorphic,180,99 +block_count,KeyedStoreIC_Megamorphic,179,98 +block_count,KeyedStoreIC_Megamorphic,180,98 block_count,KeyedStoreIC_Megamorphic,181,0 -block_count,KeyedStoreIC_Megamorphic,182,99 +block_count,KeyedStoreIC_Megamorphic,182,98 block_count,KeyedStoreIC_Megamorphic,183,50 -block_count,KeyedStoreIC_Megamorphic,184,48 -block_count,KeyedStoreIC_Megamorphic,185,99 +block_count,KeyedStoreIC_Megamorphic,184,47 +block_count,KeyedStoreIC_Megamorphic,185,98 block_count,KeyedStoreIC_Megamorphic,186,87 block_count,KeyedStoreIC_Megamorphic,187,11 block_count,KeyedStoreIC_Megamorphic,188,11 @@ -9097,8 +9113,8 @@ block_count,KeyedStoreIC_Megamorphic,316,0 block_count,KeyedStoreIC_Megamorphic,317,0 block_count,KeyedStoreIC_Megamorphic,318,2 -block_count,KeyedStoreIC_Megamorphic,319,3 -block_count,KeyedStoreIC_Megamorphic,320,3 +block_count,KeyedStoreIC_Megamorphic,319,2 +block_count,KeyedStoreIC_Megamorphic,320,2 block_count,KeyedStoreIC_Megamorphic,321,0 block_count,KeyedStoreIC_Megamorphic,322,0 block_count,KeyedStoreIC_Megamorphic,323,0 @@ -10183,7 +10199,7 @@ block_count,KeyedStoreIC_Megamorphic,1402,7 block_count,KeyedStoreIC_Megamorphic,1403,48 block_count,KeyedStoreIC_Megamorphic,1404,55 -block_count,KeyedStoreIC_Megamorphic,1405,55 +block_count,KeyedStoreIC_Megamorphic,1405,54 block_count,KeyedStoreIC_Megamorphic,1406,54 block_count,KeyedStoreIC_Megamorphic,1407,0 block_count,KeyedStoreIC_Megamorphic,1408,0 @@ -11340,7 +11356,7 @@ block_count,LoadGlobalIC_NoFeedback,27,0 block_count,LoadGlobalIC_NoFeedback,28,0 block_count,LoadGlobalIC_NoFeedback,29,358 -block_count,LoadGlobalIC_NoFeedback,30,867 +block_count,LoadGlobalIC_NoFeedback,30,866 block_count,LoadGlobalIC_NoFeedback,31,514 block_count,LoadGlobalIC_NoFeedback,32,514 block_count,LoadGlobalIC_NoFeedback,33,0 @@ -11404,7 +11420,7 @@ block_count,LoadIC_FunctionPrototype,0,213 block_count,LoadIC_FunctionPrototype,1,213 block_count,LoadIC_FunctionPrototype,2,1 -block_count,LoadIC_FunctionPrototype,3,212 +block_count,LoadIC_FunctionPrototype,3,211 block_count,LoadIC_FunctionPrototype,4,0 block_count,LoadIC_StringLength,0,194 block_count,LoadIC_StringWrapperLength,0,0 @@ -12531,26 +12547,26 @@ block_count,KeyedLoadIC_SloppyArguments,20,0 block_count,KeyedLoadIC_SloppyArguments,21,0 block_count,KeyedLoadIC_SloppyArguments,22,0 -block_count,StoreFastElementIC_InBounds,0,460 +block_count,StoreFastElementIC_InBounds,0,463 block_count,StoreFastElementIC_InBounds,1,0 -block_count,StoreFastElementIC_InBounds,2,11 -block_count,StoreFastElementIC_InBounds,3,11 +block_count,StoreFastElementIC_InBounds,2,12 +block_count,StoreFastElementIC_InBounds,3,12 block_count,StoreFastElementIC_InBounds,4,0 block_count,StoreFastElementIC_InBounds,5,0 block_count,StoreFastElementIC_InBounds,6,0 block_count,StoreFastElementIC_InBounds,7,0 block_count,StoreFastElementIC_InBounds,8,0 -block_count,StoreFastElementIC_InBounds,9,11 -block_count,StoreFastElementIC_InBounds,10,11 +block_count,StoreFastElementIC_InBounds,9,12 +block_count,StoreFastElementIC_InBounds,10,12 block_count,StoreFastElementIC_InBounds,11,0 -block_count,StoreFastElementIC_InBounds,12,11 +block_count,StoreFastElementIC_InBounds,12,12 block_count,StoreFastElementIC_InBounds,13,0 -block_count,StoreFastElementIC_InBounds,14,11 -block_count,StoreFastElementIC_InBounds,15,11 +block_count,StoreFastElementIC_InBounds,14,12 +block_count,StoreFastElementIC_InBounds,15,12 block_count,StoreFastElementIC_InBounds,16,0 -block_count,StoreFastElementIC_InBounds,17,11 +block_count,StoreFastElementIC_InBounds,17,12 block_count,StoreFastElementIC_InBounds,18,0 -block_count,StoreFastElementIC_InBounds,19,11 +block_count,StoreFastElementIC_InBounds,19,12 block_count,StoreFastElementIC_InBounds,20,0 block_count,StoreFastElementIC_InBounds,21,14 block_count,StoreFastElementIC_InBounds,22,14 @@ -12717,8 +12733,8 @@ block_count,StoreFastElementIC_InBounds,183,0 block_count,StoreFastElementIC_InBounds,184,10 block_count,StoreFastElementIC_InBounds,185,10 -block_count,StoreFastElementIC_InBounds,186,8 -block_count,StoreFastElementIC_InBounds,187,8 +block_count,StoreFastElementIC_InBounds,186,9 +block_count,StoreFastElementIC_InBounds,187,9 block_count,StoreFastElementIC_InBounds,188,0 block_count,StoreFastElementIC_InBounds,189,1 block_count,StoreFastElementIC_InBounds,190,10 @@ -12837,26 +12853,26 @@ block_count,StoreFastElementIC_InBounds,303,22 block_count,StoreFastElementIC_InBounds,304,0 block_count,StoreFastElementIC_InBounds,305,0 -block_count,StoreFastElementIC_InBounds,306,3 +block_count,StoreFastElementIC_InBounds,306,4 block_count,StoreFastElementIC_InBounds,307,0 block_count,StoreFastElementIC_InBounds,308,0 block_count,StoreFastElementIC_InBounds,309,0 block_count,StoreFastElementIC_InBounds,310,0 block_count,StoreFastElementIC_InBounds,311,0 -block_count,StoreFastElementIC_InBounds,312,3 -block_count,StoreFastElementIC_InBounds,313,3 -block_count,StoreFastElementIC_InBounds,314,3 +block_count,StoreFastElementIC_InBounds,312,4 +block_count,StoreFastElementIC_InBounds,313,4 +block_count,StoreFastElementIC_InBounds,314,4 block_count,StoreFastElementIC_InBounds,315,1 block_count,StoreFastElementIC_InBounds,316,1 block_count,StoreFastElementIC_InBounds,317,0 block_count,StoreFastElementIC_InBounds,318,0 block_count,StoreFastElementIC_InBounds,319,0 block_count,StoreFastElementIC_InBounds,320,1 -block_count,StoreFastElementIC_InBounds,321,2 -block_count,StoreFastElementIC_InBounds,322,3 -block_count,StoreFastElementIC_InBounds,323,3 +block_count,StoreFastElementIC_InBounds,321,3 +block_count,StoreFastElementIC_InBounds,322,4 +block_count,StoreFastElementIC_InBounds,323,4 block_count,StoreFastElementIC_InBounds,324,0 -block_count,StoreFastElementIC_InBounds,325,3 +block_count,StoreFastElementIC_InBounds,325,4 block_count,StoreFastElementIC_InBounds,326,0 block_count,StoreFastElementIC_InBounds,327,0 block_count,StoreFastElementIC_InBounds,328,0 @@ -13832,7 +13848,7 @@ block_count,StoreFastElementIC_InBounds,1298,0 block_count,StoreFastElementIC_InBounds,1299,0 block_count,StoreFastElementIC_InBounds,1300,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,49 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,0,47 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,1,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,2,3 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,3,0 @@ -14024,21 +14040,21 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,189,4 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,190,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,191,4 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,192,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,192,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,193,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,194,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,195,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,196,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,197,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,198,34 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,199,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,198,32 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,199,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,200,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,201,34 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,202,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,201,32 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,202,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,203,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,204,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,205,2 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,206,31 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,206,30 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,207,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,208,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,209,2 @@ -14053,7 +14069,7 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,218,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,219,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,220,2 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,221,29 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,221,28 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,222,26 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,223,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,224,2 @@ -14061,8 +14077,8 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,226,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,227,2 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,228,1 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,229,28 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,230,26 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,229,26 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,230,24 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,231,1 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,232,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,233,2 @@ -14080,12 +14096,12 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,245,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,246,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,247,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,248,29 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,249,31 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,248,27 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,249,30 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,250,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,251,31 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,252,34 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,253,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,251,30 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,252,32 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,253,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,254,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,255,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,256,0 @@ -14114,9 +14130,9 @@ block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,279,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,280,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,281,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,282,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,282,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,283,0 -block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,284,34 +block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,284,32 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,285,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,286,0 block_count,StoreFastElementIC_NoTransitionGrowAndHandleCOW,287,0 @@ -19363,7 +19379,7 @@ block_count,ArrayConstructorImpl,21,0 block_count,ArrayConstructorImpl,22,0 block_count,ArrayConstructorImpl,23,0 -block_count,ArrayConstructorImpl,24,1 +block_count,ArrayConstructorImpl,24,2 block_count,ArrayConstructorImpl,25,1 block_count,ArrayConstructorImpl,26,1 block_count,ArrayConstructorImpl,27,1 @@ -20145,8 +20161,8 @@ block_count,ArrayIndexOfSmiOrObject,24,0 block_count,ArrayIndexOfSmiOrObject,25,116 block_count,ArrayIndexOfSmiOrObject,26,1764 -block_count,ArrayIndexOfSmiOrObject,27,1677 -block_count,ArrayIndexOfSmiOrObject,28,1677 +block_count,ArrayIndexOfSmiOrObject,27,1676 +block_count,ArrayIndexOfSmiOrObject,28,1676 block_count,ArrayIndexOfSmiOrObject,29,1663 block_count,ArrayIndexOfSmiOrObject,30,0 block_count,ArrayIndexOfSmiOrObject,31,1663 @@ -20390,16 +20406,16 @@ block_count,ArrayPrototypePush,30,0 block_count,ArrayPrototypePush,31,0 block_count,ArrayPrototypePush,32,0 -block_count,ArrayPrototypePush,33,27 -block_count,ArrayPrototypePush,34,26 +block_count,ArrayPrototypePush,33,26 +block_count,ArrayPrototypePush,34,25 block_count,ArrayPrototypePush,35,0 block_count,ArrayPrototypePush,36,0 block_count,ArrayPrototypePush,37,0 block_count,ArrayPrototypePush,38,0 block_count,ArrayPrototypePush,39,0 block_count,ArrayPrototypePush,40,0 -block_count,ArrayPrototypePush,41,77 -block_count,ArrayPrototypePush,42,77 +block_count,ArrayPrototypePush,41,75 +block_count,ArrayPrototypePush,42,74 block_count,ArrayPrototypePush,43,0 block_count,ArrayPrototypePush,44,0 block_count,ArrayPrototypePush,45,0 @@ -20411,11 +20427,11 @@ block_count,ArrayPrototypePush,51,32 block_count,ArrayPrototypePush,52,32 block_count,ArrayPrototypePush,53,0 -block_count,ArrayPrototypePush,54,32 +block_count,ArrayPrototypePush,54,31 block_count,ArrayPrototypePush,55,0 block_count,ArrayPrototypePush,56,0 block_count,ArrayPrototypePush,57,0 -block_count,ArrayPrototypePush,58,32 +block_count,ArrayPrototypePush,58,31 block_count,ArrayPrototypePush,59,0 block_count,ArrayPrototypePush,60,0 block_count,ArrayPrototypePush,61,0 @@ -20424,7 +20440,7 @@ block_count,ArrayPrototypePush,64,0 block_count,ArrayPrototypePush,65,0 block_count,ArrayPrototypePush,66,0 -block_count,ArrayPrototypePush,67,315 +block_count,ArrayPrototypePush,67,316 block_count,ArrayPrototypePush,68,313 block_count,ArrayPrototypePush,69,2 block_count,ArrayPrototypePush,70,2 @@ -20490,7 +20506,7 @@ block_count,ArrayPrototypePush,130,0 block_count,ArrayPrototypePush,131,0 block_count,ArrayPrototypePush,132,0 -block_count,ArrayPrototypePush,133,313 +block_count,ArrayPrototypePush,133,314 block_count,ArrayPrototypePush,134,313 block_count,ArrayPrototypePush,135,288 block_count,ArrayPrototypePush,136,24 @@ -20515,18 +20531,18 @@ block_count,ArrayPrototypePush,155,24 block_count,ArrayPrototypePush,156,2 block_count,ArrayPrototypePush,157,181 -block_count,ArrayPrototypePush,158,179 +block_count,ArrayPrototypePush,158,178 block_count,ArrayPrototypePush,159,2 block_count,ArrayPrototypePush,160,22 block_count,ArrayPrototypePush,161,24 block_count,ArrayPrototypePush,162,0 block_count,ArrayPrototypePush,163,0 block_count,ArrayPrototypePush,164,313 -block_count,ArrayPrototypePush,165,312 -block_count,ArrayPrototypePush,166,322 -block_count,ArrayPrototypePush,167,322 +block_count,ArrayPrototypePush,165,313 +block_count,ArrayPrototypePush,166,323 +block_count,ArrayPrototypePush,167,323 block_count,ArrayPrototypePush,168,9 -block_count,ArrayPrototypePush,169,312 +block_count,ArrayPrototypePush,169,313 block_count,ArrayPrototypePush,170,0 block_count,ArrayPrototypePush,171,0 block_count,ArrayPrototypePush,172,313 @@ -20855,8 +20871,8 @@ block_count,ExtractFastJSArray,29,0 block_count,ExtractFastJSArray,30,0 block_count,ExtractFastJSArray,31,0 -block_count,ExtractFastJSArray,32,3 -block_count,ExtractFastJSArray,33,3 +block_count,ExtractFastJSArray,32,4 +block_count,ExtractFastJSArray,33,4 block_count,ExtractFastJSArray,34,0 block_count,ExtractFastJSArray,35,0 block_count,ExtractFastJSArray,36,0 @@ -21331,13 +21347,13 @@ block_count,ArrayPrototypeValues,12,0 block_count,ArrayPrototypeValues,13,33 block_count,ArrayPrototypeValues,14,33 -block_count,ArrayIteratorPrototypeNext,0,77 +block_count,ArrayIteratorPrototypeNext,0,79 block_count,ArrayIteratorPrototypeNext,1,0 -block_count,ArrayIteratorPrototypeNext,2,77 -block_count,ArrayIteratorPrototypeNext,3,77 -block_count,ArrayIteratorPrototypeNext,4,77 +block_count,ArrayIteratorPrototypeNext,2,79 +block_count,ArrayIteratorPrototypeNext,3,79 +block_count,ArrayIteratorPrototypeNext,4,79 block_count,ArrayIteratorPrototypeNext,5,0 -block_count,ArrayIteratorPrototypeNext,6,77 +block_count,ArrayIteratorPrototypeNext,6,79 block_count,ArrayIteratorPrototypeNext,7,2 block_count,ArrayIteratorPrototypeNext,8,2 block_count,ArrayIteratorPrototypeNext,9,0 @@ -21518,22 +21534,22 @@ block_count,ArrayIteratorPrototypeNext,184,0 block_count,ArrayIteratorPrototypeNext,185,0 block_count,ArrayIteratorPrototypeNext,186,0 -block_count,ArrayIteratorPrototypeNext,187,75 +block_count,ArrayIteratorPrototypeNext,187,76 block_count,ArrayIteratorPrototypeNext,188,0 -block_count,ArrayIteratorPrototypeNext,189,75 -block_count,ArrayIteratorPrototypeNext,190,75 +block_count,ArrayIteratorPrototypeNext,189,76 +block_count,ArrayIteratorPrototypeNext,190,76 block_count,ArrayIteratorPrototypeNext,191,0 -block_count,ArrayIteratorPrototypeNext,192,75 -block_count,ArrayIteratorPrototypeNext,193,75 +block_count,ArrayIteratorPrototypeNext,192,76 +block_count,ArrayIteratorPrototypeNext,193,76 block_count,ArrayIteratorPrototypeNext,194,19 -block_count,ArrayIteratorPrototypeNext,195,55 -block_count,ArrayIteratorPrototypeNext,196,55 +block_count,ArrayIteratorPrototypeNext,195,56 +block_count,ArrayIteratorPrototypeNext,196,56 block_count,ArrayIteratorPrototypeNext,197,0 block_count,ArrayIteratorPrototypeNext,198,0 block_count,ArrayIteratorPrototypeNext,199,0 block_count,ArrayIteratorPrototypeNext,200,0 -block_count,ArrayIteratorPrototypeNext,201,55 -block_count,ArrayIteratorPrototypeNext,202,55 +block_count,ArrayIteratorPrototypeNext,201,56 +block_count,ArrayIteratorPrototypeNext,202,56 block_count,ArrayIteratorPrototypeNext,203,0 block_count,ArrayIteratorPrototypeNext,204,0 block_count,ArrayIteratorPrototypeNext,205,0 @@ -21552,14 +21568,14 @@ block_count,ArrayIteratorPrototypeNext,218,0 block_count,ArrayIteratorPrototypeNext,219,0 block_count,ArrayIteratorPrototypeNext,220,0 -block_count,ArrayIteratorPrototypeNext,221,3 +block_count,ArrayIteratorPrototypeNext,221,4 block_count,ArrayIteratorPrototypeNext,222,44 block_count,ArrayIteratorPrototypeNext,223,0 block_count,ArrayIteratorPrototypeNext,224,0 block_count,ArrayIteratorPrototypeNext,225,0 -block_count,ArrayIteratorPrototypeNext,226,47 +block_count,ArrayIteratorPrototypeNext,226,48 block_count,ArrayIteratorPrototypeNext,227,0 -block_count,ArrayIteratorPrototypeNext,228,47 +block_count,ArrayIteratorPrototypeNext,228,48 block_count,ArrayIteratorPrototypeNext,229,0 block_count,ArrayIteratorPrototypeNext,230,7 block_count,ArrayIteratorPrototypeNext,231,0 @@ -21580,7 +21596,7 @@ block_count,ArrayIteratorPrototypeNext,246,0 block_count,ArrayIteratorPrototypeNext,247,0 block_count,ArrayIteratorPrototypeNext,248,0 -block_count,ArrayIteratorPrototypeNext,249,55 +block_count,ArrayIteratorPrototypeNext,249,56 block_count,ArrayIteratorPrototypeNext,250,0 block_count,ArrayIteratorPrototypeNext,251,0 block_count,ArrayIteratorPrototypeNext,252,0 @@ -21594,7 +21610,7 @@ block_count,ArrayIteratorPrototypeNext,260,19 block_count,ArrayIteratorPrototypeNext,261,20 block_count,ArrayIteratorPrototypeNext,262,1 -block_count,ArrayIteratorPrototypeNext,263,57 +block_count,ArrayIteratorPrototypeNext,263,58 block_count,ArrayIteratorPrototypeNext,264,0 block_count,ArrayIteratorPrototypeNext,265,0 block_count,ArrayIteratorPrototypeNext,266,0 @@ -21605,13 +21621,13 @@ block_count,ArrayIteratorPrototypeNext,271,0 block_count,ArrayIteratorPrototypeNext,272,0 block_count,ArrayIteratorPrototypeNext,273,0 -block_count,ArrayIteratorPrototypeNext,274,57 -block_count,ArrayIteratorPrototypeNext,275,77 +block_count,ArrayIteratorPrototypeNext,274,58 +block_count,ArrayIteratorPrototypeNext,275,79 block_count,ArrayIteratorPrototypeNext,276,0 -block_count,ArrayIteratorPrototypeNext,277,77 +block_count,ArrayIteratorPrototypeNext,277,79 block_count,ArrayIteratorPrototypeNext,278,0 -block_count,ArrayIteratorPrototypeNext,279,77 -block_count,ArrayIteratorPrototypeNext,280,77 +block_count,ArrayIteratorPrototypeNext,279,79 +block_count,ArrayIteratorPrototypeNext,280,79 block_count,AsyncFunctionEnter,0,0 block_count,AsyncFunctionEnter,1,0 block_count,AsyncFunctionEnter,2,0 @@ -22010,15 +22026,15 @@ block_count,GlobalIsNaN,8,0 block_count,GlobalIsNaN,9,0 block_count,GlobalIsNaN,10,0 -block_count,LoadIC,0,5696 -block_count,LoadIC,1,5695 +block_count,LoadIC,0,5684 +block_count,LoadIC,1,5683 block_count,LoadIC,2,1 -block_count,LoadIC,3,5696 -block_count,LoadIC,4,5696 -block_count,LoadIC,5,1490 +block_count,LoadIC,3,5684 +block_count,LoadIC,4,5684 +block_count,LoadIC,5,1487 block_count,LoadIC,6,0 -block_count,LoadIC,7,1489 -block_count,LoadIC,8,292 +block_count,LoadIC,7,1486 +block_count,LoadIC,8,301 block_count,LoadIC,9,1 block_count,LoadIC,10,1 block_count,LoadIC,11,0 @@ -22032,36 +22048,36 @@ block_count,LoadIC,19,0 block_count,LoadIC,20,0 block_count,LoadIC,21,0 -block_count,LoadIC,22,291 -block_count,LoadIC,23,291 +block_count,LoadIC,22,300 +block_count,LoadIC,23,300 block_count,LoadIC,24,0 -block_count,LoadIC,25,291 -block_count,LoadIC,26,246 -block_count,LoadIC,27,243 -block_count,LoadIC,28,3 -block_count,LoadIC,29,44 -block_count,LoadIC,30,48 -block_count,LoadIC,31,45 -block_count,LoadIC,32,45 +block_count,LoadIC,25,300 +block_count,LoadIC,26,260 +block_count,LoadIC,27,257 +block_count,LoadIC,28,2 +block_count,LoadIC,29,39 +block_count,LoadIC,30,42 +block_count,LoadIC,31,40 +block_count,LoadIC,32,40 block_count,LoadIC,33,0 block_count,LoadIC,34,2 -block_count,LoadIC,35,1196 -block_count,LoadIC,36,1975 -block_count,LoadIC,37,778 -block_count,LoadIC,38,778 +block_count,LoadIC,35,1184 +block_count,LoadIC,36,1943 +block_count,LoadIC,37,759 +block_count,LoadIC,38,758 block_count,LoadIC,39,0 -block_count,LoadIC,40,1196 -block_count,LoadIC,41,4206 -block_count,LoadIC,42,5691 +block_count,LoadIC,40,1184 +block_count,LoadIC,41,4197 +block_count,LoadIC,42,5679 block_count,LoadIC,43,1921 block_count,LoadIC,44,1912 -block_count,LoadIC,45,1589 -block_count,LoadIC,46,1588 +block_count,LoadIC,45,1590 +block_count,LoadIC,46,1590 block_count,LoadIC,47,0 -block_count,LoadIC,48,1588 +block_count,LoadIC,48,1589 block_count,LoadIC,49,0 -block_count,LoadIC,50,1589 -block_count,LoadIC,51,204 +block_count,LoadIC,50,1590 +block_count,LoadIC,51,206 block_count,LoadIC,52,37 block_count,LoadIC,53,37 block_count,LoadIC,54,0 @@ -22118,8 +22134,8 @@ block_count,LoadIC,105,0 block_count,LoadIC,106,0 block_count,LoadIC,107,1 -block_count,LoadIC,108,166 -block_count,LoadIC,109,166 +block_count,LoadIC,108,168 +block_count,LoadIC,109,168 block_count,LoadIC,110,0 block_count,LoadIC,111,0 block_count,LoadIC,112,0 @@ -22131,27 +22147,27 @@ block_count,LoadIC,118,0 block_count,LoadIC,119,0 block_count,LoadIC,120,0 -block_count,LoadIC,121,166 +block_count,LoadIC,121,168 block_count,LoadIC,122,0 -block_count,LoadIC,123,1384 -block_count,LoadIC,124,1587 -block_count,LoadIC,125,1586 -block_count,LoadIC,126,1501 -block_count,LoadIC,127,1501 +block_count,LoadIC,123,1383 +block_count,LoadIC,124,1588 +block_count,LoadIC,125,1587 +block_count,LoadIC,126,1503 +block_count,LoadIC,127,1503 block_count,LoadIC,128,0 -block_count,LoadIC,129,85 -block_count,LoadIC,130,1586 +block_count,LoadIC,129,84 +block_count,LoadIC,130,1587 block_count,LoadIC,131,0 block_count,LoadIC,132,322 block_count,LoadIC,133,8 block_count,LoadIC,134,8 block_count,LoadIC,135,0 -block_count,LoadIC,136,3770 -block_count,LoadIC,137,5357 +block_count,LoadIC,136,3757 +block_count,LoadIC,137,5345 block_count,LoadIC,138,1841 -block_count,LoadIC,139,581 +block_count,LoadIC,139,580 block_count,LoadIC,140,496 -block_count,LoadIC,141,254 +block_count,LoadIC,141,255 block_count,LoadIC,142,14 block_count,LoadIC,143,2 block_count,LoadIC,144,2 @@ -22221,23 +22237,23 @@ block_count,LoadIC,208,0 block_count,LoadIC,209,0 block_count,LoadIC,210,11 -block_count,LoadIC,211,240 -block_count,LoadIC,212,241 -block_count,LoadIC,213,241 +block_count,LoadIC,211,241 +block_count,LoadIC,212,240 +block_count,LoadIC,213,240 block_count,LoadIC,214,0 -block_count,LoadIC,215,241 -block_count,LoadIC,216,241 -block_count,LoadIC,217,344 -block_count,LoadIC,218,344 -block_count,LoadIC,219,102 -block_count,LoadIC,220,241 +block_count,LoadIC,215,240 +block_count,LoadIC,216,240 +block_count,LoadIC,217,342 +block_count,LoadIC,218,342 +block_count,LoadIC,219,101 +block_count,LoadIC,220,240 block_count,LoadIC,221,0 block_count,LoadIC,222,0 block_count,LoadIC,223,0 block_count,LoadIC,224,0 -block_count,LoadIC,225,241 +block_count,LoadIC,225,240 block_count,LoadIC,226,0 -block_count,LoadIC,227,241 +block_count,LoadIC,227,240 block_count,LoadIC,228,0 block_count,LoadIC,229,0 block_count,LoadIC,230,0 @@ -22277,21 +22293,21 @@ block_count,LoadIC,264,0 block_count,LoadIC,265,0 block_count,LoadIC,266,0 -block_count,LoadIC,267,241 -block_count,LoadIC,268,85 -block_count,LoadIC,269,1259 -block_count,LoadIC,270,3515 -block_count,LoadIC,271,3515 -block_count,LoadIC,272,914 -block_count,LoadIC,273,2601 -block_count,LoadIC,274,3515 -block_count,LoadIC,275,3342 -block_count,LoadIC,276,173 -block_count,LoadIC,277,173 -block_count,LoadIC,278,173 +block_count,LoadIC,267,240 +block_count,LoadIC,268,84 +block_count,LoadIC,269,1260 +block_count,LoadIC,270,3504 +block_count,LoadIC,271,3504 +block_count,LoadIC,272,900 +block_count,LoadIC,273,2603 +block_count,LoadIC,274,3504 +block_count,LoadIC,275,3329 +block_count,LoadIC,276,174 +block_count,LoadIC,277,174 +block_count,LoadIC,278,174 block_count,LoadIC,279,0 -block_count,LoadIC,280,173 -block_count,LoadIC,281,173 +block_count,LoadIC,280,174 +block_count,LoadIC,281,174 block_count,LoadIC,282,0 block_count,LoadIC,283,0 block_count,LoadIC,284,0 @@ -22353,24 +22369,24 @@ block_count,LoadIC_Megamorphic,4,10000 block_count,LoadIC_Megamorphic,5,0 block_count,LoadIC_Megamorphic,6,10000 -block_count,LoadIC_Megamorphic,7,8221 -block_count,LoadIC_Megamorphic,8,8169 -block_count,LoadIC_Megamorphic,9,52 -block_count,LoadIC_Megamorphic,10,1778 -block_count,LoadIC_Megamorphic,11,1830 -block_count,LoadIC_Megamorphic,12,1822 -block_count,LoadIC_Megamorphic,13,1820 +block_count,LoadIC_Megamorphic,7,8380 +block_count,LoadIC_Megamorphic,8,8307 +block_count,LoadIC_Megamorphic,9,73 +block_count,LoadIC_Megamorphic,10,1619 +block_count,LoadIC_Megamorphic,11,1692 +block_count,LoadIC_Megamorphic,12,1685 +block_count,LoadIC_Megamorphic,13,1683 block_count,LoadIC_Megamorphic,14,1 block_count,LoadIC_Megamorphic,15,7 block_count,LoadIC_Megamorphic,16,9990 -block_count,LoadIC_Megamorphic,17,3704 -block_count,LoadIC_Megamorphic,18,3704 -block_count,LoadIC_Megamorphic,19,3623 -block_count,LoadIC_Megamorphic,20,3623 +block_count,LoadIC_Megamorphic,17,3705 +block_count,LoadIC_Megamorphic,18,3705 +block_count,LoadIC_Megamorphic,19,3624 +block_count,LoadIC_Megamorphic,20,3624 block_count,LoadIC_Megamorphic,21,0 -block_count,LoadIC_Megamorphic,22,3623 +block_count,LoadIC_Megamorphic,22,3624 block_count,LoadIC_Megamorphic,23,0 -block_count,LoadIC_Megamorphic,24,3623 +block_count,LoadIC_Megamorphic,24,3624 block_count,LoadIC_Megamorphic,25,7 block_count,LoadIC_Megamorphic,26,4 block_count,LoadIC_Megamorphic,27,4 @@ -22443,23 +22459,23 @@ block_count,LoadIC_Megamorphic,94,0 block_count,LoadIC_Megamorphic,95,3 block_count,LoadIC_Megamorphic,96,0 -block_count,LoadIC_Megamorphic,97,3616 -block_count,LoadIC_Megamorphic,98,3623 -block_count,LoadIC_Megamorphic,99,3621 -block_count,LoadIC_Megamorphic,100,2853 -block_count,LoadIC_Megamorphic,101,2853 +block_count,LoadIC_Megamorphic,97,3617 +block_count,LoadIC_Megamorphic,98,3624 +block_count,LoadIC_Megamorphic,99,3622 +block_count,LoadIC_Megamorphic,100,2852 +block_count,LoadIC_Megamorphic,101,2852 block_count,LoadIC_Megamorphic,102,0 -block_count,LoadIC_Megamorphic,103,768 -block_count,LoadIC_Megamorphic,104,3621 +block_count,LoadIC_Megamorphic,103,769 +block_count,LoadIC_Megamorphic,104,3622 block_count,LoadIC_Megamorphic,105,1 block_count,LoadIC_Megamorphic,106,81 block_count,LoadIC_Megamorphic,107,0 block_count,LoadIC_Megamorphic,108,0 block_count,LoadIC_Megamorphic,109,0 -block_count,LoadIC_Megamorphic,110,6285 +block_count,LoadIC_Megamorphic,110,6284 block_count,LoadIC_Megamorphic,111,9907 block_count,LoadIC_Megamorphic,112,4346 -block_count,LoadIC_Megamorphic,113,2286 +block_count,LoadIC_Megamorphic,113,2287 block_count,LoadIC_Megamorphic,114,1517 block_count,LoadIC_Megamorphic,115,1515 block_count,LoadIC_Megamorphic,116,724 @@ -22588,14 +22604,14 @@ block_count,LoadIC_Megamorphic,239,0 block_count,LoadIC_Megamorphic,240,0 block_count,LoadIC_Megamorphic,241,1 -block_count,LoadIC_Megamorphic,242,768 +block_count,LoadIC_Megamorphic,242,769 block_count,LoadIC_Megamorphic,243,2059 -block_count,LoadIC_Megamorphic,244,5561 -block_count,LoadIC_Megamorphic,245,5561 -block_count,LoadIC_Megamorphic,246,291 -block_count,LoadIC_Megamorphic,247,5270 -block_count,LoadIC_Megamorphic,248,5561 -block_count,LoadIC_Megamorphic,249,5540 +block_count,LoadIC_Megamorphic,244,5560 +block_count,LoadIC_Megamorphic,245,5560 +block_count,LoadIC_Megamorphic,246,290 +block_count,LoadIC_Megamorphic,247,5269 +block_count,LoadIC_Megamorphic,248,5560 +block_count,LoadIC_Megamorphic,249,5539 block_count,LoadIC_Megamorphic,250,21 block_count,LoadIC_Megamorphic,251,21 block_count,LoadIC_Megamorphic,252,21 @@ -22656,10 +22672,10 @@ block_count,LoadIC_Megamorphic,307,0 block_count,LoadIC_Megamorphic,308,0 block_count,LoadIC_Megamorphic,309,9 -block_count,LoadIC_Noninlined,0,5 -block_count,LoadIC_Noninlined,1,5 +block_count,LoadIC_Noninlined,0,6 +block_count,LoadIC_Noninlined,1,6 block_count,LoadIC_Noninlined,2,0 -block_count,LoadIC_Noninlined,3,5 +block_count,LoadIC_Noninlined,3,6 block_count,LoadIC_Noninlined,4,1 block_count,LoadIC_Noninlined,5,1 block_count,LoadIC_Noninlined,6,0 @@ -22980,15 +22996,15 @@ block_count,LoadIC_Noninlined,321,0 block_count,LoadIC_Noninlined,322,0 block_count,LoadIC_Noninlined,323,1 -block_count,LoadICTrampoline,0,340 -block_count,LoadICTrampoline,1,340 +block_count,LoadICTrampoline,0,339 +block_count,LoadICTrampoline,1,339 block_count,LoadICTrampoline,2,0 -block_count,LoadICTrampoline,3,340 -block_count,LoadICBaseline,0,5112 -block_count,LoadICTrampoline_Megamorphic,0,6354 -block_count,LoadICTrampoline_Megamorphic,1,6354 +block_count,LoadICTrampoline,3,339 +block_count,LoadICBaseline,0,5101 +block_count,LoadICTrampoline_Megamorphic,0,6353 +block_count,LoadICTrampoline_Megamorphic,1,6353 block_count,LoadICTrampoline_Megamorphic,2,0 -block_count,LoadICTrampoline_Megamorphic,3,6354 +block_count,LoadICTrampoline_Megamorphic,3,6353 block_count,LoadSuperIC,0,5 block_count,LoadSuperIC,1,5 block_count,LoadSuperIC,2,5 @@ -23597,15 +23613,15 @@ block_count,LoadSuperIC,605,0 block_count,LoadSuperIC,606,0 block_count,LoadSuperICBaseline,0,5 -block_count,KeyedLoadIC,0,954 -block_count,KeyedLoadIC,1,954 +block_count,KeyedLoadIC,0,960 +block_count,KeyedLoadIC,1,960 block_count,KeyedLoadIC,2,0 -block_count,KeyedLoadIC,3,954 -block_count,KeyedLoadIC,4,954 -block_count,KeyedLoadIC,5,951 -block_count,KeyedLoadIC,6,96 +block_count,KeyedLoadIC,3,960 +block_count,KeyedLoadIC,4,960 +block_count,KeyedLoadIC,5,957 +block_count,KeyedLoadIC,6,98 block_count,KeyedLoadIC,7,0 -block_count,KeyedLoadIC,8,96 +block_count,KeyedLoadIC,8,98 block_count,KeyedLoadIC,9,52 block_count,KeyedLoadIC,10,2 block_count,KeyedLoadIC,11,1 @@ -23644,15 +23660,15 @@ block_count,KeyedLoadIC,44,1 block_count,KeyedLoadIC,45,1 block_count,KeyedLoadIC,46,0 -block_count,KeyedLoadIC,47,49 -block_count,KeyedLoadIC,48,44 -block_count,KeyedLoadIC,49,73 -block_count,KeyedLoadIC,50,29 -block_count,KeyedLoadIC,51,29 +block_count,KeyedLoadIC,47,50 +block_count,KeyedLoadIC,48,46 +block_count,KeyedLoadIC,49,76 +block_count,KeyedLoadIC,50,30 +block_count,KeyedLoadIC,51,30 block_count,KeyedLoadIC,52,0 -block_count,KeyedLoadIC,53,44 -block_count,KeyedLoadIC,54,855 -block_count,KeyedLoadIC,55,899 +block_count,KeyedLoadIC,53,46 +block_count,KeyedLoadIC,54,859 +block_count,KeyedLoadIC,55,905 block_count,KeyedLoadIC,56,2 block_count,KeyedLoadIC,57,2 block_count,KeyedLoadIC,58,0 @@ -23746,8 +23762,8 @@ block_count,KeyedLoadIC,146,0 block_count,KeyedLoadIC,147,0 block_count,KeyedLoadIC,148,0 -block_count,KeyedLoadIC,149,897 -block_count,KeyedLoadIC,150,897 +block_count,KeyedLoadIC,149,903 +block_count,KeyedLoadIC,150,903 block_count,KeyedLoadIC,151,8 block_count,KeyedLoadIC,152,0 block_count,KeyedLoadIC,153,0 @@ -23983,7 +23999,7 @@ block_count,KeyedLoadIC,383,0 block_count,KeyedLoadIC,384,8 block_count,KeyedLoadIC,385,8 -block_count,KeyedLoadIC,386,7 +block_count,KeyedLoadIC,386,8 block_count,KeyedLoadIC,387,3 block_count,KeyedLoadIC,388,7 block_count,KeyedLoadIC,389,3 @@ -24005,16 +24021,16 @@ block_count,KeyedLoadIC,405,0 block_count,KeyedLoadIC,406,0 block_count,KeyedLoadIC,407,4 -block_count,KeyedLoadIC,408,7 -block_count,KeyedLoadIC,409,7 +block_count,KeyedLoadIC,408,8 +block_count,KeyedLoadIC,409,8 block_count,KeyedLoadIC,410,0 -block_count,KeyedLoadIC,411,7 -block_count,KeyedLoadIC,412,7 +block_count,KeyedLoadIC,411,8 +block_count,KeyedLoadIC,412,8 block_count,KeyedLoadIC,413,0 block_count,KeyedLoadIC,414,0 block_count,KeyedLoadIC,415,0 block_count,KeyedLoadIC,416,0 -block_count,KeyedLoadIC,417,7 +block_count,KeyedLoadIC,417,8 block_count,KeyedLoadIC,418,0 block_count,KeyedLoadIC,419,0 block_count,KeyedLoadIC,420,0 @@ -24022,7 +24038,7 @@ block_count,KeyedLoadIC,422,0 block_count,KeyedLoadIC,423,0 block_count,KeyedLoadIC,424,0 -block_count,KeyedLoadIC,425,889 +block_count,KeyedLoadIC,425,894 block_count,KeyedLoadIC,426,0 block_count,KeyedLoadIC,427,0 block_count,KeyedLoadIC,428,0 @@ -24033,43 +24049,43 @@ block_count,KeyedLoadIC,433,0 block_count,KeyedLoadIC,434,0 block_count,KeyedLoadIC,435,0 -block_count,KeyedLoadIC,436,888 -block_count,KeyedLoadIC,437,888 -block_count,KeyedLoadIC,438,889 -block_count,KeyedLoadIC,439,546 +block_count,KeyedLoadIC,436,894 +block_count,KeyedLoadIC,437,894 +block_count,KeyedLoadIC,438,894 +block_count,KeyedLoadIC,439,551 block_count,KeyedLoadIC,440,10 -block_count,KeyedLoadIC,441,536 -block_count,KeyedLoadIC,442,546 +block_count,KeyedLoadIC,441,540 +block_count,KeyedLoadIC,442,551 block_count,KeyedLoadIC,443,1 -block_count,KeyedLoadIC,444,545 +block_count,KeyedLoadIC,444,549 block_count,KeyedLoadIC,445,0 block_count,KeyedLoadIC,446,42 -block_count,KeyedLoadIC,447,283 +block_count,KeyedLoadIC,447,287 block_count,KeyedLoadIC,448,0 block_count,KeyedLoadIC,449,0 block_count,KeyedLoadIC,450,0 block_count,KeyedLoadIC,451,0 -block_count,KeyedLoadIC,452,325 -block_count,KeyedLoadIC,453,27 -block_count,KeyedLoadIC,454,88 +block_count,KeyedLoadIC,452,329 +block_count,KeyedLoadIC,453,28 +block_count,KeyedLoadIC,454,87 block_count,KeyedLoadIC,455,0 block_count,KeyedLoadIC,456,0 block_count,KeyedLoadIC,457,0 -block_count,KeyedLoadIC,458,116 +block_count,KeyedLoadIC,458,115 block_count,KeyedLoadIC,459,110 block_count,KeyedLoadIC,460,5 -block_count,KeyedLoadIC,461,40 +block_count,KeyedLoadIC,461,41 block_count,KeyedLoadIC,462,0 -block_count,KeyedLoadIC,463,40 -block_count,KeyedLoadIC,464,40 -block_count,KeyedLoadIC,465,62 -block_count,KeyedLoadIC,466,62 +block_count,KeyedLoadIC,463,41 +block_count,KeyedLoadIC,464,41 +block_count,KeyedLoadIC,465,61 +block_count,KeyedLoadIC,466,61 block_count,KeyedLoadIC,467,0 -block_count,KeyedLoadIC,468,62 -block_count,KeyedLoadIC,469,62 +block_count,KeyedLoadIC,468,61 +block_count,KeyedLoadIC,469,61 block_count,KeyedLoadIC,470,0 -block_count,KeyedLoadIC,471,342 -block_count,KeyedLoadIC,472,342 +block_count,KeyedLoadIC,471,343 +block_count,KeyedLoadIC,472,343 block_count,KeyedLoadIC,473,0 block_count,KeyedLoadIC,474,0 block_count,KeyedLoadIC,475,0 @@ -24092,19 +24108,19 @@ block_count,KeyedLoadIC,492,0 block_count,KeyedLoadIC,493,0 block_count,KeyedLoadIC,494,0 -block_count,KeyedLoadIC,495,342 -block_count,KeyedLoadIC,496,342 +block_count,KeyedLoadIC,495,343 +block_count,KeyedLoadIC,496,343 block_count,KeyedLoadIC,497,0 -block_count,KeyedLoadIC,498,342 +block_count,KeyedLoadIC,498,343 block_count,KeyedLoadIC,499,0 -block_count,KeyedLoadIC,500,50 +block_count,KeyedLoadIC,500,49 block_count,KeyedLoadIC,501,0 block_count,KeyedLoadIC,502,2 block_count,KeyedLoadIC,503,14 block_count,KeyedLoadIC,504,0 block_count,KeyedLoadIC,505,1 -block_count,KeyedLoadIC,506,193 -block_count,KeyedLoadIC,507,79 +block_count,KeyedLoadIC,506,195 +block_count,KeyedLoadIC,507,80 block_count,KeyedLoadIC,508,0 block_count,KeyedLoadIC,509,0 block_count,KeyedLoadIC,510,0 @@ -24163,16 +24179,16 @@ block_count,KeyedLoadIC,563,0 block_count,KeyedLoadIC,564,0 block_count,KeyedLoadIC,565,0 -block_count,KeyedLoadIC,566,193 -block_count,KeyedLoadIC,567,190 +block_count,KeyedLoadIC,566,195 +block_count,KeyedLoadIC,567,191 block_count,KeyedLoadIC,568,3 block_count,KeyedLoadIC,569,0 block_count,KeyedLoadIC,570,3 block_count,KeyedLoadIC,571,3 -block_count,KeyedLoadIC,572,79 +block_count,KeyedLoadIC,572,80 block_count,KeyedLoadIC,573,0 -block_count,KeyedLoadIC,574,79 -block_count,KeyedLoadIC,575,79 +block_count,KeyedLoadIC,574,80 +block_count,KeyedLoadIC,575,80 block_count,KeyedLoadIC,576,0 block_count,KeyedLoadIC,577,0 block_count,KeyedLoadIC,578,0 @@ -24250,7 +24266,7 @@ block_count,KeyedLoadIC,650,0 block_count,KeyedLoadIC,651,0 block_count,KeyedLoadIC,652,2 -block_count,KeyedLoadIC,653,52 +block_count,KeyedLoadIC,653,53 block_count,KeyedLoadIC,654,0 block_count,KeyedLoadIC,655,0 block_count,EnumeratedKeyedLoadIC,0,7 @@ -24282,9 +24298,9 @@ block_count,EnumeratedKeyedLoadIC,26,0 block_count,EnumeratedKeyedLoadIC,27,0 block_count,EnumeratedKeyedLoadIC,28,0 -block_count,EnumeratedKeyedLoadIC,29,2 -block_count,EnumeratedKeyedLoadIC,30,2 -block_count,EnumeratedKeyedLoadIC,31,2 +block_count,EnumeratedKeyedLoadIC,29,3 +block_count,EnumeratedKeyedLoadIC,30,3 +block_count,EnumeratedKeyedLoadIC,31,3 block_count,EnumeratedKeyedLoadIC,32,2 block_count,EnumeratedKeyedLoadIC,33,0 block_count,EnumeratedKeyedLoadIC,34,2 @@ -24932,19 +24948,19 @@ block_count,EnumeratedKeyedLoadIC,676,0 block_count,EnumeratedKeyedLoadIC,677,0 block_count,EnumeratedKeyedLoadIC,678,0 -block_count,EnumeratedKeyedLoadIC,679,2 +block_count,EnumeratedKeyedLoadIC,679,3 block_count,EnumeratedKeyedLoadIC,680,0 block_count,EnumeratedKeyedLoadIC,681,0 block_count,KeyedLoadIC_Megamorphic,0,2428 block_count,KeyedLoadIC_Megamorphic,1,2428 block_count,KeyedLoadIC_Megamorphic,2,2428 -block_count,KeyedLoadIC_Megamorphic,3,2104 -block_count,KeyedLoadIC_Megamorphic,4,2100 +block_count,KeyedLoadIC_Megamorphic,3,2103 +block_count,KeyedLoadIC_Megamorphic,4,2099 block_count,KeyedLoadIC_Megamorphic,5,3 block_count,KeyedLoadIC_Megamorphic,6,0 block_count,KeyedLoadIC_Megamorphic,7,3 -block_count,KeyedLoadIC_Megamorphic,8,2100 -block_count,KeyedLoadIC_Megamorphic,9,2099 +block_count,KeyedLoadIC_Megamorphic,8,2099 +block_count,KeyedLoadIC_Megamorphic,9,2098 block_count,KeyedLoadIC_Megamorphic,10,48 block_count,KeyedLoadIC_Megamorphic,11,43 block_count,KeyedLoadIC_Megamorphic,12,5 @@ -24952,14 +24968,14 @@ block_count,KeyedLoadIC_Megamorphic,14,2050 block_count,KeyedLoadIC_Megamorphic,15,1952 block_count,KeyedLoadIC_Megamorphic,16,1952 -block_count,KeyedLoadIC_Megamorphic,17,1851 +block_count,KeyedLoadIC_Megamorphic,17,1850 block_count,KeyedLoadIC_Megamorphic,18,0 block_count,KeyedLoadIC_Megamorphic,19,0 block_count,KeyedLoadIC_Megamorphic,20,0 -block_count,KeyedLoadIC_Megamorphic,21,1851 -block_count,KeyedLoadIC_Megamorphic,22,1003 +block_count,KeyedLoadIC_Megamorphic,21,1850 +block_count,KeyedLoadIC_Megamorphic,22,1002 block_count,KeyedLoadIC_Megamorphic,23,848 -block_count,KeyedLoadIC_Megamorphic,24,100 +block_count,KeyedLoadIC_Megamorphic,24,101 block_count,KeyedLoadIC_Megamorphic,25,0 block_count,KeyedLoadIC_Megamorphic,26,97 block_count,KeyedLoadIC_Megamorphic,27,43 @@ -24997,7 +25013,7 @@ block_count,KeyedLoadIC_Megamorphic,59,0 block_count,KeyedLoadIC_Megamorphic,60,0 block_count,KeyedLoadIC_Megamorphic,61,891 -block_count,KeyedLoadIC_Megamorphic,62,891 +block_count,KeyedLoadIC_Megamorphic,62,890 block_count,KeyedLoadIC_Megamorphic,63,800 block_count,KeyedLoadIC_Megamorphic,64,678 block_count,KeyedLoadIC_Megamorphic,65,34 @@ -25008,7 +25024,7 @@ block_count,KeyedLoadIC_Megamorphic,70,298 block_count,KeyedLoadIC_Megamorphic,71,0 block_count,KeyedLoadIC_Megamorphic,72,298 -block_count,KeyedLoadIC_Megamorphic,73,143 +block_count,KeyedLoadIC_Megamorphic,73,142 block_count,KeyedLoadIC_Megamorphic,74,155 block_count,KeyedLoadIC_Megamorphic,75,298 block_count,KeyedLoadIC_Megamorphic,76,263 @@ -25028,7 +25044,7 @@ block_count,KeyedLoadIC_Megamorphic,90,643 block_count,KeyedLoadIC_Megamorphic,91,0 block_count,KeyedLoadIC_Megamorphic,92,643 -block_count,KeyedLoadIC_Megamorphic,93,489 +block_count,KeyedLoadIC_Megamorphic,93,488 block_count,KeyedLoadIC_Megamorphic,94,154 block_count,KeyedLoadIC_Megamorphic,95,230 block_count,KeyedLoadIC_Megamorphic,96,207 @@ -25114,14 +25130,14 @@ block_count,KeyedLoadIC_Megamorphic,176,0 block_count,KeyedLoadIC_Megamorphic,177,0 block_count,KeyedLoadIC_Megamorphic,178,118 -block_count,KeyedLoadIC_Megamorphic,179,773 +block_count,KeyedLoadIC_Megamorphic,179,772 block_count,KeyedLoadIC_Megamorphic,180,0 block_count,KeyedLoadIC_Megamorphic,181,0 block_count,KeyedLoadIC_Megamorphic,182,0 block_count,KeyedLoadIC_Megamorphic,183,0 block_count,KeyedLoadIC_Megamorphic,184,0 -block_count,KeyedLoadIC_Megamorphic,185,773 -block_count,KeyedLoadIC_Megamorphic,186,773 +block_count,KeyedLoadIC_Megamorphic,185,772 +block_count,KeyedLoadIC_Megamorphic,186,772 block_count,KeyedLoadIC_Megamorphic,187,1412 block_count,KeyedLoadIC_Megamorphic,188,1412 block_count,KeyedLoadIC_Megamorphic,189,1352 @@ -25158,10 +25174,10 @@ block_count,KeyedLoadIC_Megamorphic,220,787 block_count,KeyedLoadIC_Megamorphic,221,30 block_count,KeyedLoadIC_Megamorphic,222,756 -block_count,KeyedLoadIC_Megamorphic,223,3071 +block_count,KeyedLoadIC_Megamorphic,223,3070 block_count,KeyedLoadIC_Megamorphic,224,3000 block_count,KeyedLoadIC_Megamorphic,225,2913 -block_count,KeyedLoadIC_Megamorphic,226,2314 +block_count,KeyedLoadIC_Megamorphic,226,2313 block_count,KeyedLoadIC_Megamorphic,227,599 block_count,KeyedLoadIC_Megamorphic,228,86 block_count,KeyedLoadIC_Megamorphic,229,70 @@ -25283,7 +25299,7 @@ block_count,KeyedLoadIC_Megamorphic,345,0 block_count,KeyedLoadIC_Megamorphic,346,0 block_count,KeyedLoadIC_Megamorphic,347,1 -block_count,KeyedLoadIC_Megamorphic,348,1111 +block_count,KeyedLoadIC_Megamorphic,348,1110 block_count,KeyedLoadIC_Megamorphic,349,1110 block_count,KeyedLoadIC_Megamorphic,350,467 block_count,KeyedLoadIC_Megamorphic,351,440 @@ -25349,13 +25365,13 @@ block_count,KeyedLoadIC_Megamorphic,411,116 block_count,KeyedLoadIC_Megamorphic,412,0 block_count,KeyedLoadIC_Megamorphic,413,116 -block_count,KeyedLoadIC_Megamorphic,414,85 -block_count,KeyedLoadIC_Megamorphic,415,85 +block_count,KeyedLoadIC_Megamorphic,414,88 +block_count,KeyedLoadIC_Megamorphic,415,88 block_count,KeyedLoadIC_Megamorphic,416,0 -block_count,KeyedLoadIC_Megamorphic,417,31 -block_count,KeyedLoadIC_Megamorphic,418,31 -block_count,KeyedLoadIC_Megamorphic,419,15 -block_count,KeyedLoadIC_Megamorphic,420,15 +block_count,KeyedLoadIC_Megamorphic,417,28 +block_count,KeyedLoadIC_Megamorphic,418,28 +block_count,KeyedLoadIC_Megamorphic,419,12 +block_count,KeyedLoadIC_Megamorphic,420,12 block_count,KeyedLoadIC_Megamorphic,421,0 block_count,KeyedLoadIC_Megamorphic,422,16 block_count,KeyedLoadIC_Megamorphic,423,100 @@ -25892,7 +25908,7 @@ block_count,KeyedLoadIC_Megamorphic,954,394 block_count,KeyedLoadIC_Megamorphic,955,0 block_count,KeyedLoadIC_Megamorphic,956,0 -block_count,KeyedLoadIC_Megamorphic,957,322 +block_count,KeyedLoadIC_Megamorphic,957,321 block_count,KeyedLoadIC_Megamorphic,958,0 block_count,KeyedLoadIC_Megamorphic,959,0 block_count,KeyedLoadIC_Megamorphic,960,0 @@ -26102,18 +26118,18 @@ block_count,KeyedLoadICTrampoline,1,1 block_count,KeyedLoadICTrampoline,2,0 block_count,KeyedLoadICTrampoline,3,1 -block_count,KeyedLoadICBaseline,0,888 +block_count,KeyedLoadICBaseline,0,895 block_count,EnumeratedKeyedLoadICBaseline,0,5 -block_count,KeyedLoadICTrampoline_Megamorphic,0,1221 -block_count,KeyedLoadICTrampoline_Megamorphic,1,1221 +block_count,KeyedLoadICTrampoline_Megamorphic,0,1220 +block_count,KeyedLoadICTrampoline_Megamorphic,1,1220 block_count,KeyedLoadICTrampoline_Megamorphic,2,0 -block_count,KeyedLoadICTrampoline_Megamorphic,3,1221 -block_count,StoreGlobalIC,0,97 -block_count,StoreGlobalIC,1,97 -block_count,StoreGlobalIC,2,97 -block_count,StoreGlobalIC,3,97 -block_count,StoreGlobalIC,4,97 -block_count,StoreGlobalIC,5,97 +block_count,KeyedLoadICTrampoline_Megamorphic,3,1220 +block_count,StoreGlobalIC,0,321 +block_count,StoreGlobalIC,1,321 +block_count,StoreGlobalIC,2,321 +block_count,StoreGlobalIC,3,321 +block_count,StoreGlobalIC,4,321 +block_count,StoreGlobalIC,5,321 block_count,StoreGlobalIC,6,7 block_count,StoreGlobalIC,7,0 block_count,StoreGlobalIC,8,0 @@ -26123,7 +26139,7 @@ block_count,StoreGlobalIC,12,7 block_count,StoreGlobalIC,13,0 block_count,StoreGlobalIC,14,7 -block_count,StoreGlobalIC,15,89 +block_count,StoreGlobalIC,15,313 block_count,StoreGlobalIC,16,0 block_count,StoreGlobalIC,17,0 block_count,StoreGlobalIC,18,0 @@ -26630,44 +26646,44 @@ block_count,StoreGlobalIC,519,0 block_count,StoreGlobalIC,520,0 block_count,StoreGlobalIC,521,0 -block_count,StoreGlobalICTrampoline,0,0 -block_count,StoreGlobalICTrampoline,1,0 +block_count,StoreGlobalICTrampoline,0,224 +block_count,StoreGlobalICTrampoline,1,224 block_count,StoreGlobalICTrampoline,2,0 -block_count,StoreGlobalICTrampoline,3,0 -block_count,StoreGlobalICBaseline,0,7 -block_count,StoreIC,0,682 -block_count,StoreIC,1,682 +block_count,StoreGlobalICTrampoline,3,224 +block_count,StoreGlobalICBaseline,0,6 +block_count,StoreIC,0,686 +block_count,StoreIC,1,686 block_count,StoreIC,2,0 -block_count,StoreIC,3,682 -block_count,StoreIC,4,682 -block_count,StoreIC,5,675 +block_count,StoreIC,3,686 +block_count,StoreIC,4,686 +block_count,StoreIC,5,679 block_count,StoreIC,6,199 block_count,StoreIC,7,0 block_count,StoreIC,8,199 block_count,StoreIC,9,41 block_count,StoreIC,10,0 -block_count,StoreIC,11,41 -block_count,StoreIC,12,41 +block_count,StoreIC,11,40 +block_count,StoreIC,12,40 block_count,StoreIC,13,0 -block_count,StoreIC,14,41 +block_count,StoreIC,14,40 block_count,StoreIC,15,37 block_count,StoreIC,16,36 -block_count,StoreIC,17,0 -block_count,StoreIC,18,4 +block_count,StoreIC,17,1 +block_count,StoreIC,18,3 block_count,StoreIC,19,4 -block_count,StoreIC,20,3 +block_count,StoreIC,20,4 block_count,StoreIC,21,3 block_count,StoreIC,22,0 block_count,StoreIC,23,0 block_count,StoreIC,24,158 -block_count,StoreIC,25,241 -block_count,StoreIC,26,83 -block_count,StoreIC,27,83 +block_count,StoreIC,25,242 +block_count,StoreIC,26,84 +block_count,StoreIC,27,84 block_count,StoreIC,28,0 -block_count,StoreIC,29,157 -block_count,StoreIC,30,475 -block_count,StoreIC,31,674 -block_count,StoreIC,32,239 +block_count,StoreIC,29,158 +block_count,StoreIC,30,480 +block_count,StoreIC,31,678 +block_count,StoreIC,32,241 block_count,StoreIC,33,9 block_count,StoreIC,34,9 block_count,StoreIC,35,9 @@ -26808,31 +26824,31 @@ block_count,StoreIC,170,0 block_count,StoreIC,171,0 block_count,StoreIC,172,0 -block_count,StoreIC,173,230 -block_count,StoreIC,174,230 -block_count,StoreIC,175,226 -block_count,StoreIC,176,226 -block_count,StoreIC,177,226 +block_count,StoreIC,173,231 +block_count,StoreIC,174,231 +block_count,StoreIC,175,227 +block_count,StoreIC,176,227 +block_count,StoreIC,177,227 block_count,StoreIC,178,0 -block_count,StoreIC,179,226 +block_count,StoreIC,179,227 block_count,StoreIC,180,0 -block_count,StoreIC,181,226 -block_count,StoreIC,182,226 +block_count,StoreIC,181,227 +block_count,StoreIC,182,227 block_count,StoreIC,183,0 block_count,StoreIC,184,0 block_count,StoreIC,185,0 -block_count,StoreIC,186,226 -block_count,StoreIC,187,187 -block_count,StoreIC,188,179 +block_count,StoreIC,186,227 +block_count,StoreIC,187,188 +block_count,StoreIC,188,180 block_count,StoreIC,189,5 block_count,StoreIC,190,5 block_count,StoreIC,191,0 -block_count,StoreIC,192,174 -block_count,StoreIC,193,174 +block_count,StoreIC,192,175 +block_count,StoreIC,193,175 block_count,StoreIC,194,34 block_count,StoreIC,195,0 block_count,StoreIC,196,34 -block_count,StoreIC,197,139 +block_count,StoreIC,197,140 block_count,StoreIC,198,0 block_count,StoreIC,199,7 block_count,StoreIC,200,4 @@ -26842,7 +26858,7 @@ block_count,StoreIC,204,38 block_count,StoreIC,205,0 block_count,StoreIC,206,38 -block_count,StoreIC,207,226 +block_count,StoreIC,207,227 block_count,StoreIC,208,42 block_count,StoreIC,209,0 block_count,StoreIC,210,0 @@ -26856,24 +26872,24 @@ block_count,StoreIC,218,42 block_count,StoreIC,219,0 block_count,StoreIC,220,42 -block_count,StoreIC,221,19 -block_count,StoreIC,222,19 +block_count,StoreIC,221,20 +block_count,StoreIC,222,20 block_count,StoreIC,223,0 -block_count,StoreIC,224,19 +block_count,StoreIC,224,20 block_count,StoreIC,225,0 block_count,StoreIC,226,0 -block_count,StoreIC,227,19 +block_count,StoreIC,227,20 block_count,StoreIC,228,0 -block_count,StoreIC,229,19 +block_count,StoreIC,229,20 block_count,StoreIC,230,0 -block_count,StoreIC,231,19 -block_count,StoreIC,232,19 +block_count,StoreIC,231,20 +block_count,StoreIC,232,20 block_count,StoreIC,233,0 -block_count,StoreIC,234,19 -block_count,StoreIC,235,19 +block_count,StoreIC,234,20 +block_count,StoreIC,235,20 block_count,StoreIC,236,0 -block_count,StoreIC,237,19 -block_count,StoreIC,238,19 +block_count,StoreIC,237,20 +block_count,StoreIC,238,20 block_count,StoreIC,239,12 block_count,StoreIC,240,7 block_count,StoreIC,241,0 @@ -26884,11 +26900,11 @@ block_count,StoreIC,246,7 block_count,StoreIC,247,2 block_count,StoreIC,248,5 -block_count,StoreIC,249,19 +block_count,StoreIC,249,20 block_count,StoreIC,250,22 block_count,StoreIC,251,42 -block_count,StoreIC,252,183 -block_count,StoreIC,253,176 +block_count,StoreIC,252,184 +block_count,StoreIC,253,177 block_count,StoreIC,254,7 block_count,StoreIC,255,4 block_count,StoreIC,256,2 @@ -26916,37 +26932,37 @@ block_count,StoreIC,278,0 block_count,StoreIC,279,0 block_count,StoreIC,280,0 -block_count,StoreIC,281,434 -block_count,StoreIC,282,14 -block_count,StoreIC,283,14 -block_count,StoreIC,284,14 -block_count,StoreIC,285,14 -block_count,StoreIC,286,14 +block_count,StoreIC,281,437 +block_count,StoreIC,282,13 +block_count,StoreIC,283,13 +block_count,StoreIC,284,13 +block_count,StoreIC,285,13 +block_count,StoreIC,286,13 block_count,StoreIC,287,0 -block_count,StoreIC,288,14 -block_count,StoreIC,289,14 +block_count,StoreIC,288,13 +block_count,StoreIC,289,13 block_count,StoreIC,290,14 block_count,StoreIC,291,14 block_count,StoreIC,292,0 -block_count,StoreIC,293,14 +block_count,StoreIC,293,13 block_count,StoreIC,294,0 block_count,StoreIC,295,0 block_count,StoreIC,296,0 block_count,StoreIC,297,0 -block_count,StoreIC,298,14 -block_count,StoreIC,299,14 +block_count,StoreIC,298,13 +block_count,StoreIC,299,13 block_count,StoreIC,300,0 -block_count,StoreIC,301,14 +block_count,StoreIC,301,13 block_count,StoreIC,302,0 block_count,StoreIC,303,0 block_count,StoreIC,304,0 block_count,StoreIC,305,0 -block_count,StoreIC,306,420 -block_count,StoreIC,307,400 -block_count,StoreIC,308,400 +block_count,StoreIC,306,423 +block_count,StoreIC,307,403 +block_count,StoreIC,308,403 block_count,StoreIC,309,40 -block_count,StoreIC,310,36 -block_count,StoreIC,311,36 +block_count,StoreIC,310,37 +block_count,StoreIC,311,37 block_count,StoreIC,312,0 block_count,StoreIC,313,3 block_count,StoreIC,314,40 @@ -26969,19 +26985,19 @@ block_count,StoreIC,331,0 block_count,StoreIC,332,0 block_count,StoreIC,333,0 -block_count,StoreIC,334,190 -block_count,StoreIC,335,190 -block_count,StoreIC,336,190 +block_count,StoreIC,334,192 +block_count,StoreIC,335,192 +block_count,StoreIC,336,192 block_count,StoreIC,337,11 block_count,StoreIC,338,0 block_count,StoreIC,339,11 -block_count,StoreIC,340,179 +block_count,StoreIC,340,180 block_count,StoreIC,341,0 -block_count,StoreIC,342,190 -block_count,StoreIC,343,43 -block_count,StoreIC,344,146 -block_count,StoreIC,345,190 -block_count,StoreIC,346,190 +block_count,StoreIC,342,192 +block_count,StoreIC,343,44 +block_count,StoreIC,344,148 +block_count,StoreIC,345,192 +block_count,StoreIC,346,192 block_count,StoreIC,347,0 block_count,StoreIC,348,0 block_count,StoreIC,349,0 @@ -26989,7 +27005,7 @@ block_count,StoreIC,351,164 block_count,StoreIC,352,0 block_count,StoreIC,353,164 -block_count,StoreIC,354,28 +block_count,StoreIC,354,29 block_count,StoreIC,355,135 block_count,StoreIC,356,164 block_count,StoreIC,357,164 @@ -27019,24 +27035,24 @@ block_count,StoreIC,381,6 block_count,StoreIC,382,0 block_count,StoreIC,383,1 -block_count,StoreIC_Megamorphic,0,1306 -block_count,StoreIC_Megamorphic,1,1306 +block_count,StoreIC_Megamorphic,0,1305 +block_count,StoreIC_Megamorphic,1,1305 block_count,StoreIC_Megamorphic,2,0 -block_count,StoreIC_Megamorphic,3,1306 -block_count,StoreIC_Megamorphic,4,1306 +block_count,StoreIC_Megamorphic,3,1305 +block_count,StoreIC_Megamorphic,4,1305 block_count,StoreIC_Megamorphic,5,0 -block_count,StoreIC_Megamorphic,6,1306 -block_count,StoreIC_Megamorphic,7,1175 -block_count,StoreIC_Megamorphic,8,1062 -block_count,StoreIC_Megamorphic,9,113 -block_count,StoreIC_Megamorphic,10,130 -block_count,StoreIC_Megamorphic,11,244 -block_count,StoreIC_Megamorphic,12,243 -block_count,StoreIC_Megamorphic,13,241 +block_count,StoreIC_Megamorphic,6,1305 +block_count,StoreIC_Megamorphic,7,1181 +block_count,StoreIC_Megamorphic,8,1051 +block_count,StoreIC_Megamorphic,9,129 +block_count,StoreIC_Megamorphic,10,124 +block_count,StoreIC_Megamorphic,11,254 +block_count,StoreIC_Megamorphic,12,253 +block_count,StoreIC_Megamorphic,13,251 block_count,StoreIC_Megamorphic,14,1 block_count,StoreIC_Megamorphic,15,0 block_count,StoreIC_Megamorphic,16,1303 -block_count,StoreIC_Megamorphic,17,522 +block_count,StoreIC_Megamorphic,17,521 block_count,StoreIC_Megamorphic,18,1 block_count,StoreIC_Megamorphic,19,1 block_count,StoreIC_Megamorphic,20,1 @@ -27177,20 +27193,20 @@ block_count,StoreIC_Megamorphic,155,0 block_count,StoreIC_Megamorphic,156,0 block_count,StoreIC_Megamorphic,157,0 -block_count,StoreIC_Megamorphic,158,521 -block_count,StoreIC_Megamorphic,159,521 -block_count,StoreIC_Megamorphic,160,318 -block_count,StoreIC_Megamorphic,161,318 -block_count,StoreIC_Megamorphic,162,318 +block_count,StoreIC_Megamorphic,158,520 +block_count,StoreIC_Megamorphic,159,520 +block_count,StoreIC_Megamorphic,160,317 +block_count,StoreIC_Megamorphic,161,317 +block_count,StoreIC_Megamorphic,162,317 block_count,StoreIC_Megamorphic,163,0 -block_count,StoreIC_Megamorphic,164,318 +block_count,StoreIC_Megamorphic,164,317 block_count,StoreIC_Megamorphic,165,0 -block_count,StoreIC_Megamorphic,166,318 -block_count,StoreIC_Megamorphic,167,318 +block_count,StoreIC_Megamorphic,166,317 +block_count,StoreIC_Megamorphic,167,317 block_count,StoreIC_Megamorphic,168,0 block_count,StoreIC_Megamorphic,169,0 block_count,StoreIC_Megamorphic,170,0 -block_count,StoreIC_Megamorphic,171,318 +block_count,StoreIC_Megamorphic,171,317 block_count,StoreIC_Megamorphic,172,199 block_count,StoreIC_Megamorphic,173,199 block_count,StoreIC_Megamorphic,174,0 @@ -27208,10 +27224,10 @@ block_count,StoreIC_Megamorphic,186,0 block_count,StoreIC_Megamorphic,187,0 block_count,StoreIC_Megamorphic,188,0 -block_count,StoreIC_Megamorphic,189,118 +block_count,StoreIC_Megamorphic,189,117 block_count,StoreIC_Megamorphic,190,0 -block_count,StoreIC_Megamorphic,191,118 -block_count,StoreIC_Megamorphic,192,318 +block_count,StoreIC_Megamorphic,191,117 +block_count,StoreIC_Megamorphic,192,317 block_count,StoreIC_Megamorphic,193,29 block_count,StoreIC_Megamorphic,194,0 block_count,StoreIC_Megamorphic,195,0 @@ -27256,8 +27272,8 @@ block_count,StoreIC_Megamorphic,234,13 block_count,StoreIC_Megamorphic,235,16 block_count,StoreIC_Megamorphic,236,29 -block_count,StoreIC_Megamorphic,237,288 -block_count,StoreIC_Megamorphic,238,288 +block_count,StoreIC_Megamorphic,237,287 +block_count,StoreIC_Megamorphic,238,287 block_count,StoreIC_Megamorphic,239,0 block_count,StoreIC_Megamorphic,240,0 block_count,StoreIC_Megamorphic,241,0 @@ -27313,18 +27329,18 @@ block_count,StoreIC_Megamorphic,291,781 block_count,StoreIC_Megamorphic,292,781 block_count,StoreIC_Megamorphic,293,781 -block_count,StoreIC_Megamorphic,294,6 +block_count,StoreIC_Megamorphic,294,5 block_count,StoreIC_Megamorphic,295,5 block_count,StoreIC_Megamorphic,296,5 block_count,StoreIC_Megamorphic,297,0 block_count,StoreIC_Megamorphic,298,0 -block_count,StoreIC_Megamorphic,299,6 +block_count,StoreIC_Megamorphic,299,5 block_count,StoreIC_Megamorphic,300,0 -block_count,StoreIC_Megamorphic,301,6 +block_count,StoreIC_Megamorphic,301,5 block_count,StoreIC_Megamorphic,302,0 -block_count,StoreIC_Megamorphic,303,6 -block_count,StoreIC_Megamorphic,304,6 -block_count,StoreIC_Megamorphic,305,6 +block_count,StoreIC_Megamorphic,303,5 +block_count,StoreIC_Megamorphic,304,5 +block_count,StoreIC_Megamorphic,305,5 block_count,StoreIC_Megamorphic,306,0 block_count,StoreIC_Megamorphic,307,0 block_count,StoreIC_Megamorphic,308,0 @@ -27355,13 +27371,13 @@ block_count,StoreIC_Megamorphic,333,0 block_count,StoreIC_Megamorphic,334,0 block_count,StoreIC_Megamorphic,335,0 -block_count,StoreIC_Megamorphic,336,329 +block_count,StoreIC_Megamorphic,336,330 block_count,StoreIC_Megamorphic,337,0 -block_count,StoreIC_Megamorphic,338,329 +block_count,StoreIC_Megamorphic,338,330 block_count,StoreIC_Megamorphic,339,2 block_count,StoreIC_Megamorphic,340,327 -block_count,StoreIC_Megamorphic,341,329 -block_count,StoreIC_Megamorphic,342,329 +block_count,StoreIC_Megamorphic,341,330 +block_count,StoreIC_Megamorphic,342,330 block_count,StoreIC_Megamorphic,343,0 block_count,StoreIC_Megamorphic,344,0 block_count,StoreIC_Megamorphic,345,0 @@ -27390,17 +27406,17 @@ block_count,StoreICTrampoline,1,19 block_count,StoreICTrampoline,2,0 block_count,StoreICTrampoline,3,19 -block_count,StoreICTrampoline_Megamorphic,0,630 -block_count,StoreICTrampoline_Megamorphic,1,630 +block_count,StoreICTrampoline_Megamorphic,0,629 +block_count,StoreICTrampoline_Megamorphic,1,629 block_count,StoreICTrampoline_Megamorphic,2,0 -block_count,StoreICTrampoline_Megamorphic,3,630 -block_count,StoreICBaseline,0,619 -block_count,DefineNamedOwnIC,0,80 -block_count,DefineNamedOwnIC,1,80 +block_count,StoreICTrampoline_Megamorphic,3,629 +block_count,StoreICBaseline,0,623 +block_count,DefineNamedOwnIC,0,81 +block_count,DefineNamedOwnIC,1,81 block_count,DefineNamedOwnIC,2,0 -block_count,DefineNamedOwnIC,3,80 -block_count,DefineNamedOwnIC,4,80 -block_count,DefineNamedOwnIC,5,75 +block_count,DefineNamedOwnIC,3,81 +block_count,DefineNamedOwnIC,4,81 +block_count,DefineNamedOwnIC,5,77 block_count,DefineNamedOwnIC,6,0 block_count,DefineNamedOwnIC,7,0 block_count,DefineNamedOwnIC,8,0 @@ -27425,8 +27441,8 @@ block_count,DefineNamedOwnIC,27,0 block_count,DefineNamedOwnIC,28,0 block_count,DefineNamedOwnIC,29,0 -block_count,DefineNamedOwnIC,30,75 -block_count,DefineNamedOwnIC,31,75 +block_count,DefineNamedOwnIC,30,77 +block_count,DefineNamedOwnIC,31,77 block_count,DefineNamedOwnIC,32,0 block_count,DefineNamedOwnIC,33,0 block_count,DefineNamedOwnIC,34,0 @@ -27671,7 +27687,7 @@ block_count,DefineNamedOwnIC,273,0 block_count,DefineNamedOwnIC,274,0 block_count,DefineNamedOwnIC,275,0 -block_count,DefineNamedOwnIC,276,75 +block_count,DefineNamedOwnIC,276,77 block_count,DefineNamedOwnIC,277,0 block_count,DefineNamedOwnIC,278,0 block_count,DefineNamedOwnIC,279,0 @@ -27691,9 +27707,9 @@ block_count,DefineNamedOwnIC,293,0 block_count,DefineNamedOwnIC,294,0 block_count,DefineNamedOwnIC,295,0 -block_count,DefineNamedOwnIC,296,75 -block_count,DefineNamedOwnIC,297,75 -block_count,DefineNamedOwnIC,298,75 +block_count,DefineNamedOwnIC,296,77 +block_count,DefineNamedOwnIC,297,77 +block_count,DefineNamedOwnIC,298,77 block_count,DefineNamedOwnIC,299,1 block_count,DefineNamedOwnIC,300,1 block_count,DefineNamedOwnIC,301,1 @@ -27719,30 +27735,30 @@ block_count,DefineNamedOwnIC,321,0 block_count,DefineNamedOwnIC,322,0 block_count,DefineNamedOwnIC,323,0 -block_count,DefineNamedOwnIC,324,59 -block_count,DefineNamedOwnIC,325,59 -block_count,DefineNamedOwnIC,326,59 +block_count,DefineNamedOwnIC,324,60 +block_count,DefineNamedOwnIC,325,60 +block_count,DefineNamedOwnIC,326,60 block_count,DefineNamedOwnIC,327,9 block_count,DefineNamedOwnIC,328,0 block_count,DefineNamedOwnIC,329,9 -block_count,DefineNamedOwnIC,330,50 +block_count,DefineNamedOwnIC,330,51 block_count,DefineNamedOwnIC,331,0 -block_count,DefineNamedOwnIC,332,59 +block_count,DefineNamedOwnIC,332,60 block_count,DefineNamedOwnIC,333,0 -block_count,DefineNamedOwnIC,334,59 -block_count,DefineNamedOwnIC,335,59 -block_count,DefineNamedOwnIC,336,59 +block_count,DefineNamedOwnIC,334,60 +block_count,DefineNamedOwnIC,335,60 +block_count,DefineNamedOwnIC,336,60 block_count,DefineNamedOwnIC,337,0 block_count,DefineNamedOwnIC,338,0 block_count,DefineNamedOwnIC,339,0 block_count,DefineNamedOwnIC,340,0 -block_count,DefineNamedOwnIC,341,11 +block_count,DefineNamedOwnIC,341,12 block_count,DefineNamedOwnIC,342,0 -block_count,DefineNamedOwnIC,343,11 +block_count,DefineNamedOwnIC,343,12 block_count,DefineNamedOwnIC,344,0 -block_count,DefineNamedOwnIC,345,11 -block_count,DefineNamedOwnIC,346,11 -block_count,DefineNamedOwnIC,347,11 +block_count,DefineNamedOwnIC,345,12 +block_count,DefineNamedOwnIC,346,12 +block_count,DefineNamedOwnIC,347,12 block_count,DefineNamedOwnIC,348,0 block_count,DefineNamedOwnIC,349,0 block_count,DefineNamedOwnIC,350,0 @@ -27769,17 +27785,17 @@ block_count,DefineNamedOwnIC,371,4 block_count,DefineNamedOwnIC,372,0 block_count,DefineNamedOwnIC,373,0 -block_count,DefineNamedOwnICBaseline,0,73 +block_count,DefineNamedOwnICBaseline,0,75 block_count,KeyedStoreIC,0,497 block_count,KeyedStoreIC,1,497 block_count,KeyedStoreIC,2,0 block_count,KeyedStoreIC,3,497 block_count,KeyedStoreIC,4,497 -block_count,KeyedStoreIC,5,495 -block_count,KeyedStoreIC,6,45 +block_count,KeyedStoreIC,5,494 +block_count,KeyedStoreIC,6,44 block_count,KeyedStoreIC,7,0 -block_count,KeyedStoreIC,8,45 -block_count,KeyedStoreIC,9,24 +block_count,KeyedStoreIC,8,44 +block_count,KeyedStoreIC,9,23 block_count,KeyedStoreIC,10,0 block_count,KeyedStoreIC,11,0 block_count,KeyedStoreIC,12,0 @@ -27788,17 +27804,17 @@ block_count,KeyedStoreIC,15,0 block_count,KeyedStoreIC,16,0 block_count,KeyedStoreIC,17,0 -block_count,KeyedStoreIC,18,23 +block_count,KeyedStoreIC,18,22 block_count,KeyedStoreIC,19,21 block_count,KeyedStoreIC,20,37 block_count,KeyedStoreIC,21,16 block_count,KeyedStoreIC,22,16 block_count,KeyedStoreIC,23,0 block_count,KeyedStoreIC,24,21 -block_count,KeyedStoreIC,25,449 +block_count,KeyedStoreIC,25,450 block_count,KeyedStoreIC,26,471 block_count,KeyedStoreIC,27,470 -block_count,KeyedStoreIC,28,469 +block_count,KeyedStoreIC,28,470 block_count,KeyedStoreIC,29,104 block_count,KeyedStoreIC,30,104 block_count,KeyedStoreIC,31,0 @@ -27811,7 +27827,7 @@ block_count,KeyedStoreIC,38,1 block_count,KeyedStoreIC,39,0 block_count,KeyedStoreIC,40,0 -block_count,KeyedStoreIC,41,103 +block_count,KeyedStoreIC,41,102 block_count,KeyedStoreIC,42,0 block_count,KeyedStoreIC,43,0 block_count,KeyedStoreIC,44,0 @@ -28216,11 +28232,11 @@ block_count,KeyedStoreICTrampoline,1,1 block_count,KeyedStoreICTrampoline,2,0 block_count,KeyedStoreICTrampoline,3,1 -block_count,KeyedStoreICTrampoline_Megamorphic,0,309 -block_count,KeyedStoreICTrampoline_Megamorphic,1,309 +block_count,KeyedStoreICTrampoline_Megamorphic,0,310 +block_count,KeyedStoreICTrampoline_Megamorphic,1,310 block_count,KeyedStoreICTrampoline_Megamorphic,2,0 -block_count,KeyedStoreICTrampoline_Megamorphic,3,309 -block_count,KeyedStoreICBaseline,0,451 +block_count,KeyedStoreICTrampoline_Megamorphic,3,310 +block_count,KeyedStoreICBaseline,0,450 block_count,DefineKeyedOwnIC,0,2 block_count,DefineKeyedOwnIC,1,2 block_count,DefineKeyedOwnIC,2,0 @@ -28659,12 +28675,12 @@ block_count,DefineKeyedOwnIC,435,0 block_count,DefineKeyedOwnIC,436,2 block_count,DefineKeyedOwnIC,437,2 -block_count,StoreInArrayLiteralIC,0,42 -block_count,StoreInArrayLiteralIC,1,42 +block_count,StoreInArrayLiteralIC,0,44 +block_count,StoreInArrayLiteralIC,1,44 block_count,StoreInArrayLiteralIC,2,0 -block_count,StoreInArrayLiteralIC,3,42 -block_count,StoreInArrayLiteralIC,4,42 -block_count,StoreInArrayLiteralIC,5,41 +block_count,StoreInArrayLiteralIC,3,44 +block_count,StoreInArrayLiteralIC,4,44 +block_count,StoreInArrayLiteralIC,5,43 block_count,StoreInArrayLiteralIC,6,2 block_count,StoreInArrayLiteralIC,7,0 block_count,StoreInArrayLiteralIC,8,2 @@ -28677,25 +28693,25 @@ block_count,StoreInArrayLiteralIC,15,2 block_count,StoreInArrayLiteralIC,16,0 block_count,StoreInArrayLiteralIC,17,2 -block_count,StoreInArrayLiteralIC,18,39 -block_count,StoreInArrayLiteralIC,19,41 -block_count,StoreInArrayLiteralIC,20,41 +block_count,StoreInArrayLiteralIC,18,40 +block_count,StoreInArrayLiteralIC,19,43 +block_count,StoreInArrayLiteralIC,20,43 block_count,StoreInArrayLiteralIC,21,0 block_count,StoreInArrayLiteralIC,22,0 block_count,StoreInArrayLiteralIC,23,0 block_count,StoreInArrayLiteralIC,24,0 block_count,StoreInArrayLiteralIC,25,0 -block_count,StoreInArrayLiteralIC,26,41 +block_count,StoreInArrayLiteralIC,26,43 block_count,StoreInArrayLiteralIC,27,0 block_count,StoreInArrayLiteralIC,28,1 block_count,StoreInArrayLiteralIC,29,0 block_count,StoreInArrayLiteralIC,30,0 -block_count,StoreInArrayLiteralICBaseline,0,37 -block_count,LoadGlobalIC,0,1043 -block_count,LoadGlobalIC,1,1043 -block_count,LoadGlobalIC,2,938 -block_count,LoadGlobalIC,3,938 -block_count,LoadGlobalIC,4,938 +block_count,StoreInArrayLiteralICBaseline,0,39 +block_count,LoadGlobalIC,0,1204 +block_count,LoadGlobalIC,1,1204 +block_count,LoadGlobalIC,2,1098 +block_count,LoadGlobalIC,3,1098 +block_count,LoadGlobalIC,4,1098 block_count,LoadGlobalIC,5,0 block_count,LoadGlobalIC,6,0 block_count,LoadGlobalIC,7,0 @@ -28916,11 +28932,11 @@ block_count,LoadGlobalIC,222,0 block_count,LoadGlobalIC,223,0 block_count,LoadGlobalIC,224,0 -block_count,LoadGlobalIC,225,104 +block_count,LoadGlobalIC,225,105 block_count,LoadGlobalIC,226,0 -block_count,LoadGlobalIC,227,104 +block_count,LoadGlobalIC,227,105 block_count,LoadGlobalIC,228,0 -block_count,LoadGlobalIC,229,104 +block_count,LoadGlobalIC,229,105 block_count,LoadGlobalICInsideTypeof,0,2 block_count,LoadGlobalICInsideTypeof,1,2 block_count,LoadGlobalICInsideTypeof,2,2 @@ -29146,11 +29162,11 @@ block_count,LoadGlobalICInsideTypeof,222,0 block_count,LoadGlobalICInsideTypeof,223,0 block_count,LoadGlobalICInsideTypeof,224,0 -block_count,LoadGlobalICTrampoline,0,97 -block_count,LoadGlobalICTrampoline,1,97 +block_count,LoadGlobalICTrampoline,0,277 +block_count,LoadGlobalICTrampoline,1,277 block_count,LoadGlobalICTrampoline,2,0 -block_count,LoadGlobalICTrampoline,3,97 -block_count,LoadGlobalICBaseline,0,880 +block_count,LoadGlobalICTrampoline,3,277 +block_count,LoadGlobalICBaseline,0,881 block_count,LoadGlobalICInsideTypeofTrampoline,0,0 block_count,LoadGlobalICInsideTypeofTrampoline,1,0 block_count,LoadGlobalICInsideTypeofTrampoline,2,0 @@ -29182,11 +29198,11 @@ block_count,LookupGlobalICInsideTypeofBaseline,10,0 block_count,LookupGlobalICInsideTypeofBaseline,11,0 block_count,LookupGlobalICInsideTypeofBaseline,12,0 -block_count,KeyedHasIC,0,727 -block_count,KeyedHasIC,1,727 +block_count,KeyedHasIC,0,726 +block_count,KeyedHasIC,1,726 block_count,KeyedHasIC,2,0 -block_count,KeyedHasIC,3,727 -block_count,KeyedHasIC,4,727 +block_count,KeyedHasIC,3,726 +block_count,KeyedHasIC,4,726 block_count,KeyedHasIC,5,726 block_count,KeyedHasIC,6,726 block_count,KeyedHasIC,7,0 @@ -29492,8 +29508,8 @@ block_count,KeyedHasIC_Megamorphic,30,722 block_count,KeyedHasIC_Megamorphic,31,2855 block_count,KeyedHasIC_Megamorphic,32,2855 -block_count,KeyedHasIC_Megamorphic,33,2852 -block_count,KeyedHasIC_Megamorphic,34,2731 +block_count,KeyedHasIC_Megamorphic,33,2851 +block_count,KeyedHasIC_Megamorphic,34,2730 block_count,KeyedHasIC_Megamorphic,35,719 block_count,KeyedHasIC_Megamorphic,36,719 block_count,KeyedHasIC_Megamorphic,37,0 @@ -29503,9 +29519,9 @@ block_count,KeyedHasIC_Megamorphic,41,0 block_count,KeyedHasIC_Megamorphic,42,4316 block_count,KeyedHasIC_Megamorphic,43,1418 -block_count,KeyedHasIC_Megamorphic,44,2898 +block_count,KeyedHasIC_Megamorphic,44,2897 block_count,KeyedHasIC_Megamorphic,45,4316 -block_count,KeyedHasIC_Megamorphic,46,3597 +block_count,KeyedHasIC_Megamorphic,46,3596 block_count,KeyedHasIC_Megamorphic,47,719 block_count,KeyedHasIC_Megamorphic,48,719 block_count,KeyedHasIC_Megamorphic,49,719 @@ -29524,11 +29540,11 @@ block_count,KeyedHasIC_Megamorphic,62,2011 block_count,KeyedHasIC_Megamorphic,63,489 block_count,KeyedHasIC_Megamorphic,64,1522 -block_count,KeyedHasIC_Megamorphic,65,7543 -block_count,KeyedHasIC_Megamorphic,66,7541 -block_count,KeyedHasIC_Megamorphic,67,7538 -block_count,KeyedHasIC_Megamorphic,68,6021 -block_count,KeyedHasIC_Megamorphic,69,1517 +block_count,KeyedHasIC_Megamorphic,65,7542 +block_count,KeyedHasIC_Megamorphic,66,7539 +block_count,KeyedHasIC_Megamorphic,67,7537 +block_count,KeyedHasIC_Megamorphic,68,6020 +block_count,KeyedHasIC_Megamorphic,69,1516 block_count,KeyedHasIC_Megamorphic,70,2 block_count,KeyedHasIC_Megamorphic,71,2 block_count,KeyedHasIC_Megamorphic,72,2006 @@ -29992,7 +30008,7 @@ block_count,IterableToListConvertHoles,7,41 block_count,IterableToListConvertHoles,8,41 block_count,FindOrderedHashMapEntry,0,393 -block_count,FindOrderedHashMapEntry,1,391 +block_count,FindOrderedHashMapEntry,1,390 block_count,FindOrderedHashMapEntry,2,131 block_count,FindOrderedHashMapEntry,3,131 block_count,FindOrderedHashMapEntry,4,131 @@ -30008,9 +30024,9 @@ block_count,FindOrderedHashMapEntry,14,57 block_count,FindOrderedHashMapEntry,15,63 block_count,FindOrderedHashMapEntry,16,131 -block_count,FindOrderedHashMapEntry,17,260 -block_count,FindOrderedHashMapEntry,18,152 -block_count,FindOrderedHashMapEntry,19,128 +block_count,FindOrderedHashMapEntry,17,246 +block_count,FindOrderedHashMapEntry,18,138 +block_count,FindOrderedHashMapEntry,19,114 block_count,FindOrderedHashMapEntry,20,23 block_count,FindOrderedHashMapEntry,21,107 block_count,FindOrderedHashMapEntry,22,0 @@ -30063,7 +30079,7 @@ block_count,FindOrderedHashMapEntry,69,42 block_count,FindOrderedHashMapEntry,70,2 block_count,FindOrderedHashMapEntry,71,6 -block_count,FindOrderedHashMapEntry,72,4 +block_count,FindOrderedHashMapEntry,72,3 block_count,FindOrderedHashMapEntry,73,3 block_count,FindOrderedHashMapEntry,74,1 block_count,FindOrderedHashMapEntry,75,0 @@ -30854,26 +30870,26 @@ block_count,MapIteratorToList,54,0 block_count,MapIteratorToList,55,0 block_count,MapIteratorToList,56,0 -block_count,Add_Baseline,0,571 -block_count,Add_Baseline,1,333 -block_count,Add_Baseline,2,5 +block_count,Add_Baseline,0,574 +block_count,Add_Baseline,1,335 +block_count,Add_Baseline,2,6 block_count,Add_Baseline,3,5 block_count,Add_Baseline,4,0 -block_count,Add_Baseline,5,327 -block_count,Add_Baseline,6,327 +block_count,Add_Baseline,5,329 +block_count,Add_Baseline,6,328 block_count,Add_Baseline,7,0 -block_count,Add_Baseline,8,327 -block_count,Add_Baseline,9,327 +block_count,Add_Baseline,8,328 +block_count,Add_Baseline,9,328 block_count,Add_Baseline,10,0 -block_count,Add_Baseline,11,237 -block_count,Add_Baseline,12,143 -block_count,Add_Baseline,13,122 -block_count,Add_Baseline,14,122 +block_count,Add_Baseline,11,238 +block_count,Add_Baseline,12,144 +block_count,Add_Baseline,13,124 +block_count,Add_Baseline,14,124 block_count,Add_Baseline,15,0 block_count,Add_Baseline,16,20 block_count,Add_Baseline,17,93 block_count,Add_Baseline,18,93 -block_count,Add_Baseline,19,87 +block_count,Add_Baseline,19,88 block_count,Add_Baseline,20,0 block_count,Add_Baseline,21,0 block_count,Add_Baseline,22,0 @@ -30896,10 +30912,10 @@ block_count,Add_Baseline,39,0 block_count,Add_Baseline,40,0 block_count,Add_Baseline,41,0 -block_count,Add_Baseline,42,80 +block_count,Add_Baseline,42,81 block_count,Add_Baseline,43,0 block_count,Add_Baseline,44,80 -block_count,Add_Baseline,45,80 +block_count,Add_Baseline,45,81 block_count,Add_Baseline,46,5 block_count,Add_Baseline,47,0 block_count,Add_Baseline,48,0 @@ -30909,25 +30925,25 @@ block_count,Add_Baseline,52,0 block_count,Add_Baseline,53,0 block_count,Add_Baseline,54,0 -block_count,Add_Baseline,55,13 +block_count,Add_Baseline,55,12 block_count,Add_Baseline,56,0 block_count,Add_Baseline,57,13 block_count,Add_Baseline,58,0 block_count,Add_Baseline,59,13 block_count,Add_Baseline,60,13 -block_count,Add_Baseline,61,149 +block_count,Add_Baseline,61,151 block_count,Add_Baseline,62,0 -block_count,Add_Baseline,63,149 -block_count,Add_Baseline,64,149 +block_count,Add_Baseline,63,151 +block_count,Add_Baseline,64,151 block_count,Add_Baseline,65,0 -block_count,Add_Baseline,66,149 -block_count,Add_Baseline,67,149 -block_count,AddSmi_Baseline,0,553 -block_count,AddSmi_Baseline,1,550 -block_count,AddSmi_Baseline,2,550 +block_count,Add_Baseline,66,151 +block_count,Add_Baseline,67,151 +block_count,AddSmi_Baseline,0,555 +block_count,AddSmi_Baseline,1,552 +block_count,AddSmi_Baseline,2,552 block_count,AddSmi_Baseline,3,0 -block_count,AddSmi_Baseline,4,550 -block_count,AddSmi_Baseline,5,550 +block_count,AddSmi_Baseline,4,552 +block_count,AddSmi_Baseline,5,552 block_count,AddSmi_Baseline,6,0 block_count,AddSmi_Baseline,7,2 block_count,AddSmi_Baseline,8,2 @@ -30981,21 +30997,21 @@ block_count,AddSmi_Baseline,56,0 block_count,AddSmi_Baseline,57,2 block_count,AddSmi_Baseline,58,2 -block_count,Subtract_Baseline,0,123 +block_count,Subtract_Baseline,0,124 block_count,Subtract_Baseline,1,65 block_count,Subtract_Baseline,2,5 block_count,Subtract_Baseline,3,5 block_count,Subtract_Baseline,4,0 -block_count,Subtract_Baseline,5,59 -block_count,Subtract_Baseline,6,59 +block_count,Subtract_Baseline,5,60 +block_count,Subtract_Baseline,6,60 block_count,Subtract_Baseline,7,0 block_count,Subtract_Baseline,8,0 block_count,Subtract_Baseline,9,0 block_count,Subtract_Baseline,10,0 -block_count,Subtract_Baseline,11,59 +block_count,Subtract_Baseline,11,60 block_count,Subtract_Baseline,12,0 -block_count,Subtract_Baseline,13,59 -block_count,Subtract_Baseline,14,59 +block_count,Subtract_Baseline,13,60 +block_count,Subtract_Baseline,14,60 block_count,Subtract_Baseline,15,58 block_count,Subtract_Baseline,16,58 block_count,Subtract_Baseline,17,55 @@ -31038,7 +31054,7 @@ block_count,Subtract_Baseline,54,0 block_count,Subtract_Baseline,55,64 block_count,Subtract_Baseline,56,64 -block_count,SubtractSmi_Baseline,0,71 +block_count,SubtractSmi_Baseline,0,72 block_count,SubtractSmi_Baseline,1,54 block_count,SubtractSmi_Baseline,2,54 block_count,SubtractSmi_Baseline,3,0 @@ -31057,20 +31073,20 @@ block_count,SubtractSmi_Baseline,16,0 block_count,SubtractSmi_Baseline,17,17 block_count,SubtractSmi_Baseline,18,17 -block_count,Multiply_Baseline,0,181 -block_count,Multiply_Baseline,1,30 +block_count,Multiply_Baseline,0,185 +block_count,Multiply_Baseline,1,31 block_count,Multiply_Baseline,2,15 block_count,Multiply_Baseline,3,15 block_count,Multiply_Baseline,4,0 -block_count,Multiply_Baseline,5,14 -block_count,Multiply_Baseline,6,14 -block_count,Multiply_Baseline,7,11 -block_count,Multiply_Baseline,8,11 +block_count,Multiply_Baseline,5,15 +block_count,Multiply_Baseline,6,15 +block_count,Multiply_Baseline,7,12 +block_count,Multiply_Baseline,8,12 block_count,Multiply_Baseline,9,0 block_count,Multiply_Baseline,10,0 block_count,Multiply_Baseline,11,0 block_count,Multiply_Baseline,12,0 -block_count,Multiply_Baseline,13,11 +block_count,Multiply_Baseline,13,12 block_count,Multiply_Baseline,14,2 block_count,Multiply_Baseline,15,2 block_count,Multiply_Baseline,16,0 @@ -31078,19 +31094,19 @@ block_count,Multiply_Baseline,18,0 block_count,Multiply_Baseline,19,0 block_count,Multiply_Baseline,20,0 -block_count,Multiply_Baseline,21,14 +block_count,Multiply_Baseline,21,15 block_count,Multiply_Baseline,22,0 -block_count,Multiply_Baseline,23,14 -block_count,Multiply_Baseline,24,14 +block_count,Multiply_Baseline,23,15 +block_count,Multiply_Baseline,24,15 block_count,Multiply_Baseline,25,0 -block_count,Multiply_Baseline,26,14 -block_count,Multiply_Baseline,27,14 -block_count,Multiply_Baseline,28,151 -block_count,Multiply_Baseline,29,151 -block_count,Multiply_Baseline,30,142 -block_count,Multiply_Baseline,31,142 +block_count,Multiply_Baseline,26,15 +block_count,Multiply_Baseline,27,15 +block_count,Multiply_Baseline,28,154 +block_count,Multiply_Baseline,29,154 +block_count,Multiply_Baseline,30,144 +block_count,Multiply_Baseline,31,144 block_count,Multiply_Baseline,32,0 -block_count,Multiply_Baseline,33,8 +block_count,Multiply_Baseline,33,10 block_count,Multiply_Baseline,34,0 block_count,Multiply_Baseline,35,0 block_count,Multiply_Baseline,36,0 @@ -31122,16 +31138,16 @@ block_count,Multiply_Baseline,62,0 block_count,Multiply_Baseline,63,0 block_count,Multiply_Baseline,64,0 -block_count,Multiply_Baseline,65,166 +block_count,Multiply_Baseline,65,169 block_count,Multiply_Baseline,66,0 -block_count,Multiply_Baseline,67,166 -block_count,Multiply_Baseline,68,166 +block_count,Multiply_Baseline,67,169 +block_count,Multiply_Baseline,68,169 block_count,Multiply_Baseline,69,0 -block_count,Multiply_Baseline,70,166 -block_count,Multiply_Baseline,71,166 +block_count,Multiply_Baseline,70,169 +block_count,Multiply_Baseline,71,169 block_count,MultiplySmi_Baseline,0,29 block_count,MultiplySmi_Baseline,1,24 -block_count,MultiplySmi_Baseline,2,24 +block_count,MultiplySmi_Baseline,2,23 block_count,MultiplySmi_Baseline,3,16 block_count,MultiplySmi_Baseline,4,16 block_count,MultiplySmi_Baseline,5,0 @@ -31148,7 +31164,7 @@ block_count,MultiplySmi_Baseline,16,0 block_count,MultiplySmi_Baseline,17,24 block_count,MultiplySmi_Baseline,18,0 -block_count,MultiplySmi_Baseline,19,24 +block_count,MultiplySmi_Baseline,19,23 block_count,MultiplySmi_Baseline,20,24 block_count,MultiplySmi_Baseline,21,0 block_count,MultiplySmi_Baseline,22,24 @@ -31276,7 +31292,7 @@ block_count,DivideSmi_Baseline,10,0 block_count,DivideSmi_Baseline,11,0 block_count,DivideSmi_Baseline,12,3 -block_count,DivideSmi_Baseline,13,0 +block_count,DivideSmi_Baseline,13,1 block_count,DivideSmi_Baseline,14,2 block_count,DivideSmi_Baseline,15,0 block_count,DivideSmi_Baseline,16,2 @@ -31518,8 +31534,8 @@ block_count,BitwiseAnd_Baseline,43,5 block_count,BitwiseAnd_Baseline,44,32 block_count,BitwiseAnd_Baseline,45,23 -block_count,BitwiseAnd_Baseline,46,8 -block_count,BitwiseAnd_Baseline,47,8 +block_count,BitwiseAnd_Baseline,46,9 +block_count,BitwiseAnd_Baseline,47,9 block_count,BitwiseAnd_Baseline,48,1 block_count,BitwiseAnd_Baseline,49,1 block_count,BitwiseAnd_Baseline,50,0 @@ -31539,19 +31555,19 @@ block_count,BitwiseAnd_Baseline,64,0 block_count,BitwiseAnd_Baseline,65,7 block_count,BitwiseAnd_Baseline,66,32 -block_count,BitwiseAnd_Baseline,67,27 +block_count,BitwiseAnd_Baseline,67,28 block_count,BitwiseAnd_Baseline,68,4 block_count,BitwiseAnd_Baseline,69,0 block_count,BitwiseAnd_Baseline,70,4 block_count,BitwiseAnd_Baseline,71,4 block_count,BitwiseAnd_Baseline,72,32 block_count,BitwiseAnd_Baseline,73,4 -block_count,BitwiseAnd_Baseline,74,27 +block_count,BitwiseAnd_Baseline,74,28 block_count,BitwiseAnd_Baseline,75,32 block_count,BitwiseAnd_Baseline,76,0 block_count,BitwiseAnd_Baseline,77,32 block_count,BitwiseAnd_Baseline,78,32 -block_count,BitwiseAndSmi_Baseline,0,114 +block_count,BitwiseAndSmi_Baseline,0,116 block_count,BitwiseAndSmi_Baseline,1,6 block_count,BitwiseAndSmi_Baseline,2,6 block_count,BitwiseAndSmi_Baseline,3,1 @@ -31582,11 +31598,11 @@ block_count,BitwiseAndSmi_Baseline,28,0 block_count,BitwiseAndSmi_Baseline,29,6 block_count,BitwiseAndSmi_Baseline,30,6 -block_count,BitwiseAndSmi_Baseline,31,108 -block_count,BitwiseAndSmi_Baseline,32,114 +block_count,BitwiseAndSmi_Baseline,31,109 +block_count,BitwiseAndSmi_Baseline,32,116 block_count,BitwiseAndSmi_Baseline,33,0 -block_count,BitwiseAndSmi_Baseline,34,114 -block_count,BitwiseOr_Baseline,0,58 +block_count,BitwiseAndSmi_Baseline,34,116 +block_count,BitwiseOr_Baseline,0,59 block_count,BitwiseOr_Baseline,1,54 block_count,BitwiseOr_Baseline,2,4 block_count,BitwiseOr_Baseline,3,5 @@ -31630,7 +31646,7 @@ block_count,BitwiseOr_Baseline,41,0 block_count,BitwiseOr_Baseline,42,0 block_count,BitwiseOr_Baseline,43,4 -block_count,BitwiseOr_Baseline,44,58 +block_count,BitwiseOr_Baseline,44,59 block_count,BitwiseOr_Baseline,45,55 block_count,BitwiseOr_Baseline,46,3 block_count,BitwiseOr_Baseline,47,3 @@ -31652,22 +31668,22 @@ block_count,BitwiseOr_Baseline,63,0 block_count,BitwiseOr_Baseline,64,0 block_count,BitwiseOr_Baseline,65,3 -block_count,BitwiseOr_Baseline,66,58 -block_count,BitwiseOr_Baseline,67,52 -block_count,BitwiseOr_Baseline,68,6 +block_count,BitwiseOr_Baseline,66,59 +block_count,BitwiseOr_Baseline,67,53 +block_count,BitwiseOr_Baseline,68,5 block_count,BitwiseOr_Baseline,69,0 -block_count,BitwiseOr_Baseline,70,6 -block_count,BitwiseOr_Baseline,71,6 -block_count,BitwiseOr_Baseline,72,58 -block_count,BitwiseOr_Baseline,73,6 -block_count,BitwiseOr_Baseline,74,52 -block_count,BitwiseOr_Baseline,75,58 +block_count,BitwiseOr_Baseline,70,5 +block_count,BitwiseOr_Baseline,71,5 +block_count,BitwiseOr_Baseline,72,59 +block_count,BitwiseOr_Baseline,73,5 +block_count,BitwiseOr_Baseline,74,53 +block_count,BitwiseOr_Baseline,75,59 block_count,BitwiseOr_Baseline,76,0 -block_count,BitwiseOr_Baseline,77,58 -block_count,BitwiseOr_Baseline,78,58 -block_count,BitwiseOrSmi_Baseline,0,284 +block_count,BitwiseOr_Baseline,77,59 +block_count,BitwiseOr_Baseline,78,59 +block_count,BitwiseOrSmi_Baseline,0,285 block_count,BitwiseOrSmi_Baseline,1,4 -block_count,BitwiseOrSmi_Baseline,2,4 +block_count,BitwiseOrSmi_Baseline,2,5 block_count,BitwiseOrSmi_Baseline,3,0 block_count,BitwiseOrSmi_Baseline,4,0 block_count,BitwiseOrSmi_Baseline,5,0 @@ -31696,14 +31712,14 @@ block_count,BitwiseOrSmi_Baseline,28,2 block_count,BitwiseOrSmi_Baseline,29,2 block_count,BitwiseOrSmi_Baseline,30,4 -block_count,BitwiseOrSmi_Baseline,31,279 -block_count,BitwiseOrSmi_Baseline,32,284 +block_count,BitwiseOrSmi_Baseline,31,280 +block_count,BitwiseOrSmi_Baseline,32,285 block_count,BitwiseOrSmi_Baseline,33,0 -block_count,BitwiseOrSmi_Baseline,34,284 -block_count,BitwiseXor_Baseline,0,40 -block_count,BitwiseXor_Baseline,1,22 -block_count,BitwiseXor_Baseline,2,17 -block_count,BitwiseXor_Baseline,3,17 +block_count,BitwiseOrSmi_Baseline,34,285 +block_count,BitwiseXor_Baseline,0,41 +block_count,BitwiseXor_Baseline,1,23 +block_count,BitwiseXor_Baseline,2,18 +block_count,BitwiseXor_Baseline,3,18 block_count,BitwiseXor_Baseline,4,0 block_count,BitwiseXor_Baseline,5,0 block_count,BitwiseXor_Baseline,6,0 @@ -31743,11 +31759,11 @@ block_count,BitwiseXor_Baseline,40,0 block_count,BitwiseXor_Baseline,41,0 block_count,BitwiseXor_Baseline,42,0 -block_count,BitwiseXor_Baseline,43,17 -block_count,BitwiseXor_Baseline,44,40 -block_count,BitwiseXor_Baseline,45,18 -block_count,BitwiseXor_Baseline,46,21 -block_count,BitwiseXor_Baseline,47,21 +block_count,BitwiseXor_Baseline,43,18 +block_count,BitwiseXor_Baseline,44,41 +block_count,BitwiseXor_Baseline,45,19 +block_count,BitwiseXor_Baseline,46,22 +block_count,BitwiseXor_Baseline,47,22 block_count,BitwiseXor_Baseline,48,0 block_count,BitwiseXor_Baseline,49,0 block_count,BitwiseXor_Baseline,50,0 @@ -31765,20 +31781,20 @@ block_count,BitwiseXor_Baseline,62,0 block_count,BitwiseXor_Baseline,63,0 block_count,BitwiseXor_Baseline,64,0 -block_count,BitwiseXor_Baseline,65,21 -block_count,BitwiseXor_Baseline,66,40 +block_count,BitwiseXor_Baseline,65,22 +block_count,BitwiseXor_Baseline,66,41 block_count,BitwiseXor_Baseline,67,25 block_count,BitwiseXor_Baseline,68,15 block_count,BitwiseXor_Baseline,69,0 block_count,BitwiseXor_Baseline,70,15 block_count,BitwiseXor_Baseline,71,15 -block_count,BitwiseXor_Baseline,72,40 +block_count,BitwiseXor_Baseline,72,41 block_count,BitwiseXor_Baseline,73,15 block_count,BitwiseXor_Baseline,74,25 -block_count,BitwiseXor_Baseline,75,40 +block_count,BitwiseXor_Baseline,75,41 block_count,BitwiseXor_Baseline,76,0 -block_count,BitwiseXor_Baseline,77,40 -block_count,BitwiseXor_Baseline,78,40 +block_count,BitwiseXor_Baseline,77,41 +block_count,BitwiseXor_Baseline,78,41 block_count,BitwiseXorSmi_Baseline,0,1 block_count,BitwiseXorSmi_Baseline,1,0 block_count,BitwiseXorSmi_Baseline,2,0 @@ -31893,7 +31909,7 @@ block_count,ShiftLeft_Baseline,76,0 block_count,ShiftLeft_Baseline,77,5 block_count,ShiftLeft_Baseline,78,5 -block_count,ShiftLeftSmi_Baseline,0,76 +block_count,ShiftLeftSmi_Baseline,0,78 block_count,ShiftLeftSmi_Baseline,1,6 block_count,ShiftLeftSmi_Baseline,2,6 block_count,ShiftLeftSmi_Baseline,3,0 @@ -31924,19 +31940,19 @@ block_count,ShiftLeftSmi_Baseline,28,2 block_count,ShiftLeftSmi_Baseline,29,4 block_count,ShiftLeftSmi_Baseline,30,6 -block_count,ShiftLeftSmi_Baseline,31,69 -block_count,ShiftLeftSmi_Baseline,32,67 +block_count,ShiftLeftSmi_Baseline,31,71 +block_count,ShiftLeftSmi_Baseline,32,68 block_count,ShiftLeftSmi_Baseline,33,2 block_count,ShiftLeftSmi_Baseline,34,0 block_count,ShiftLeftSmi_Baseline,35,2 block_count,ShiftLeftSmi_Baseline,36,2 -block_count,ShiftLeftSmi_Baseline,37,69 +block_count,ShiftLeftSmi_Baseline,37,71 block_count,ShiftLeftSmi_Baseline,38,2 -block_count,ShiftLeftSmi_Baseline,39,67 -block_count,ShiftLeftSmi_Baseline,40,69 -block_count,ShiftLeftSmi_Baseline,41,76 +block_count,ShiftLeftSmi_Baseline,39,68 +block_count,ShiftLeftSmi_Baseline,40,71 +block_count,ShiftLeftSmi_Baseline,41,78 block_count,ShiftLeftSmi_Baseline,42,0 -block_count,ShiftLeftSmi_Baseline,43,76 +block_count,ShiftLeftSmi_Baseline,43,78 block_count,ShiftRight_Baseline,0,7 block_count,ShiftRight_Baseline,1,7 block_count,ShiftRight_Baseline,2,0 @@ -32016,7 +32032,7 @@ block_count,ShiftRight_Baseline,76,0 block_count,ShiftRight_Baseline,77,7 block_count,ShiftRight_Baseline,78,7 -block_count,ShiftRightSmi_Baseline,0,236 +block_count,ShiftRightSmi_Baseline,0,238 block_count,ShiftRightSmi_Baseline,1,5 block_count,ShiftRightSmi_Baseline,2,5 block_count,ShiftRightSmi_Baseline,3,0 @@ -32047,10 +32063,10 @@ block_count,ShiftRightSmi_Baseline,28,0 block_count,ShiftRightSmi_Baseline,29,5 block_count,ShiftRightSmi_Baseline,30,5 -block_count,ShiftRightSmi_Baseline,31,231 -block_count,ShiftRightSmi_Baseline,32,236 +block_count,ShiftRightSmi_Baseline,31,232 +block_count,ShiftRightSmi_Baseline,32,238 block_count,ShiftRightSmi_Baseline,33,0 -block_count,ShiftRightSmi_Baseline,34,236 +block_count,ShiftRightSmi_Baseline,34,238 block_count,ShiftRightLogical_Baseline,0,1 block_count,ShiftRightLogical_Baseline,1,1 block_count,ShiftRightLogical_Baseline,2,0 @@ -32128,8 +32144,8 @@ block_count,ShiftRightLogical_Baseline,74,0 block_count,ShiftRightLogical_Baseline,75,1 block_count,ShiftRightLogicalSmi_Baseline,0,18 -block_count,ShiftRightLogicalSmi_Baseline,1,8 -block_count,ShiftRightLogicalSmi_Baseline,2,8 +block_count,ShiftRightLogicalSmi_Baseline,1,9 +block_count,ShiftRightLogicalSmi_Baseline,2,9 block_count,ShiftRightLogicalSmi_Baseline,3,0 block_count,ShiftRightLogicalSmi_Baseline,4,0 block_count,ShiftRightLogicalSmi_Baseline,5,0 @@ -32147,35 +32163,35 @@ block_count,ShiftRightLogicalSmi_Baseline,17,0 block_count,ShiftRightLogicalSmi_Baseline,18,0 block_count,ShiftRightLogicalSmi_Baseline,19,0 -block_count,ShiftRightLogicalSmi_Baseline,20,8 -block_count,ShiftRightLogicalSmi_Baseline,21,8 -block_count,ShiftRightLogicalSmi_Baseline,22,8 +block_count,ShiftRightLogicalSmi_Baseline,20,9 +block_count,ShiftRightLogicalSmi_Baseline,21,9 +block_count,ShiftRightLogicalSmi_Baseline,22,9 block_count,ShiftRightLogicalSmi_Baseline,23,0 block_count,ShiftRightLogicalSmi_Baseline,24,0 block_count,ShiftRightLogicalSmi_Baseline,25,0 block_count,ShiftRightLogicalSmi_Baseline,26,0 -block_count,ShiftRightLogicalSmi_Baseline,27,8 +block_count,ShiftRightLogicalSmi_Baseline,27,9 block_count,ShiftRightLogicalSmi_Baseline,28,0 -block_count,ShiftRightLogicalSmi_Baseline,29,8 -block_count,ShiftRightLogicalSmi_Baseline,30,8 +block_count,ShiftRightLogicalSmi_Baseline,29,9 +block_count,ShiftRightLogicalSmi_Baseline,30,9 block_count,ShiftRightLogicalSmi_Baseline,31,9 -block_count,ShiftRightLogicalSmi_Baseline,32,8 +block_count,ShiftRightLogicalSmi_Baseline,32,9 block_count,ShiftRightLogicalSmi_Baseline,33,0 block_count,ShiftRightLogicalSmi_Baseline,34,0 block_count,ShiftRightLogicalSmi_Baseline,35,0 block_count,ShiftRightLogicalSmi_Baseline,36,0 block_count,ShiftRightLogicalSmi_Baseline,37,9 block_count,ShiftRightLogicalSmi_Baseline,38,0 -block_count,ShiftRightLogicalSmi_Baseline,39,8 +block_count,ShiftRightLogicalSmi_Baseline,39,9 block_count,ShiftRightLogicalSmi_Baseline,40,9 block_count,ShiftRightLogicalSmi_Baseline,41,18 block_count,ShiftRightLogicalSmi_Baseline,42,0 block_count,ShiftRightLogicalSmi_Baseline,43,18 -block_count,Equal_Baseline,0,337 -block_count,Equal_Baseline,1,341 -block_count,Equal_Baseline,2,258 -block_count,Equal_Baseline,3,59 -block_count,Equal_Baseline,4,57 +block_count,Equal_Baseline,0,334 +block_count,Equal_Baseline,1,338 +block_count,Equal_Baseline,2,256 +block_count,Equal_Baseline,3,61 +block_count,Equal_Baseline,4,58 block_count,Equal_Baseline,5,23 block_count,Equal_Baseline,6,22 block_count,Equal_Baseline,7,19 @@ -32241,24 +32257,24 @@ block_count,Equal_Baseline,67,0 block_count,Equal_Baseline,68,0 block_count,Equal_Baseline,69,0 -block_count,Equal_Baseline,70,34 +block_count,Equal_Baseline,70,35 block_count,Equal_Baseline,71,0 -block_count,Equal_Baseline,72,33 -block_count,Equal_Baseline,73,24 -block_count,Equal_Baseline,74,9 -block_count,Equal_Baseline,75,9 -block_count,Equal_Baseline,76,9 +block_count,Equal_Baseline,72,35 +block_count,Equal_Baseline,73,25 +block_count,Equal_Baseline,74,10 +block_count,Equal_Baseline,75,10 +block_count,Equal_Baseline,76,10 block_count,Equal_Baseline,77,0 -block_count,Equal_Baseline,78,33 +block_count,Equal_Baseline,78,35 block_count,Equal_Baseline,79,4 -block_count,Equal_Baseline,80,29 -block_count,Equal_Baseline,81,33 +block_count,Equal_Baseline,80,30 +block_count,Equal_Baseline,81,35 block_count,Equal_Baseline,82,0 -block_count,Equal_Baseline,83,33 -block_count,Equal_Baseline,84,33 +block_count,Equal_Baseline,83,35 +block_count,Equal_Baseline,84,35 block_count,Equal_Baseline,85,2 block_count,Equal_Baseline,86,2 -block_count,Equal_Baseline,87,198 +block_count,Equal_Baseline,87,194 block_count,Equal_Baseline,88,4 block_count,Equal_Baseline,89,0 block_count,Equal_Baseline,90,0 @@ -32278,7 +32294,7 @@ block_count,Equal_Baseline,104,0 block_count,Equal_Baseline,105,0 block_count,Equal_Baseline,106,4 -block_count,Equal_Baseline,107,193 +block_count,Equal_Baseline,107,190 block_count,Equal_Baseline,108,0 block_count,Equal_Baseline,109,0 block_count,Equal_Baseline,110,0 @@ -32294,9 +32310,9 @@ block_count,Equal_Baseline,120,7 block_count,Equal_Baseline,121,4 block_count,Equal_Baseline,122,2 -block_count,Equal_Baseline,123,82 +block_count,Equal_Baseline,123,81 block_count,Equal_Baseline,124,16 -block_count,Equal_Baseline,125,15 +block_count,Equal_Baseline,125,16 block_count,Equal_Baseline,126,10 block_count,Equal_Baseline,127,3 block_count,Equal_Baseline,128,0 @@ -32313,50 +32329,50 @@ block_count,Equal_Baseline,139,0 block_count,Equal_Baseline,140,0 block_count,Equal_Baseline,141,0 -block_count,Equal_Baseline,142,66 -block_count,Equal_Baseline,143,85 -block_count,Equal_Baseline,144,217 -block_count,Equal_Baseline,145,337 +block_count,Equal_Baseline,142,65 +block_count,Equal_Baseline,143,84 +block_count,Equal_Baseline,144,214 +block_count,Equal_Baseline,145,334 block_count,Equal_Baseline,146,0 -block_count,Equal_Baseline,147,337 -block_count,StrictEqual_Baseline,0,502 -block_count,StrictEqual_Baseline,1,416 +block_count,Equal_Baseline,147,334 +block_count,StrictEqual_Baseline,0,497 +block_count,StrictEqual_Baseline,1,412 block_count,StrictEqual_Baseline,2,288 block_count,StrictEqual_Baseline,3,288 block_count,StrictEqual_Baseline,4,287 -block_count,StrictEqual_Baseline,5,139 -block_count,StrictEqual_Baseline,6,139 +block_count,StrictEqual_Baseline,5,140 +block_count,StrictEqual_Baseline,6,140 block_count,StrictEqual_Baseline,7,62 block_count,StrictEqual_Baseline,8,60 -block_count,StrictEqual_Baseline,9,49 +block_count,StrictEqual_Baseline,9,48 block_count,StrictEqual_Baseline,10,0 -block_count,StrictEqual_Baseline,11,49 +block_count,StrictEqual_Baseline,11,48 block_count,StrictEqual_Baseline,12,0 -block_count,StrictEqual_Baseline,13,49 +block_count,StrictEqual_Baseline,13,48 block_count,StrictEqual_Baseline,14,11 block_count,StrictEqual_Baseline,15,5 block_count,StrictEqual_Baseline,16,6 -block_count,StrictEqual_Baseline,17,1 -block_count,StrictEqual_Baseline,18,77 -block_count,StrictEqual_Baseline,19,77 +block_count,StrictEqual_Baseline,17,2 +block_count,StrictEqual_Baseline,18,78 +block_count,StrictEqual_Baseline,19,78 block_count,StrictEqual_Baseline,20,0 block_count,StrictEqual_Baseline,21,0 block_count,StrictEqual_Baseline,22,0 -block_count,StrictEqual_Baseline,23,76 +block_count,StrictEqual_Baseline,23,77 block_count,StrictEqual_Baseline,24,0 block_count,StrictEqual_Baseline,25,0 block_count,StrictEqual_Baseline,26,0 block_count,StrictEqual_Baseline,27,0 -block_count,StrictEqual_Baseline,28,147 +block_count,StrictEqual_Baseline,28,146 block_count,StrictEqual_Baseline,29,0 -block_count,StrictEqual_Baseline,30,146 -block_count,StrictEqual_Baseline,31,41 -block_count,StrictEqual_Baseline,32,105 -block_count,StrictEqual_Baseline,33,146 +block_count,StrictEqual_Baseline,30,145 +block_count,StrictEqual_Baseline,31,39 +block_count,StrictEqual_Baseline,32,106 +block_count,StrictEqual_Baseline,33,145 block_count,StrictEqual_Baseline,34,0 -block_count,StrictEqual_Baseline,35,145 -block_count,StrictEqual_Baseline,36,146 -block_count,StrictEqual_Baseline,37,102 +block_count,StrictEqual_Baseline,35,144 +block_count,StrictEqual_Baseline,36,145 +block_count,StrictEqual_Baseline,37,100 block_count,StrictEqual_Baseline,38,44 block_count,StrictEqual_Baseline,39,1 block_count,StrictEqual_Baseline,40,0 @@ -32368,18 +32384,18 @@ block_count,StrictEqual_Baseline,46,0 block_count,StrictEqual_Baseline,47,0 block_count,StrictEqual_Baseline,48,0 -block_count,StrictEqual_Baseline,49,128 +block_count,StrictEqual_Baseline,49,123 block_count,StrictEqual_Baseline,50,1 block_count,StrictEqual_Baseline,51,0 block_count,StrictEqual_Baseline,52,0 block_count,StrictEqual_Baseline,53,0 block_count,StrictEqual_Baseline,54,0 -block_count,StrictEqual_Baseline,55,126 +block_count,StrictEqual_Baseline,55,122 block_count,StrictEqual_Baseline,56,10 block_count,StrictEqual_Baseline,57,85 -block_count,StrictEqual_Baseline,58,38 -block_count,StrictEqual_Baseline,59,38 -block_count,StrictEqual_Baseline,60,21 +block_count,StrictEqual_Baseline,58,39 +block_count,StrictEqual_Baseline,59,39 +block_count,StrictEqual_Baseline,60,22 block_count,StrictEqual_Baseline,61,3 block_count,StrictEqual_Baseline,62,2 block_count,StrictEqual_Baseline,63,2 @@ -32387,7 +32403,7 @@ block_count,StrictEqual_Baseline,65,1 block_count,StrictEqual_Baseline,66,1 block_count,StrictEqual_Baseline,67,0 -block_count,StrictEqual_Baseline,68,17 +block_count,StrictEqual_Baseline,68,18 block_count,StrictEqual_Baseline,69,17 block_count,StrictEqual_Baseline,70,0 block_count,StrictEqual_Baseline,71,16 @@ -32395,14 +32411,14 @@ block_count,StrictEqual_Baseline,73,0 block_count,StrictEqual_Baseline,74,0 block_count,StrictEqual_Baseline,75,0 -block_count,StrictEqual_Baseline,76,46 -block_count,StrictEqual_Baseline,77,269 +block_count,StrictEqual_Baseline,76,45 +block_count,StrictEqual_Baseline,77,266 block_count,StrictEqual_Baseline,78,85 -block_count,StrictEqual_Baseline,79,502 +block_count,StrictEqual_Baseline,79,497 block_count,StrictEqual_Baseline,80,0 -block_count,StrictEqual_Baseline,81,502 -block_count,LessThan_Baseline,0,487 -block_count,LessThan_Baseline,1,488 +block_count,StrictEqual_Baseline,81,497 +block_count,LessThan_Baseline,0,478 +block_count,LessThan_Baseline,1,478 block_count,LessThan_Baseline,2,40 block_count,LessThan_Baseline,3,9 block_count,LessThan_Baseline,4,0 @@ -32491,7 +32507,7 @@ block_count,LessThan_Baseline,87,0 block_count,LessThan_Baseline,88,0 block_count,LessThan_Baseline,89,30 -block_count,LessThan_Baseline,90,448 +block_count,LessThan_Baseline,90,438 block_count,LessThan_Baseline,91,1 block_count,LessThan_Baseline,92,0 block_count,LessThan_Baseline,93,0 @@ -32503,25 +32519,25 @@ block_count,LessThan_Baseline,99,0 block_count,LessThan_Baseline,100,0 block_count,LessThan_Baseline,101,1 -block_count,LessThan_Baseline,102,446 -block_count,LessThan_Baseline,103,121 -block_count,LessThan_Baseline,104,324 +block_count,LessThan_Baseline,102,437 +block_count,LessThan_Baseline,103,115 +block_count,LessThan_Baseline,104,321 block_count,LessThan_Baseline,105,0 block_count,LessThan_Baseline,106,0 block_count,LessThan_Baseline,107,0 block_count,LessThan_Baseline,108,0 block_count,LessThan_Baseline,109,0 block_count,LessThan_Baseline,110,40 -block_count,LessThan_Baseline,111,31 +block_count,LessThan_Baseline,111,32 block_count,LessThan_Baseline,112,8 -block_count,LessThan_Baseline,113,153 -block_count,LessThan_Baseline,114,333 -block_count,LessThan_Baseline,115,487 +block_count,LessThan_Baseline,113,147 +block_count,LessThan_Baseline,114,330 +block_count,LessThan_Baseline,115,478 block_count,LessThan_Baseline,116,0 -block_count,LessThan_Baseline,117,487 -block_count,GreaterThan_Baseline,0,166 -block_count,GreaterThan_Baseline,1,167 -block_count,GreaterThan_Baseline,2,14 +block_count,LessThan_Baseline,117,478 +block_count,GreaterThan_Baseline,0,164 +block_count,GreaterThan_Baseline,1,165 +block_count,GreaterThan_Baseline,2,15 block_count,GreaterThan_Baseline,3,9 block_count,GreaterThan_Baseline,4,0 block_count,GreaterThan_Baseline,5,0 @@ -32598,7 +32614,7 @@ block_count,GreaterThan_Baseline,76,0 block_count,GreaterThan_Baseline,77,0 block_count,GreaterThan_Baseline,78,8 -block_count,GreaterThan_Baseline,79,5 +block_count,GreaterThan_Baseline,79,6 block_count,GreaterThan_Baseline,80,0 block_count,GreaterThan_Baseline,81,0 block_count,GreaterThan_Baseline,82,0 @@ -32609,7 +32625,7 @@ block_count,GreaterThan_Baseline,87,0 block_count,GreaterThan_Baseline,88,0 block_count,GreaterThan_Baseline,89,5 -block_count,GreaterThan_Baseline,90,152 +block_count,GreaterThan_Baseline,90,150 block_count,GreaterThan_Baseline,91,0 block_count,GreaterThan_Baseline,92,0 block_count,GreaterThan_Baseline,93,0 @@ -32621,8 +32637,8 @@ block_count,GreaterThan_Baseline,99,0 block_count,GreaterThan_Baseline,100,0 block_count,GreaterThan_Baseline,101,0 -block_count,GreaterThan_Baseline,102,152 -block_count,GreaterThan_Baseline,103,99 +block_count,GreaterThan_Baseline,102,149 +block_count,GreaterThan_Baseline,103,97 block_count,GreaterThan_Baseline,104,52 block_count,GreaterThan_Baseline,105,0 block_count,GreaterThan_Baseline,106,0 @@ -32632,13 +32648,13 @@ block_count,GreaterThan_Baseline,110,14 block_count,GreaterThan_Baseline,111,7 block_count,GreaterThan_Baseline,112,6 -block_count,GreaterThan_Baseline,113,107 +block_count,GreaterThan_Baseline,113,105 block_count,GreaterThan_Baseline,114,58 -block_count,GreaterThan_Baseline,115,166 +block_count,GreaterThan_Baseline,115,164 block_count,GreaterThan_Baseline,116,0 -block_count,GreaterThan_Baseline,117,166 -block_count,LessThanOrEqual_Baseline,0,65 -block_count,LessThanOrEqual_Baseline,1,65 +block_count,GreaterThan_Baseline,117,164 +block_count,LessThanOrEqual_Baseline,0,62 +block_count,LessThanOrEqual_Baseline,1,62 block_count,LessThanOrEqual_Baseline,2,6 block_count,LessThanOrEqual_Baseline,3,2 block_count,LessThanOrEqual_Baseline,4,0 @@ -32727,7 +32743,7 @@ block_count,LessThanOrEqual_Baseline,87,0 block_count,LessThanOrEqual_Baseline,88,0 block_count,LessThanOrEqual_Baseline,89,3 -block_count,LessThanOrEqual_Baseline,90,59 +block_count,LessThanOrEqual_Baseline,90,56 block_count,LessThanOrEqual_Baseline,91,1 block_count,LessThanOrEqual_Baseline,92,0 block_count,LessThanOrEqual_Baseline,93,0 @@ -32739,9 +32755,9 @@ block_count,LessThanOrEqual_Baseline,99,0 block_count,LessThanOrEqual_Baseline,100,0 block_count,LessThanOrEqual_Baseline,101,1 -block_count,LessThanOrEqual_Baseline,102,58 +block_count,LessThanOrEqual_Baseline,102,54 block_count,LessThanOrEqual_Baseline,103,5 -block_count,LessThanOrEqual_Baseline,104,52 +block_count,LessThanOrEqual_Baseline,104,49 block_count,LessThanOrEqual_Baseline,105,0 block_count,LessThanOrEqual_Baseline,106,0 block_count,LessThanOrEqual_Baseline,107,0 @@ -32751,12 +32767,12 @@ block_count,LessThanOrEqual_Baseline,111,2 block_count,LessThanOrEqual_Baseline,112,4 block_count,LessThanOrEqual_Baseline,113,8 -block_count,LessThanOrEqual_Baseline,114,57 -block_count,LessThanOrEqual_Baseline,115,65 +block_count,LessThanOrEqual_Baseline,114,53 +block_count,LessThanOrEqual_Baseline,115,62 block_count,LessThanOrEqual_Baseline,116,0 -block_count,LessThanOrEqual_Baseline,117,65 -block_count,GreaterThanOrEqual_Baseline,0,121 -block_count,GreaterThanOrEqual_Baseline,1,122 +block_count,LessThanOrEqual_Baseline,117,62 +block_count,GreaterThanOrEqual_Baseline,0,119 +block_count,GreaterThanOrEqual_Baseline,1,120 block_count,GreaterThanOrEqual_Baseline,2,14 block_count,GreaterThanOrEqual_Baseline,3,10 block_count,GreaterThanOrEqual_Baseline,4,0 @@ -32834,7 +32850,7 @@ block_count,GreaterThanOrEqual_Baseline,76,0 block_count,GreaterThanOrEqual_Baseline,77,0 block_count,GreaterThanOrEqual_Baseline,78,9 -block_count,GreaterThanOrEqual_Baseline,79,3 +block_count,GreaterThanOrEqual_Baseline,79,4 block_count,GreaterThanOrEqual_Baseline,80,0 block_count,GreaterThanOrEqual_Baseline,81,0 block_count,GreaterThanOrEqual_Baseline,82,0 @@ -32844,8 +32860,8 @@ block_count,GreaterThanOrEqual_Baseline,86,0 block_count,GreaterThanOrEqual_Baseline,87,0 block_count,GreaterThanOrEqual_Baseline,88,0 -block_count,GreaterThanOrEqual_Baseline,89,3 -block_count,GreaterThanOrEqual_Baseline,90,107 +block_count,GreaterThanOrEqual_Baseline,89,4 +block_count,GreaterThanOrEqual_Baseline,90,105 block_count,GreaterThanOrEqual_Baseline,91,0 block_count,GreaterThanOrEqual_Baseline,92,0 block_count,GreaterThanOrEqual_Baseline,93,0 @@ -32857,9 +32873,9 @@ block_count,GreaterThanOrEqual_Baseline,99,0 block_count,GreaterThanOrEqual_Baseline,100,0 block_count,GreaterThanOrEqual_Baseline,101,0 -block_count,GreaterThanOrEqual_Baseline,102,107 +block_count,GreaterThanOrEqual_Baseline,102,105 block_count,GreaterThanOrEqual_Baseline,103,62 -block_count,GreaterThanOrEqual_Baseline,104,44 +block_count,GreaterThanOrEqual_Baseline,104,42 block_count,GreaterThanOrEqual_Baseline,105,0 block_count,GreaterThanOrEqual_Baseline,106,0 block_count,GreaterThanOrEqual_Baseline,107,0 @@ -32869,10 +32885,10 @@ block_count,GreaterThanOrEqual_Baseline,111,6 block_count,GreaterThanOrEqual_Baseline,112,7 block_count,GreaterThanOrEqual_Baseline,113,69 -block_count,GreaterThanOrEqual_Baseline,114,51 -block_count,GreaterThanOrEqual_Baseline,115,121 +block_count,GreaterThanOrEqual_Baseline,114,50 +block_count,GreaterThanOrEqual_Baseline,115,119 block_count,GreaterThanOrEqual_Baseline,116,0 -block_count,GreaterThanOrEqual_Baseline,117,121 +block_count,GreaterThanOrEqual_Baseline,117,119 block_count,BitwiseNot_Baseline,0,6 block_count,BitwiseNot_Baseline,1,5 block_count,BitwiseNot_Baseline,2,0 @@ -32908,8 +32924,8 @@ block_count,BitwiseNot_Baseline,32,0 block_count,BitwiseNot_Baseline,33,6 block_count,BitwiseNot_Baseline,34,6 -block_count,Decrement_Baseline,0,51 -block_count,Decrement_Baseline,1,51 +block_count,Decrement_Baseline,0,54 +block_count,Decrement_Baseline,1,54 block_count,Decrement_Baseline,2,0 block_count,Decrement_Baseline,3,0 block_count,Decrement_Baseline,4,0 @@ -32924,18 +32940,18 @@ block_count,Decrement_Baseline,13,0 block_count,Decrement_Baseline,14,0 block_count,Decrement_Baseline,15,0 -block_count,Decrement_Baseline,16,51 -block_count,Decrement_Baseline,17,51 +block_count,Decrement_Baseline,16,53 +block_count,Decrement_Baseline,17,53 block_count,Decrement_Baseline,18,0 block_count,Decrement_Baseline,19,0 block_count,Decrement_Baseline,20,0 block_count,Decrement_Baseline,21,0 block_count,Decrement_Baseline,22,0 -block_count,Decrement_Baseline,23,51 +block_count,Decrement_Baseline,23,54 block_count,Decrement_Baseline,24,0 -block_count,Decrement_Baseline,25,51 -block_count,Increment_Baseline,0,324 -block_count,Increment_Baseline,1,324 +block_count,Decrement_Baseline,25,54 +block_count,Increment_Baseline,0,322 +block_count,Increment_Baseline,1,322 block_count,Increment_Baseline,2,0 block_count,Increment_Baseline,3,0 block_count,Increment_Baseline,4,0 @@ -32950,16 +32966,16 @@ block_count,Increment_Baseline,13,0 block_count,Increment_Baseline,14,0 block_count,Increment_Baseline,15,0 -block_count,Increment_Baseline,16,324 -block_count,Increment_Baseline,17,324 +block_count,Increment_Baseline,16,322 +block_count,Increment_Baseline,17,322 block_count,Increment_Baseline,18,0 block_count,Increment_Baseline,19,0 block_count,Increment_Baseline,20,0 block_count,Increment_Baseline,21,0 block_count,Increment_Baseline,22,0 -block_count,Increment_Baseline,23,324 +block_count,Increment_Baseline,23,322 block_count,Increment_Baseline,24,0 -block_count,Increment_Baseline,25,324 +block_count,Increment_Baseline,25,322 block_count,Negate_Baseline,0,13 block_count,Negate_Baseline,1,13 block_count,Negate_Baseline,2,11 @@ -34198,8 +34214,8 @@ block_count,InstanceOf,34,0 block_count,InstanceOf,35,0 block_count,InstanceOf,36,11 -block_count,InstanceOf_Baseline,0,76 -block_count,InstanceOf_Baseline,1,76 +block_count,InstanceOf_Baseline,0,77 +block_count,InstanceOf_Baseline,1,77 block_count,InstanceOf_Baseline,2,2 block_count,InstanceOf_Baseline,3,0 block_count,InstanceOf_Baseline,4,0 @@ -34218,14 +34234,14 @@ block_count,InstanceOf_Baseline,17,0 block_count,InstanceOf_Baseline,18,0 block_count,InstanceOf_Baseline,19,2 -block_count,InstanceOf_Baseline,20,73 +block_count,InstanceOf_Baseline,20,75 block_count,InstanceOf_Baseline,21,0 -block_count,InstanceOf_Baseline,22,76 -block_count,InstanceOf_Baseline,23,76 +block_count,InstanceOf_Baseline,22,77 +block_count,InstanceOf_Baseline,23,77 block_count,InstanceOf_Baseline,24,0 -block_count,InstanceOf_Baseline,25,76 +block_count,InstanceOf_Baseline,25,77 block_count,InstanceOf_Baseline,26,0 -block_count,InstanceOf_Baseline,27,76 +block_count,InstanceOf_Baseline,27,77 block_count,InstanceOf_Baseline,28,0 block_count,InstanceOf_Baseline,29,0 block_count,InstanceOf_Baseline,30,0 @@ -34256,7 +34272,7 @@ block_count,InstanceOf_Baseline,55,0 block_count,InstanceOf_Baseline,56,0 block_count,InstanceOf_Baseline,57,0 -block_count,InstanceOf_Baseline,58,76 +block_count,InstanceOf_Baseline,58,77 block_count,InstanceOf_Baseline,59,0 block_count,InstanceOf_Baseline,60,0 block_count,ForInEnumerate,0,59 @@ -35025,9 +35041,9 @@ block_count,SetConstructor,89,0 block_count,SetConstructor,90,0 block_count,SetConstructor,91,115 -block_count,SetConstructor,92,115 +block_count,SetConstructor,92,114 block_count,SetConstructor,93,0 -block_count,SetConstructor,94,115 +block_count,SetConstructor,94,114 block_count,SetConstructor,95,0 block_count,SetConstructor,96,0 block_count,SetConstructor,97,115 @@ -36118,16 +36134,16 @@ block_count,TypedArrayPrototypeByteLength,10,0 block_count,TypedArrayPrototypeByteLength,11,0 block_count,TypedArrayPrototypeByteLength,12,0 -block_count,TypedArrayPrototypeLength,0,13 +block_count,TypedArrayPrototypeLength,0,14 block_count,TypedArrayPrototypeLength,1,0 -block_count,TypedArrayPrototypeLength,2,13 -block_count,TypedArrayPrototypeLength,3,13 -block_count,TypedArrayPrototypeLength,4,13 +block_count,TypedArrayPrototypeLength,2,14 +block_count,TypedArrayPrototypeLength,3,14 +block_count,TypedArrayPrototypeLength,4,14 block_count,TypedArrayPrototypeLength,5,0 -block_count,TypedArrayPrototypeLength,6,13 -block_count,TypedArrayPrototypeLength,7,13 -block_count,TypedArrayPrototypeLength,8,13 -block_count,TypedArrayPrototypeLength,9,13 +block_count,TypedArrayPrototypeLength,6,14 +block_count,TypedArrayPrototypeLength,7,14 +block_count,TypedArrayPrototypeLength,8,14 +block_count,TypedArrayPrototypeLength,9,14 block_count,TypedArrayPrototypeLength,10,0 block_count,TypedArrayPrototypeLength,11,0 block_count,TypedArrayPrototypeLength,12,0 @@ -36163,8 +36179,8 @@ block_count,TypedArrayPrototypeLength,42,0 block_count,TypedArrayPrototypeLength,43,0 block_count,TypedArrayPrototypeLength,44,0 -block_count,TypedArrayPrototypeLength,45,13 -block_count,TypedArrayPrototypeLength,46,13 +block_count,TypedArrayPrototypeLength,45,14 +block_count,TypedArrayPrototypeLength,46,14 block_count,TypedArrayPrototypeToStringTag,0,0 block_count,TypedArrayPrototypeToStringTag,1,0 block_count,TypedArrayPrototypeToStringTag,2,0 @@ -36969,7 +36985,7 @@ block_count,WeakMapLookupHashIndex,30,0 block_count,WeakMapLookupHashIndex,31,74 block_count,WeakMapLookupHashIndex,32,74 -block_count,WeakMapLookupHashIndex,33,111 +block_count,WeakMapLookupHashIndex,33,112 block_count,WeakMapLookupHashIndex,34,111 block_count,WeakMapLookupHashIndex,35,37 block_count,WeakMapLookupHashIndex,36,73 @@ -37512,26 +37528,26 @@ block_count,AsyncGeneratorYieldWithAwaitResolveClosure,3,8 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,4,0 block_count,AsyncGeneratorYieldWithAwaitResolveClosure,5,8 -block_count,StringAdd_CheckNone,0,8654 -block_count,StringAdd_CheckNone,1,8229 -block_count,StringAdd_CheckNone,2,8181 -block_count,StringAdd_CheckNone,3,8181 -block_count,StringAdd_CheckNone,4,6457 -block_count,StringAdd_CheckNone,5,6429 +block_count,StringAdd_CheckNone,0,8652 +block_count,StringAdd_CheckNone,1,8227 +block_count,StringAdd_CheckNone,2,8179 +block_count,StringAdd_CheckNone,3,8179 +block_count,StringAdd_CheckNone,4,6456 +block_count,StringAdd_CheckNone,5,6427 block_count,StringAdd_CheckNone,6,28 -block_count,StringAdd_CheckNone,7,6457 -block_count,StringAdd_CheckNone,8,6456 +block_count,StringAdd_CheckNone,7,6456 +block_count,StringAdd_CheckNone,8,6455 block_count,StringAdd_CheckNone,9,0 -block_count,StringAdd_CheckNone,10,6457 +block_count,StringAdd_CheckNone,10,6456 block_count,StringAdd_CheckNone,11,2 -block_count,StringAdd_CheckNone,12,6454 -block_count,StringAdd_CheckNone,13,6457 +block_count,StringAdd_CheckNone,12,6453 +block_count,StringAdd_CheckNone,13,6456 block_count,StringAdd_CheckNone,14,0 -block_count,StringAdd_CheckNone,15,6456 -block_count,StringAdd_CheckNone,16,6457 +block_count,StringAdd_CheckNone,15,6455 +block_count,StringAdd_CheckNone,16,6456 block_count,StringAdd_CheckNone,17,1723 -block_count,StringAdd_CheckNone,18,1725 -block_count,StringAdd_CheckNone,19,1724 +block_count,StringAdd_CheckNone,18,1724 +block_count,StringAdd_CheckNone,19,1723 block_count,StringAdd_CheckNone,20,1 block_count,StringAdd_CheckNone,21,1 block_count,StringAdd_CheckNone,22,0 @@ -37567,10 +37583,10 @@ block_count,StringAdd_CheckNone,52,1713 block_count,StringAdd_CheckNone,53,0 block_count,StringAdd_CheckNone,54,1713 -block_count,StringAdd_CheckNone,55,841 +block_count,StringAdd_CheckNone,55,840 block_count,StringAdd_CheckNone,56,872 -block_count,StringAdd_CheckNone,57,2011 -block_count,StringAdd_CheckNone,58,1138 +block_count,StringAdd_CheckNone,57,2009 +block_count,StringAdd_CheckNone,58,1137 block_count,StringAdd_CheckNone,59,872 block_count,StringAdd_CheckNone,60,1713 block_count,StringAdd_CheckNone,61,359 @@ -37578,14 +37594,14 @@ block_count,StringAdd_CheckNone,63,1713 block_count,StringAdd_CheckNone,64,0 block_count,StringAdd_CheckNone,65,1713 -block_count,StringAdd_CheckNone,66,1025 +block_count,StringAdd_CheckNone,66,1024 block_count,StringAdd_CheckNone,67,688 block_count,StringAdd_CheckNone,68,1318 -block_count,StringAdd_CheckNone,69,630 +block_count,StringAdd_CheckNone,69,629 block_count,StringAdd_CheckNone,70,688 block_count,StringAdd_CheckNone,71,1713 block_count,StringAdd_CheckNone,72,364 -block_count,StringAdd_CheckNone,73,1349 +block_count,StringAdd_CheckNone,73,1348 block_count,StringAdd_CheckNone,74,1713 block_count,StringAdd_CheckNone,75,0 block_count,StringAdd_CheckNone,76,9 @@ -37635,7 +37651,7 @@ block_count,SubString,6,65 block_count,SubString,7,65 block_count,SubString,8,0 -block_count,SubString,9,124 +block_count,SubString,9,123 block_count,SubString,10,7 block_count,SubString,11,197 block_count,SubString,12,0 @@ -37851,17 +37867,17 @@ block_count,SubString,222,113 block_count,SubString,223,231 block_count,SubString,224,231 -block_count,GetProperty,0,765 -block_count,GetProperty,1,765 +block_count,GetProperty,0,767 +block_count,GetProperty,1,767 block_count,GetProperty,2,0 -block_count,GetProperty,3,765 -block_count,GetProperty,4,760 -block_count,GetProperty,5,760 -block_count,GetProperty,6,760 +block_count,GetProperty,3,766 +block_count,GetProperty,4,762 +block_count,GetProperty,5,762 +block_count,GetProperty,6,762 block_count,GetProperty,7,0 block_count,GetProperty,8,0 block_count,GetProperty,9,0 -block_count,GetProperty,10,760 +block_count,GetProperty,10,762 block_count,GetProperty,11,627 block_count,GetProperty,12,0 block_count,GetProperty,13,0 @@ -37880,12 +37896,12 @@ block_count,GetProperty,26,0 block_count,GetProperty,27,0 block_count,GetProperty,28,0 -block_count,GetProperty,29,132 -block_count,GetProperty,30,760 -block_count,GetProperty,31,1887 -block_count,GetProperty,32,1887 -block_count,GetProperty,33,1886 -block_count,GetProperty,34,1863 +block_count,GetProperty,29,134 +block_count,GetProperty,30,762 +block_count,GetProperty,31,1890 +block_count,GetProperty,32,1890 +block_count,GetProperty,33,1889 +block_count,GetProperty,34,1867 block_count,GetProperty,35,313 block_count,GetProperty,36,313 block_count,GetProperty,37,0 @@ -37909,31 +37925,31 @@ block_count,GetProperty,55,252 block_count,GetProperty,56,0 block_count,GetProperty,57,252 -block_count,GetProperty,58,61 +block_count,GetProperty,58,60 block_count,GetProperty,59,0 -block_count,GetProperty,60,1550 +block_count,GetProperty,60,1553 block_count,GetProperty,61,0 -block_count,GetProperty,62,1550 +block_count,GetProperty,62,1553 block_count,GetProperty,63,326 -block_count,GetProperty,64,1223 -block_count,GetProperty,65,3059 -block_count,GetProperty,66,2692 -block_count,GetProperty,67,2570 -block_count,GetProperty,68,1835 -block_count,GetProperty,69,734 +block_count,GetProperty,64,1226 +block_count,GetProperty,65,3069 +block_count,GetProperty,66,2701 +block_count,GetProperty,67,2579 +block_count,GetProperty,68,1842 +block_count,GetProperty,69,736 block_count,GetProperty,70,122 -block_count,GetProperty,71,366 -block_count,GetProperty,72,1061 -block_count,GetProperty,73,474 -block_count,GetProperty,74,587 -block_count,GetProperty,75,577 +block_count,GetProperty,71,367 +block_count,GetProperty,72,1063 +block_count,GetProperty,73,475 +block_count,GetProperty,74,588 +block_count,GetProperty,75,578 block_count,GetProperty,76,9 -block_count,GetProperty,77,750 +block_count,GetProperty,77,752 block_count,GetProperty,78,2 -block_count,GetProperty,79,748 -block_count,GetProperty,80,735 +block_count,GetProperty,79,750 +block_count,GetProperty,80,736 block_count,GetProperty,81,0 -block_count,GetProperty,82,735 +block_count,GetProperty,82,736 block_count,GetProperty,83,13 block_count,GetProperty,84,0 block_count,GetProperty,85,13 @@ -37941,7 +37957,7 @@ block_count,GetProperty,87,0 block_count,GetProperty,88,0 block_count,GetProperty,89,0 -block_count,GetProperty,90,750 +block_count,GetProperty,90,752 block_count,GetProperty,91,22 block_count,GetProperty,92,0 block_count,GetProperty,93,0 @@ -37984,8 +38000,8 @@ block_count,GetProperty,130,0 block_count,GetProperty,131,0 block_count,GetProperty,132,0 -block_count,GetProperty,133,1136 -block_count,GetProperty,134,1135 +block_count,GetProperty,133,1138 +block_count,GetProperty,134,1137 block_count,GetProperty,135,1 block_count,GetProperty,136,0 block_count,GetProperty,137,1 @@ -38023,10 +38039,10 @@ block_count,GetProperty,169,0 block_count,GetProperty,170,0 block_count,GetProperty,171,0 -block_count,GetProperty,172,1136 -block_count,GetProperty,173,1127 +block_count,GetProperty,172,1138 +block_count,GetProperty,173,1128 block_count,GetProperty,174,9 -block_count,GetProperty,175,750 +block_count,GetProperty,175,752 block_count,GetProperty,176,2 block_count,GetProperty,177,2 block_count,GetProperty,178,0 @@ -38066,7 +38082,7 @@ block_count,GetProperty,212,0 block_count,GetProperty,213,0 block_count,GetProperty,214,0 -block_count,GetProperty,215,748 +block_count,GetProperty,215,750 block_count,GetProperty,216,0 block_count,GetProperty,217,4 block_count,GetProperty,218,0 @@ -40473,9 +40489,9 @@ block_count,CreateDataProperty,970,0 block_count,GetOwnPropertyDescriptor,0,0 block_count,GetOwnPropertyDescriptor,1,0 -block_count,FindNonDefaultConstructorOrConstruct,0,16 -block_count,FindNonDefaultConstructorOrConstruct,1,16 -block_count,FindNonDefaultConstructorOrConstruct,2,16 +block_count,FindNonDefaultConstructorOrConstruct,0,17 +block_count,FindNonDefaultConstructorOrConstruct,1,17 +block_count,FindNonDefaultConstructorOrConstruct,2,17 block_count,FindNonDefaultConstructorOrConstruct,3,20 block_count,FindNonDefaultConstructorOrConstruct,4,20 block_count,FindNonDefaultConstructorOrConstruct,5,20 @@ -41244,6 +41260,326 @@ block_count,ArrayForEachLoopContinuation,6,0 block_count,ArrayForEachLoopContinuation,7,0 block_count,ArrayForEachLoopContinuation,8,0 +block_count,ArrayForEachLoopContinuation,9,0 +block_count,ArrayForEachLoopContinuation,10,0 +block_count,ArrayForEachLoopContinuation,11,0 +block_count,ArrayForEachLoopContinuation,12,0 +block_count,ArrayForEachLoopContinuation,13,0 +block_count,ArrayForEachLoopContinuation,14,0 +block_count,ArrayForEachLoopContinuation,15,0 +block_count,ArrayForEachLoopContinuation,16,0 +block_count,ArrayForEachLoopContinuation,17,0 +block_count,ArrayForEachLoopContinuation,18,0 +block_count,ArrayForEachLoopContinuation,19,0 +block_count,ArrayForEachLoopContinuation,20,0 +block_count,ArrayForEachLoopContinuation,21,0 +block_count,ArrayForEachLoopContinuation,22,0 +block_count,ArrayForEachLoopContinuation,23,0 +block_count,ArrayForEachLoopContinuation,24,0 +block_count,ArrayForEachLoopContinuation,25,0 +block_count,ArrayForEachLoopContinuation,26,0 +block_count,ArrayForEachLoopContinuation,27,0 +block_count,ArrayForEachLoopContinuation,28,0 +block_count,ArrayForEachLoopContinuation,29,0 +block_count,ArrayForEachLoopContinuation,30,0 +block_count,ArrayForEachLoopContinuation,31,0 +block_count,ArrayForEachLoopContinuation,32,0 +block_count,ArrayForEachLoopContinuation,33,0 +block_count,ArrayForEachLoopContinuation,34,0 +block_count,ArrayForEachLoopContinuation,35,0 +block_count,ArrayForEachLoopContinuation,36,0 +block_count,ArrayForEachLoopContinuation,37,0 +block_count,ArrayForEachLoopContinuation,38,0 +block_count,ArrayForEachLoopContinuation,39,0 +block_count,ArrayForEachLoopContinuation,40,0 +block_count,ArrayForEachLoopContinuation,41,0 +block_count,ArrayForEachLoopContinuation,42,0 +block_count,ArrayForEachLoopContinuation,43,0 +block_count,ArrayForEachLoopContinuation,44,0 +block_count,ArrayForEachLoopContinuation,45,0 +block_count,ArrayForEachLoopContinuation,46,0 +block_count,ArrayForEachLoopContinuation,47,0 +block_count,ArrayForEachLoopContinuation,48,0 +block_count,ArrayForEachLoopContinuation,49,0 +block_count,ArrayForEachLoopContinuation,50,0 +block_count,ArrayForEachLoopContinuation,51,0 +block_count,ArrayForEachLoopContinuation,52,0 +block_count,ArrayForEachLoopContinuation,53,0 +block_count,ArrayForEachLoopContinuation,54,0 +block_count,ArrayForEachLoopContinuation,55,0 +block_count,ArrayForEachLoopContinuation,56,0 +block_count,ArrayForEachLoopContinuation,57,0 +block_count,ArrayForEachLoopContinuation,58,0 +block_count,ArrayForEachLoopContinuation,59,0 +block_count,ArrayForEachLoopContinuation,60,0 +block_count,ArrayForEachLoopContinuation,61,0 +block_count,ArrayForEachLoopContinuation,62,0 +block_count,ArrayForEachLoopContinuation,63,0 +block_count,ArrayForEachLoopContinuation,64,0 +block_count,ArrayForEachLoopContinuation,65,0 +block_count,ArrayForEachLoopContinuation,66,0 +block_count,ArrayForEachLoopContinuation,67,0 +block_count,ArrayForEachLoopContinuation,68,0 +block_count,ArrayForEachLoopContinuation,69,0 +block_count,ArrayForEachLoopContinuation,70,0 +block_count,ArrayForEachLoopContinuation,71,0 +block_count,ArrayForEachLoopContinuation,72,0 +block_count,ArrayForEachLoopContinuation,73,0 +block_count,ArrayForEachLoopContinuation,74,0 +block_count,ArrayForEachLoopContinuation,75,0 +block_count,ArrayForEachLoopContinuation,76,0 +block_count,ArrayForEachLoopContinuation,77,0 +block_count,ArrayForEachLoopContinuation,78,0 +block_count,ArrayForEachLoopContinuation,79,0 +block_count,ArrayForEachLoopContinuation,80,0 +block_count,ArrayForEachLoopContinuation,81,0 +block_count,ArrayForEachLoopContinuation,82,0 +block_count,ArrayForEachLoopContinuation,83,0 +block_count,ArrayForEachLoopContinuation,84,0 +block_count,ArrayForEachLoopContinuation,85,0 +block_count,ArrayForEachLoopContinuation,86,0 +block_count,ArrayForEachLoopContinuation,87,0 +block_count,ArrayForEachLoopContinuation,88,0 +block_count,ArrayForEachLoopContinuation,89,0 +block_count,ArrayForEachLoopContinuation,90,0 +block_count,ArrayForEachLoopContinuation,91,0 +block_count,ArrayForEachLoopContinuation,92,0 +block_count,ArrayForEachLoopContinuation,93,0 +block_count,ArrayForEachLoopContinuation,94,0 +block_count,ArrayForEachLoopContinuation,95,0 +block_count,ArrayForEachLoopContinuation,96,0 +block_count,ArrayForEachLoopContinuation,97,0 +block_count,ArrayForEachLoopContinuation,98,0 +block_count,ArrayForEachLoopContinuation,99,0 +block_count,ArrayForEachLoopContinuation,100,0 +block_count,ArrayForEachLoopContinuation,101,0 +block_count,ArrayForEachLoopContinuation,102,0 +block_count,ArrayForEachLoopContinuation,103,0 +block_count,ArrayForEachLoopContinuation,104,0 +block_count,ArrayForEachLoopContinuation,105,0 +block_count,ArrayForEachLoopContinuation,106,0 +block_count,ArrayForEachLoopContinuation,107,0 +block_count,ArrayForEachLoopContinuation,108,0 +block_count,ArrayForEachLoopContinuation,109,0 +block_count,ArrayForEachLoopContinuation,110,0 +block_count,ArrayForEachLoopContinuation,111,0 +block_count,ArrayForEachLoopContinuation,112,0 +block_count,ArrayForEachLoopContinuation,113,0 +block_count,ArrayForEachLoopContinuation,114,0 +block_count,ArrayForEachLoopContinuation,115,0 +block_count,ArrayForEachLoopContinuation,116,0 +block_count,ArrayForEachLoopContinuation,117,0 +block_count,ArrayForEachLoopContinuation,118,0 +block_count,ArrayForEachLoopContinuation,119,0 +block_count,ArrayForEachLoopContinuation,120,0 +block_count,ArrayForEachLoopContinuation,121,0 +block_count,ArrayForEachLoopContinuation,122,0 +block_count,ArrayForEachLoopContinuation,123,0 +block_count,ArrayForEachLoopContinuation,124,0 +block_count,ArrayForEachLoopContinuation,125,0 +block_count,ArrayForEachLoopContinuation,126,0 +block_count,ArrayForEachLoopContinuation,127,0 +block_count,ArrayForEachLoopContinuation,128,0 +block_count,ArrayForEachLoopContinuation,129,0 +block_count,ArrayForEachLoopContinuation,130,0 +block_count,ArrayForEachLoopContinuation,131,0 +block_count,ArrayForEachLoopContinuation,132,0 +block_count,ArrayForEachLoopContinuation,133,0 +block_count,ArrayForEachLoopContinuation,134,0 +block_count,ArrayForEachLoopContinuation,135,0 +block_count,ArrayForEachLoopContinuation,136,0 +block_count,ArrayForEachLoopContinuation,137,0 +block_count,ArrayForEachLoopContinuation,138,0 +block_count,ArrayForEachLoopContinuation,139,0 +block_count,ArrayForEachLoopContinuation,140,0 +block_count,ArrayForEachLoopContinuation,141,0 +block_count,ArrayForEachLoopContinuation,142,0 +block_count,ArrayForEachLoopContinuation,143,0 +block_count,ArrayForEachLoopContinuation,144,0 +block_count,ArrayForEachLoopContinuation,145,0 +block_count,ArrayForEachLoopContinuation,146,0 +block_count,ArrayForEachLoopContinuation,147,0 +block_count,ArrayForEachLoopContinuation,148,0 +block_count,ArrayForEachLoopContinuation,149,0 +block_count,ArrayForEachLoopContinuation,150,0 +block_count,ArrayForEachLoopContinuation,151,0 +block_count,ArrayForEachLoopContinuation,152,0 +block_count,ArrayForEachLoopContinuation,153,0 +block_count,ArrayForEachLoopContinuation,154,0 +block_count,ArrayForEachLoopContinuation,155,0 +block_count,ArrayForEachLoopContinuation,156,0 +block_count,ArrayForEachLoopContinuation,157,0 +block_count,ArrayForEachLoopContinuation,158,0 +block_count,ArrayForEachLoopContinuation,159,0 +block_count,ArrayForEachLoopContinuation,160,0 +block_count,ArrayForEachLoopContinuation,161,0 +block_count,ArrayForEachLoopContinuation,162,0 +block_count,ArrayForEachLoopContinuation,163,0 +block_count,ArrayForEachLoopContinuation,164,0 +block_count,ArrayForEachLoopContinuation,165,0 +block_count,ArrayForEachLoopContinuation,166,0 +block_count,ArrayForEachLoopContinuation,167,0 +block_count,ArrayForEachLoopContinuation,168,0 +block_count,ArrayForEachLoopContinuation,169,0 +block_count,ArrayForEachLoopContinuation,170,0 +block_count,ArrayForEachLoopContinuation,171,0 +block_count,ArrayForEachLoopContinuation,172,0 +block_count,ArrayForEachLoopContinuation,173,0 +block_count,ArrayForEachLoopContinuation,174,0 +block_count,ArrayForEachLoopContinuation,175,0 +block_count,ArrayForEachLoopContinuation,176,0 +block_count,ArrayForEachLoopContinuation,177,0 +block_count,ArrayForEachLoopContinuation,178,0 +block_count,ArrayForEachLoopContinuation,179,0 +block_count,ArrayForEachLoopContinuation,180,0 +block_count,ArrayForEachLoopContinuation,181,0 +block_count,ArrayForEachLoopContinuation,182,0 +block_count,ArrayForEachLoopContinuation,183,0 +block_count,ArrayForEachLoopContinuation,184,0 +block_count,ArrayForEachLoopContinuation,185,0 +block_count,ArrayForEachLoopContinuation,186,0 +block_count,ArrayForEachLoopContinuation,187,0 +block_count,ArrayForEachLoopContinuation,188,0 +block_count,ArrayForEachLoopContinuation,189,0 +block_count,ArrayForEachLoopContinuation,190,0 +block_count,ArrayForEachLoopContinuation,191,0 +block_count,ArrayForEachLoopContinuation,192,0 +block_count,ArrayForEachLoopContinuation,193,0 +block_count,ArrayForEachLoopContinuation,194,0 +block_count,ArrayForEachLoopContinuation,195,0 +block_count,ArrayForEachLoopContinuation,196,0 +block_count,ArrayForEachLoopContinuation,197,0 +block_count,ArrayForEachLoopContinuation,198,0 +block_count,ArrayForEachLoopContinuation,199,0 +block_count,ArrayForEachLoopContinuation,200,0 +block_count,ArrayForEachLoopContinuation,201,0 +block_count,ArrayForEachLoopContinuation,202,0 +block_count,ArrayForEachLoopContinuation,203,0 +block_count,ArrayForEachLoopContinuation,204,0 +block_count,ArrayForEachLoopContinuation,205,0 +block_count,ArrayForEachLoopContinuation,206,0 +block_count,ArrayForEachLoopContinuation,207,0 +block_count,ArrayForEachLoopContinuation,208,0 +block_count,ArrayForEachLoopContinuation,209,0 +block_count,ArrayForEachLoopContinuation,210,0 +block_count,ArrayForEachLoopContinuation,211,0 +block_count,ArrayForEachLoopContinuation,212,0 +block_count,ArrayForEachLoopContinuation,213,0 +block_count,ArrayForEachLoopContinuation,214,0 +block_count,ArrayForEachLoopContinuation,215,0 +block_count,ArrayForEachLoopContinuation,216,0 +block_count,ArrayForEachLoopContinuation,217,0 +block_count,ArrayForEachLoopContinuation,218,0 +block_count,ArrayForEachLoopContinuation,219,0 +block_count,ArrayForEachLoopContinuation,220,0 +block_count,ArrayForEachLoopContinuation,221,0 +block_count,ArrayForEachLoopContinuation,222,0 +block_count,ArrayForEachLoopContinuation,223,0 +block_count,ArrayForEachLoopContinuation,224,0 +block_count,ArrayForEachLoopContinuation,225,0 +block_count,ArrayForEachLoopContinuation,226,0 +block_count,ArrayForEachLoopContinuation,227,0 +block_count,ArrayForEachLoopContinuation,228,0 +block_count,ArrayForEachLoopContinuation,229,0 +block_count,ArrayForEachLoopContinuation,230,0 +block_count,ArrayForEachLoopContinuation,231,0 +block_count,ArrayForEachLoopContinuation,232,0 +block_count,ArrayForEachLoopContinuation,233,0 +block_count,ArrayForEachLoopContinuation,234,0 +block_count,ArrayForEachLoopContinuation,235,0 +block_count,ArrayForEachLoopContinuation,236,0 +block_count,ArrayForEachLoopContinuation,237,0 +block_count,ArrayForEachLoopContinuation,238,0 +block_count,ArrayForEachLoopContinuation,239,0 +block_count,ArrayForEachLoopContinuation,240,0 +block_count,ArrayForEachLoopContinuation,241,0 +block_count,ArrayForEachLoopContinuation,242,0 +block_count,ArrayForEachLoopContinuation,243,0 +block_count,ArrayForEachLoopContinuation,244,0 +block_count,ArrayForEachLoopContinuation,245,0 +block_count,ArrayForEachLoopContinuation,246,0 +block_count,ArrayForEachLoopContinuation,247,0 +block_count,ArrayForEachLoopContinuation,248,0 +block_count,ArrayForEachLoopContinuation,249,0 +block_count,ArrayForEachLoopContinuation,250,0 +block_count,ArrayForEachLoopContinuation,251,0 +block_count,ArrayForEachLoopContinuation,252,0 +block_count,ArrayForEachLoopContinuation,253,0 +block_count,ArrayForEachLoopContinuation,254,0 +block_count,ArrayForEachLoopContinuation,255,0 +block_count,ArrayForEachLoopContinuation,256,0 +block_count,ArrayForEachLoopContinuation,257,0 +block_count,ArrayForEachLoopContinuation,258,0 +block_count,ArrayForEachLoopContinuation,259,0 +block_count,ArrayForEachLoopContinuation,260,0 +block_count,ArrayForEachLoopContinuation,261,0 +block_count,ArrayForEachLoopContinuation,262,0 +block_count,ArrayForEachLoopContinuation,263,0 +block_count,ArrayForEachLoopContinuation,264,0 +block_count,ArrayForEachLoopContinuation,265,0 +block_count,ArrayForEachLoopContinuation,266,0 +block_count,ArrayForEachLoopContinuation,267,0 +block_count,ArrayForEachLoopContinuation,268,0 +block_count,ArrayForEachLoopContinuation,269,0 +block_count,ArrayForEachLoopContinuation,270,0 +block_count,ArrayForEachLoopContinuation,271,0 +block_count,ArrayForEachLoopContinuation,272,0 +block_count,ArrayForEachLoopContinuation,273,0 +block_count,ArrayForEachLoopContinuation,274,0 +block_count,ArrayForEachLoopContinuation,275,0 +block_count,ArrayForEachLoopContinuation,276,0 +block_count,ArrayForEachLoopContinuation,277,0 +block_count,ArrayForEachLoopContinuation,278,0 +block_count,ArrayForEachLoopContinuation,279,0 +block_count,ArrayForEachLoopContinuation,280,0 +block_count,ArrayForEachLoopContinuation,281,0 +block_count,ArrayForEachLoopContinuation,282,0 +block_count,ArrayForEachLoopContinuation,283,0 +block_count,ArrayForEachLoopContinuation,284,0 +block_count,ArrayForEachLoopContinuation,285,0 +block_count,ArrayForEachLoopContinuation,286,0 +block_count,ArrayForEachLoopContinuation,287,0 +block_count,ArrayForEachLoopContinuation,288,0 +block_count,ArrayForEachLoopContinuation,289,0 +block_count,ArrayForEachLoopContinuation,290,0 +block_count,ArrayForEachLoopContinuation,291,0 +block_count,ArrayForEachLoopContinuation,292,0 +block_count,ArrayForEachLoopContinuation,293,0 +block_count,ArrayForEachLoopContinuation,294,0 +block_count,ArrayForEachLoopContinuation,295,0 +block_count,ArrayForEachLoopContinuation,296,0 +block_count,ArrayForEachLoopContinuation,297,0 +block_count,ArrayForEachLoopContinuation,298,0 +block_count,ArrayForEachLoopContinuation,299,0 +block_count,ArrayForEachLoopContinuation,300,0 +block_count,ArrayForEachLoopContinuation,301,0 +block_count,ArrayForEachLoopContinuation,302,0 +block_count,ArrayForEachLoopContinuation,303,0 +block_count,ArrayForEachLoopContinuation,304,0 +block_count,ArrayForEachLoopContinuation,305,0 +block_count,ArrayForEachLoopContinuation,306,0 +block_count,ArrayForEachLoopContinuation,307,0 +block_count,ArrayForEachLoopContinuation,308,0 +block_count,ArrayForEachLoopContinuation,309,0 +block_count,ArrayForEachLoopContinuation,310,0 +block_count,ArrayForEachLoopContinuation,311,0 +block_count,ArrayForEachLoopContinuation,312,0 +block_count,ArrayForEachLoopContinuation,313,0 +block_count,ArrayForEachLoopContinuation,314,0 +block_count,ArrayForEachLoopContinuation,315,0 +block_count,ArrayForEachLoopContinuation,316,0 +block_count,ArrayForEachLoopContinuation,317,0 +block_count,ArrayForEachLoopContinuation,318,0 +block_count,ArrayForEachLoopContinuation,319,0 +block_count,ArrayForEachLoopContinuation,320,0 +block_count,ArrayForEachLoopContinuation,321,0 +block_count,ArrayForEachLoopContinuation,322,0 +block_count,ArrayForEachLoopContinuation,323,0 +block_count,ArrayForEachLoopContinuation,324,0 +block_count,ArrayForEachLoopContinuation,325,0 +block_count,ArrayForEachLoopContinuation,326,0 +block_count,ArrayForEachLoopContinuation,327,0 +block_count,ArrayForEachLoopContinuation,328,0 block_count,ArrayForEach,0,2 block_count,ArrayForEach,1,0 block_count,ArrayForEach,2,2 @@ -41552,7 +41888,7 @@ block_count,LoadJoinElement_FastSmiOrObjectElements_0,0,742 block_count,LoadJoinElement_FastSmiOrObjectElements_0,1,0 block_count,LoadJoinElement_FastSmiOrObjectElements_0,2,742 -block_count,LoadJoinElement_FastSmiOrObjectElements_0,3,741 +block_count,LoadJoinElement_FastSmiOrObjectElements_0,3,740 block_count,LoadJoinElement_FastSmiOrObjectElements_0,4,1 block_count,LoadJoinElement_FastDoubleElements_0,0,103 block_count,LoadJoinElement_FastDoubleElements_0,1,0 @@ -41783,7 +42119,7 @@ block_count,ArrayPrototypeJoin,163,0 block_count,ArrayPrototypeJoin,164,0 block_count,ArrayPrototypeJoin,165,183 -block_count,ArrayPrototypeJoin,166,1029 +block_count,ArrayPrototypeJoin,166,1028 block_count,ArrayPrototypeJoin,167,845 block_count,ArrayPrototypeJoin,168,845 block_count,ArrayPrototypeJoin,169,845 @@ -42095,7 +42431,7 @@ block_count,ArrayPrototypeJoin,475,0 block_count,ArrayPrototypeJoin,476,0 block_count,ArrayPrototypeJoin,477,0 -block_count,ArrayPrototypeJoin,478,310 +block_count,ArrayPrototypeJoin,478,309 block_count,ArrayPrototypeJoin,479,334 block_count,ArrayPrototypeJoin,480,844 block_count,ArrayPrototypeJoin,481,661 @@ -45710,7 +46046,7 @@ block_count,ToString,115,0 block_count,ToString,116,2 block_count,ToString,117,0 -block_count,ToString,118,11 +block_count,ToString,118,10 block_count,ToString,119,11 block_count,ToString,120,11 block_count,ToString,121,0 @@ -45771,21 +46107,21 @@ block_count,StringPrototypeToString,7,19 block_count,StringPrototypeToString,8,0 block_count,StringPrototypeToString,9,19 -block_count,StringPrototypeCharAt,0,123 +block_count,StringPrototypeCharAt,0,124 block_count,StringPrototypeCharAt,1,0 -block_count,StringPrototypeCharAt,2,123 -block_count,StringPrototypeCharAt,3,123 -block_count,StringPrototypeCharAt,4,123 +block_count,StringPrototypeCharAt,2,124 +block_count,StringPrototypeCharAt,3,124 +block_count,StringPrototypeCharAt,4,124 block_count,StringPrototypeCharAt,5,0 block_count,StringPrototypeCharAt,6,0 block_count,StringPrototypeCharAt,7,0 -block_count,StringPrototypeCharAt,8,123 +block_count,StringPrototypeCharAt,8,124 block_count,StringPrototypeCharAt,9,0 -block_count,StringPrototypeCharAt,10,123 -block_count,StringPrototypeCharAt,11,123 +block_count,StringPrototypeCharAt,10,124 +block_count,StringPrototypeCharAt,11,124 block_count,StringPrototypeCharAt,12,0 -block_count,StringPrototypeCharAt,13,123 -block_count,StringPrototypeCharAt,14,123 +block_count,StringPrototypeCharAt,13,124 +block_count,StringPrototypeCharAt,14,124 block_count,StringPrototypeCharAt,15,121 block_count,StringPrototypeCharAt,16,67 block_count,StringPrototypeCharAt,17,135 @@ -45807,7 +46143,7 @@ block_count,StringPrototypeCharAt,33,0 block_count,StringPrototypeCharAt,34,0 block_count,StringPrototypeCharAt,35,0 -block_count,StringPrototypeCharAt,36,53 +block_count,StringPrototypeCharAt,36,54 block_count,StringPrototypeCharAt,37,121 block_count,StringPrototypeCharAt,38,121 block_count,StringPrototypeCharAt,39,14 @@ -45836,7 +46172,7 @@ block_count,StringPrototypeCharCodeAt,14,117 block_count,StringPrototypeCharCodeAt,15,117 block_count,StringPrototypeCharCodeAt,16,27 -block_count,StringPrototypeCharCodeAt,17,54 +block_count,StringPrototypeCharCodeAt,17,55 block_count,StringPrototypeCharCodeAt,18,26 block_count,StringPrototypeCharCodeAt,19,26 block_count,StringPrototypeCharCodeAt,20,0 @@ -45855,7 +46191,7 @@ block_count,StringPrototypeCharCodeAt,33,0 block_count,StringPrototypeCharCodeAt,34,0 block_count,StringPrototypeCharCodeAt,35,0 -block_count,StringPrototypeCharCodeAt,36,89 +block_count,StringPrototypeCharCodeAt,36,90 block_count,StringPrototypeCharCodeAt,37,117 block_count,StringPrototypeCharCodeAt,38,117 block_count,StringPrototypeCharCodeAt,39,18 @@ -46235,14 +46571,14 @@ block_count,StringAddConvertLeft,172,0 block_count,StringAddConvertLeft,173,0 block_count,StringAddConvertLeft,174,0 -block_count,StringAddConvertRight,0,201 +block_count,StringAddConvertRight,0,200 block_count,StringAddConvertRight,1,186 block_count,StringAddConvertRight,2,139 block_count,StringAddConvertRight,3,47 block_count,StringAddConvertRight,4,14 block_count,StringAddConvertRight,5,61 -block_count,StringAddConvertRight,6,201 -block_count,StringAddConvertRight,7,201 +block_count,StringAddConvertRight,6,200 +block_count,StringAddConvertRight,7,200 block_count,StringAddConvertRight,8,186 block_count,StringAddConvertRight,9,186 block_count,StringAddConvertRight,10,0 @@ -46409,7 +46745,7 @@ block_count,StringAddConvertRight,171,0 block_count,StringAddConvertRight,172,14 block_count,StringAddConvertRight,173,0 -block_count,StringAddConvertRight,174,15 +block_count,StringAddConvertRight,174,14 block_count,StringCharAt,0,9 block_count,StringCharAt,1,1 block_count,StringCharAt,2,3 @@ -46442,7 +46778,7 @@ block_count,StringCharAt,29,0 block_count,StringCharAt,30,0 block_count,StringCharAt,31,9 -block_count,FastNewClosureBaseline,0,87 +block_count,FastNewClosureBaseline,0,88 block_count,FastNewFunctionContextFunction,0,93 block_count,FastNewFunctionContextFunction,1,93 block_count,FastNewFunctionContextFunction,2,0 @@ -46461,7 +46797,7 @@ block_count,FastNewFunctionContextFunction,15,67 block_count,FastNewFunctionContextFunction,16,93 block_count,FastNewFunctionContextFunction,17,57 -block_count,FastNewFunctionContextFunction,18,35 +block_count,FastNewFunctionContextFunction,18,36 block_count,CreateRegExpLiteral,0,41 block_count,CreateRegExpLiteral,1,41 block_count,CreateRegExpLiteral,2,0 @@ -46473,21 +46809,21 @@ block_count,CreateRegExpLiteral,8,41 block_count,CreateRegExpLiteral,9,0 block_count,CreateRegExpLiteral,10,0 -block_count,CreateShallowArrayLiteral,0,19 -block_count,CreateShallowArrayLiteral,1,19 +block_count,CreateShallowArrayLiteral,0,20 +block_count,CreateShallowArrayLiteral,1,20 block_count,CreateShallowArrayLiteral,2,0 -block_count,CreateShallowArrayLiteral,3,19 -block_count,CreateShallowArrayLiteral,4,19 -block_count,CreateShallowArrayLiteral,5,17 -block_count,CreateShallowArrayLiteral,6,13 -block_count,CreateShallowArrayLiteral,7,13 -block_count,CreateShallowArrayLiteral,8,13 +block_count,CreateShallowArrayLiteral,3,20 +block_count,CreateShallowArrayLiteral,4,20 +block_count,CreateShallowArrayLiteral,5,18 +block_count,CreateShallowArrayLiteral,6,14 +block_count,CreateShallowArrayLiteral,7,14 +block_count,CreateShallowArrayLiteral,8,14 block_count,CreateShallowArrayLiteral,9,0 -block_count,CreateShallowArrayLiteral,10,13 +block_count,CreateShallowArrayLiteral,10,14 block_count,CreateShallowArrayLiteral,11,0 block_count,CreateShallowArrayLiteral,12,0 -block_count,CreateShallowArrayLiteral,13,13 -block_count,CreateShallowArrayLiteral,14,13 +block_count,CreateShallowArrayLiteral,13,14 +block_count,CreateShallowArrayLiteral,14,14 block_count,CreateShallowArrayLiteral,15,0 block_count,CreateShallowArrayLiteral,16,0 block_count,CreateShallowArrayLiteral,17,0 @@ -46497,8 +46833,8 @@ block_count,CreateShallowArrayLiteral,21,0 block_count,CreateShallowArrayLiteral,22,0 block_count,CreateShallowArrayLiteral,23,0 -block_count,CreateShallowArrayLiteral,24,13 -block_count,CreateShallowArrayLiteral,25,13 +block_count,CreateShallowArrayLiteral,24,14 +block_count,CreateShallowArrayLiteral,25,14 block_count,CreateShallowArrayLiteral,26,0 block_count,CreateShallowArrayLiteral,27,0 block_count,CreateShallowArrayLiteral,28,0 @@ -46510,10 +46846,10 @@ block_count,CreateShallowArrayLiteral,34,0 block_count,CreateShallowArrayLiteral,35,0 block_count,CreateShallowArrayLiteral,36,0 -block_count,CreateShallowArrayLiteral,37,13 +block_count,CreateShallowArrayLiteral,37,14 block_count,CreateShallowArrayLiteral,38,0 block_count,CreateShallowArrayLiteral,39,4 -block_count,CreateShallowArrayLiteral,40,17 +block_count,CreateShallowArrayLiteral,40,18 block_count,CreateShallowArrayLiteral,41,2 block_count,CreateShallowArrayLiteral,42,2 block_count,CreateShallowArrayLiteral,43,0 @@ -46542,15 +46878,15 @@ block_count,CreateShallowArrayLiteral,66,2 block_count,CreateShallowArrayLiteral,67,0 block_count,CreateShallowArrayLiteral,68,0 -block_count,CreateShallowArrayLiteral,69,19 +block_count,CreateShallowArrayLiteral,69,20 block_count,CreateShallowArrayLiteral,70,0 -block_count,CreateShallowArrayLiteral,71,19 -block_count,CreateShallowArrayLiteral,72,19 +block_count,CreateShallowArrayLiteral,71,20 +block_count,CreateShallowArrayLiteral,72,20 block_count,CreateShallowArrayLiteral,73,0 -block_count,CreateShallowArrayLiteral,74,19 +block_count,CreateShallowArrayLiteral,74,20 block_count,CreateShallowArrayLiteral,75,0 -block_count,CreateShallowArrayLiteral,76,19 -block_count,CreateShallowArrayLiteral,77,19 +block_count,CreateShallowArrayLiteral,76,20 +block_count,CreateShallowArrayLiteral,77,20 block_count,CreateShallowArrayLiteral,78,0 block_count,CreateShallowArrayLiteral,79,0 block_count,CreateEmptyArrayLiteral,0,29 @@ -46568,14 +46904,14 @@ block_count,CreateShallowObjectLiteral,0,32 block_count,CreateShallowObjectLiteral,1,32 block_count,CreateShallowObjectLiteral,2,0 -block_count,CreateShallowObjectLiteral,3,31 -block_count,CreateShallowObjectLiteral,4,31 -block_count,CreateShallowObjectLiteral,5,31 -block_count,CreateShallowObjectLiteral,6,31 +block_count,CreateShallowObjectLiteral,3,32 +block_count,CreateShallowObjectLiteral,4,32 +block_count,CreateShallowObjectLiteral,5,32 +block_count,CreateShallowObjectLiteral,6,32 block_count,CreateShallowObjectLiteral,7,0 -block_count,CreateShallowObjectLiteral,8,31 +block_count,CreateShallowObjectLiteral,8,32 block_count,CreateShallowObjectLiteral,9,0 -block_count,CreateShallowObjectLiteral,10,31 +block_count,CreateShallowObjectLiteral,10,32 block_count,CreateShallowObjectLiteral,11,0 block_count,CreateShallowObjectLiteral,12,0 block_count,CreateShallowObjectLiteral,13,0 @@ -46617,7 +46953,7 @@ block_count,CreateShallowObjectLiteral,49,0 block_count,CreateShallowObjectLiteral,50,0 block_count,CreateShallowObjectLiteral,51,0 -block_count,CreateShallowObjectLiteral,52,31 +block_count,CreateShallowObjectLiteral,52,32 block_count,CreateShallowObjectLiteral,53,0 block_count,CreateShallowObjectLiteral,54,0 block_count,CreateShallowObjectLiteral,55,0 @@ -46685,17 +47021,17 @@ block_count,CreateShallowObjectLiteral,117,0 block_count,CreateShallowObjectLiteral,118,0 block_count,CreateShallowObjectLiteral,119,0 -block_count,CreateShallowObjectLiteral,120,31 -block_count,CreateShallowObjectLiteral,121,31 -block_count,CreateShallowObjectLiteral,122,31 +block_count,CreateShallowObjectLiteral,120,32 +block_count,CreateShallowObjectLiteral,121,32 +block_count,CreateShallowObjectLiteral,122,32 block_count,CreateShallowObjectLiteral,123,0 -block_count,CreateShallowObjectLiteral,124,31 +block_count,CreateShallowObjectLiteral,124,32 block_count,CreateShallowObjectLiteral,125,0 block_count,CreateShallowObjectLiteral,126,0 -block_count,CreateShallowObjectLiteral,127,31 -block_count,CreateShallowObjectLiteral,128,31 -block_count,CreateShallowObjectLiteral,129,91 -block_count,CreateShallowObjectLiteral,130,82 +block_count,CreateShallowObjectLiteral,127,32 +block_count,CreateShallowObjectLiteral,128,32 +block_count,CreateShallowObjectLiteral,129,93 +block_count,CreateShallowObjectLiteral,130,84 block_count,CreateShallowObjectLiteral,131,0 block_count,CreateShallowObjectLiteral,132,0 block_count,CreateShallowObjectLiteral,133,0 @@ -46722,10 +47058,10 @@ block_count,CreateShallowObjectLiteral,154,0 block_count,CreateShallowObjectLiteral,155,0 block_count,CreateShallowObjectLiteral,156,0 -block_count,CreateShallowObjectLiteral,157,82 +block_count,CreateShallowObjectLiteral,157,83 block_count,CreateShallowObjectLiteral,158,8 -block_count,CreateShallowObjectLiteral,159,90 -block_count,CreateShallowObjectLiteral,160,59 +block_count,CreateShallowObjectLiteral,159,92 +block_count,CreateShallowObjectLiteral,160,61 block_count,CreateShallowObjectLiteral,161,31 block_count,CreateShallowObjectLiteral,162,0 block_count,CreateShallowObjectLiteral,163,0 @@ -46935,7 +47271,7 @@ block_count,NumberToString,65,0 block_count,NumberToString,66,0 block_count,NumberToString,67,0 -block_count,NumberToString,68,1511 +block_count,NumberToString,68,1510 block_count,NumberToString,69,15 block_count,ToBoolean,0,36 block_count,ToBoolean,1,36 @@ -46958,27 +47294,27 @@ block_count,ToBoolean,18,0 block_count,ToBoolean,19,0 block_count,ToBoolean,20,0 -block_count,ToBooleanForBaselineJump,0,1093 -block_count,ToBooleanForBaselineJump,1,1011 -block_count,ToBooleanForBaselineJump,2,615 -block_count,ToBooleanForBaselineJump,3,385 -block_count,ToBooleanForBaselineJump,4,385 -block_count,ToBooleanForBaselineJump,5,185 -block_count,ToBooleanForBaselineJump,6,184 -block_count,ToBooleanForBaselineJump,7,184 +block_count,ToBooleanForBaselineJump,0,1103 +block_count,ToBooleanForBaselineJump,1,1017 +block_count,ToBooleanForBaselineJump,2,617 +block_count,ToBooleanForBaselineJump,3,387 +block_count,ToBooleanForBaselineJump,4,387 +block_count,ToBooleanForBaselineJump,5,186 +block_count,ToBooleanForBaselineJump,6,185 +block_count,ToBooleanForBaselineJump,7,185 block_count,ToBooleanForBaselineJump,8,0 block_count,ToBooleanForBaselineJump,9,0 block_count,ToBooleanForBaselineJump,10,0 block_count,ToBooleanForBaselineJump,11,1 block_count,ToBooleanForBaselineJump,12,0 block_count,ToBooleanForBaselineJump,13,1 -block_count,ToBooleanForBaselineJump,14,199 +block_count,ToBooleanForBaselineJump,14,200 block_count,ToBooleanForBaselineJump,15,0 block_count,ToBooleanForBaselineJump,16,229 -block_count,ToBooleanForBaselineJump,17,395 -block_count,ToBooleanForBaselineJump,18,82 -block_count,ToBooleanForBaselineJump,19,51 -block_count,ToBooleanForBaselineJump,20,31 +block_count,ToBooleanForBaselineJump,17,400 +block_count,ToBooleanForBaselineJump,18,85 +block_count,ToBooleanForBaselineJump,19,52 +block_count,ToBooleanForBaselineJump,20,32 block_count,ToLength,0,2 block_count,ToLength,1,2 block_count,ToLength,2,0 @@ -47732,39 +48068,39 @@ block_count,DataViewPrototypeSetFloat64,114,0 block_count,DataViewPrototypeSetFloat64,115,0 block_count,DataViewPrototypeSetFloat64,116,0 -block_count,FunctionPrototypeHasInstance,0,90 +block_count,FunctionPrototypeHasInstance,0,92 block_count,FunctionPrototypeHasInstance,1,0 -block_count,FunctionPrototypeHasInstance,2,90 -block_count,FunctionPrototypeHasInstance,3,90 -block_count,FunctionPrototypeHasInstance,4,89 -block_count,FunctionPrototypeHasInstance,5,89 +block_count,FunctionPrototypeHasInstance,2,92 +block_count,FunctionPrototypeHasInstance,3,92 +block_count,FunctionPrototypeHasInstance,4,91 +block_count,FunctionPrototypeHasInstance,5,91 block_count,FunctionPrototypeHasInstance,6,0 -block_count,FunctionPrototypeHasInstance,7,89 +block_count,FunctionPrototypeHasInstance,7,91 block_count,FunctionPrototypeHasInstance,8,0 block_count,FunctionPrototypeHasInstance,9,0 block_count,FunctionPrototypeHasInstance,10,0 -block_count,FunctionPrototypeHasInstance,11,89 -block_count,FunctionPrototypeHasInstance,12,89 -block_count,FunctionPrototypeHasInstance,13,89 -block_count,FunctionPrototypeHasInstance,14,4 -block_count,FunctionPrototypeHasInstance,15,4 +block_count,FunctionPrototypeHasInstance,11,91 +block_count,FunctionPrototypeHasInstance,12,91 +block_count,FunctionPrototypeHasInstance,13,91 +block_count,FunctionPrototypeHasInstance,14,5 +block_count,FunctionPrototypeHasInstance,15,5 block_count,FunctionPrototypeHasInstance,16,0 -block_count,FunctionPrototypeHasInstance,17,84 -block_count,FunctionPrototypeHasInstance,18,89 -block_count,FunctionPrototypeHasInstance,19,289 -block_count,FunctionPrototypeHasInstance,20,282 +block_count,FunctionPrototypeHasInstance,17,86 +block_count,FunctionPrototypeHasInstance,18,91 +block_count,FunctionPrototypeHasInstance,19,297 +block_count,FunctionPrototypeHasInstance,20,290 block_count,FunctionPrototypeHasInstance,21,7 block_count,FunctionPrototypeHasInstance,22,7 block_count,FunctionPrototypeHasInstance,23,7 block_count,FunctionPrototypeHasInstance,24,0 block_count,FunctionPrototypeHasInstance,25,0 block_count,FunctionPrototypeHasInstance,26,0 -block_count,FunctionPrototypeHasInstance,27,289 -block_count,FunctionPrototypeHasInstance,28,236 -block_count,FunctionPrototypeHasInstance,29,200 +block_count,FunctionPrototypeHasInstance,27,297 +block_count,FunctionPrototypeHasInstance,28,242 +block_count,FunctionPrototypeHasInstance,29,206 block_count,FunctionPrototypeHasInstance,30,35 -block_count,FunctionPrototypeHasInstance,31,53 -block_count,FunctionPrototypeHasInstance,32,89 +block_count,FunctionPrototypeHasInstance,31,55 +block_count,FunctionPrototypeHasInstance,32,91 block_count,FunctionPrototypeHasInstance,33,0 block_count,FunctionPrototypeHasInstance,34,0 block_count,FunctionPrototypeHasInstance,35,0 @@ -47847,8 +48183,8 @@ block_count,GetIteratorWithFeedback,1,0 block_count,GetIteratorWithFeedback,2,0 block_count,GetIteratorBaseline,0,34 -block_count,CallIteratorWithFeedback,0,34 -block_count,CallIteratorWithFeedback,1,34 +block_count,CallIteratorWithFeedback,0,35 +block_count,CallIteratorWithFeedback,1,35 block_count,CallIteratorWithFeedback,2,0 block_count,CallIteratorWithFeedback,3,0 block_count,CallIteratorWithFeedback,4,0 @@ -47913,15 +48249,15 @@ block_count,CallIteratorWithFeedback,63,0 block_count,CallIteratorWithFeedback,64,0 block_count,CallIteratorWithFeedback,65,0 -block_count,CallIteratorWithFeedback,66,34 +block_count,CallIteratorWithFeedback,66,35 block_count,CallIteratorWithFeedback,67,0 -block_count,CallIteratorWithFeedback,68,34 -block_count,CallIteratorWithFeedback,69,34 +block_count,CallIteratorWithFeedback,68,35 +block_count,CallIteratorWithFeedback,69,35 block_count,CallIteratorWithFeedback,70,0 -block_count,CallIteratorWithFeedback,71,34 -block_count,CallIteratorWithFeedback,72,34 +block_count,CallIteratorWithFeedback,71,35 +block_count,CallIteratorWithFeedback,72,35 block_count,CallIteratorWithFeedback,73,0 -block_count,CallIteratorWithFeedback,74,34 +block_count,CallIteratorWithFeedback,74,35 block_count,MathAbs,0,2 block_count,MathAbs,1,0 block_count,MathAbs,2,2 @@ -48106,7 +48442,7 @@ block_count,MathMax,15,2 block_count,MathMax,16,0 block_count,MathMax,17,2 -block_count,MathMax,18,1 +block_count,MathMax,18,2 block_count,MathMax,19,0 block_count,MathMax,20,0 block_count,MathMax,21,0 @@ -48729,7 +49065,7 @@ block_count,NumberParseInt,0,5 block_count,NumberParseInt,1,0 block_count,NumberParseInt,2,5 -block_count,Add,0,14 +block_count,Add,0,13 block_count,Add,1,14 block_count,Add,2,0 block_count,Add,3,0 @@ -49045,7 +49381,7 @@ block_count,LessThan,20,0 block_count,LessThan,21,0 block_count,LessThan,22,0 -block_count,LessThan,23,1251 +block_count,LessThan,23,1250 block_count,LessThan,24,519 block_count,LessThan,25,519 block_count,LessThan,26,0 @@ -49055,7 +49391,7 @@ block_count,LessThan,30,0 block_count,LessThan,31,0 block_count,LessThan,32,0 -block_count,LessThan,33,33 +block_count,LessThan,33,34 block_count,LessThan,34,33 block_count,LessThan,35,0 block_count,LessThan,36,0 @@ -49072,7 +49408,7 @@ block_count,LessThan,47,134 block_count,GreaterThan,0,668 block_count,GreaterThan,1,1159 -block_count,GreaterThan,2,1141 +block_count,GreaterThan,2,1140 block_count,GreaterThan,3,1036 block_count,GreaterThan,4,16 block_count,GreaterThan,5,16 @@ -49093,7 +49429,7 @@ block_count,GreaterThan,20,0 block_count,GreaterThan,21,0 block_count,GreaterThan,22,0 -block_count,GreaterThan,23,1020 +block_count,GreaterThan,23,1019 block_count,GreaterThan,24,474 block_count,GreaterThan,25,474 block_count,GreaterThan,26,0 @@ -49219,7 +49555,7 @@ block_count,Equal,55,3 block_count,Equal,56,19 block_count,Equal,57,41 -block_count,Equal,58,62 +block_count,Equal,58,61 block_count,Equal,59,61 block_count,Equal,60,34 block_count,Equal,61,4 @@ -49279,7 +49615,7 @@ block_count,StrictEqual,28,0 block_count,StrictEqual,29,0 block_count,StrictEqual,30,0 -block_count,StrictEqual,31,30 +block_count,StrictEqual,31,31 block_count,StrictEqual,32,169 block_count,StrictEqual,33,167 block_count,StrictEqual,34,167 @@ -50705,16 +51041,16 @@ block_count,RegExpPrototypeExec,15,423 block_count,RegExpPrototypeExec,16,0 block_count,RegExpPrototypeExec,17,423 -block_count,RegExpPrototypeExec,18,397 +block_count,RegExpPrototypeExec,18,396 block_count,RegExpPrototypeExec,19,331 block_count,RegExpPrototypeExec,20,65 -block_count,RegExpPrototypeExec,21,397 -block_count,RegExpPrototypeExec,22,397 -block_count,RegExpPrototypeExec,23,397 +block_count,RegExpPrototypeExec,21,396 +block_count,RegExpPrototypeExec,22,396 +block_count,RegExpPrototypeExec,23,396 block_count,RegExpPrototypeExec,24,0 block_count,RegExpPrototypeExec,25,0 block_count,RegExpPrototypeExec,26,0 -block_count,RegExpPrototypeExec,27,397 +block_count,RegExpPrototypeExec,27,396 block_count,RegExpPrototypeExec,28,12 block_count,RegExpPrototypeExec,29,25 block_count,RegExpPrototypeExec,30,3 @@ -50746,7 +51082,7 @@ block_count,RegExpPrototypeExec,56,0 block_count,RegExpPrototypeExec,57,384 block_count,RegExpPrototypeExec,58,396 -block_count,RegExpPrototypeExec,59,397 +block_count,RegExpPrototypeExec,59,396 block_count,RegExpPrototypeExec,60,0 block_count,RegExpPrototypeExec,61,331 block_count,RegExpPrototypeExec,62,65 @@ -51010,7 +51346,7 @@ block_count,RegExpPrototypeExec,320,172 block_count,RegExpPrototypeExec,321,74 block_count,RegExpPrototypeExec,322,97 -block_count,RegExpPrototypeExec,323,471 +block_count,RegExpPrototypeExec,323,470 block_count,RegExpPrototypeExec,324,373 block_count,RegExpPrototypeExec,325,97 block_count,RegExpPrototypeExec,326,172 @@ -51018,10 +51354,10 @@ block_count,RegExpPrototypeExec,328,88 block_count,RegExpPrototypeExec,329,172 block_count,RegExpPrototypeExec,330,97 -block_count,RegExpPrototypeExec,331,858 +block_count,RegExpPrototypeExec,331,857 block_count,RegExpPrototypeExec,332,351 block_count,RegExpPrototypeExec,333,506 -block_count,RegExpPrototypeExec,334,858 +block_count,RegExpPrototypeExec,334,857 block_count,RegExpPrototypeExec,335,760 block_count,RegExpPrototypeExec,336,97 block_count,RegExpPrototypeExec,337,0 @@ -51136,7 +51472,7 @@ block_count,RegExpPrototypeExec,446,172 block_count,RegExpPrototypeExec,447,251 block_count,RegExpPrototypeExec,448,423 -block_count,RegExpMatchFast,0,1252 +block_count,RegExpMatchFast,0,1251 block_count,RegExpMatchFast,1,2 block_count,RegExpMatchFast,2,0 block_count,RegExpMatchFast,3,0 @@ -52074,16 +52410,16 @@ block_count,RegExpReplace,36,0 block_count,RegExpReplace,37,0 block_count,RegExpReplace,38,3 -block_count,RegExpReplace,39,797 -block_count,RegExpReplace,40,797 -block_count,RegExpReplace,41,797 -block_count,RegExpReplace,42,398 +block_count,RegExpReplace,39,796 +block_count,RegExpReplace,40,796 +block_count,RegExpReplace,41,796 +block_count,RegExpReplace,42,397 block_count,RegExpReplace,43,0 block_count,RegExpReplace,44,0 block_count,RegExpReplace,45,0 -block_count,RegExpReplace,46,398 -block_count,RegExpReplace,47,398 -block_count,RegExpReplace,48,399 +block_count,RegExpReplace,46,397 +block_count,RegExpReplace,47,397 +block_count,RegExpReplace,48,398 block_count,RegExpReplace,49,395 block_count,RegExpReplace,50,395 block_count,RegExpReplace,51,0 @@ -52364,19 +52700,19 @@ block_count,RegExpReplace,326,0 block_count,RegExpReplace,327,32 block_count,RegExpReplace,328,13 -block_count,RegExpReplace,329,138 +block_count,RegExpReplace,329,137 block_count,RegExpReplace,330,85 block_count,RegExpReplace,331,52 -block_count,RegExpReplace,332,138 +block_count,RegExpReplace,332,137 block_count,RegExpReplace,333,0 -block_count,RegExpReplace,334,138 -block_count,RegExpReplace,335,138 -block_count,RegExpReplace,336,138 -block_count,RegExpReplace,337,138 +block_count,RegExpReplace,334,137 +block_count,RegExpReplace,335,137 +block_count,RegExpReplace,336,137 +block_count,RegExpReplace,337,137 block_count,RegExpReplace,338,0 block_count,RegExpReplace,339,0 block_count,RegExpReplace,340,0 -block_count,RegExpReplace,341,138 +block_count,RegExpReplace,341,137 block_count,RegExpReplace,342,196 block_count,RegExpReplace,343,145 block_count,RegExpReplace,344,145 @@ -52599,7 +52935,7 @@ block_count,RegExpReplace,561,0 block_count,RegExpReplace,562,0 block_count,RegExpReplace,563,50 -block_count,RegExpReplace,564,138 +block_count,RegExpReplace,564,137 block_count,RegExpReplace,565,50 block_count,RegExpReplace,566,0 block_count,RegExpReplace,567,50 @@ -52617,10 +52953,10 @@ block_count,RegExpReplace,579,50 block_count,RegExpReplace,580,0 block_count,RegExpReplace,581,87 -block_count,RegExpReplace,582,138 -block_count,RegExpReplace,583,138 +block_count,RegExpReplace,582,137 +block_count,RegExpReplace,583,137 block_count,RegExpReplace,584,0 -block_count,RegExpReplace,585,138 +block_count,RegExpReplace,585,137 block_count,RegExpReplace,586,0 block_count,RegExpPrototypeReplace,0,0 block_count,RegExpPrototypeReplace,1,0 @@ -52959,7 +53295,7 @@ block_count,RegExpSplit,63,0 block_count,RegExpSplit,64,52 block_count,RegExpSplit,65,0 -block_count,RegExpSplit,66,52 +block_count,RegExpSplit,66,51 block_count,RegExpSplit,67,52 block_count,RegExpSplit,68,52 block_count,RegExpSplit,69,0 @@ -53640,7 +53976,7 @@ block_count,RegExpPrototypeTestFast,53,0 block_count,RegExpPrototypeTestFast,54,447 block_count,RegExpPrototypeTestFast,55,0 -block_count,RegExpPrototypeTestFast,56,447 +block_count,RegExpPrototypeTestFast,56,446 block_count,RegExpPrototypeTestFast,57,447 block_count,RegExpPrototypeTestFast,58,447 block_count,RegExpPrototypeTestFast,59,0 @@ -54597,27 +54933,27 @@ block_count,StringIteratorPrototypeNext,86,0 block_count,StringIteratorPrototypeNext,87,0 block_count,StringIteratorPrototypeNext,88,0 -block_count,StringPrototypeMatch,0,1252 +block_count,StringPrototypeMatch,0,1251 block_count,StringPrototypeMatch,1,0 -block_count,StringPrototypeMatch,2,1252 -block_count,StringPrototypeMatch,3,1252 -block_count,StringPrototypeMatch,4,1252 -block_count,StringPrototypeMatch,5,1252 -block_count,StringPrototypeMatch,6,1252 -block_count,StringPrototypeMatch,7,1252 -block_count,StringPrototypeMatch,8,1252 +block_count,StringPrototypeMatch,2,1251 +block_count,StringPrototypeMatch,3,1251 +block_count,StringPrototypeMatch,4,1251 +block_count,StringPrototypeMatch,5,1251 +block_count,StringPrototypeMatch,6,1251 +block_count,StringPrototypeMatch,7,1251 +block_count,StringPrototypeMatch,8,1251 block_count,StringPrototypeMatch,9,0 -block_count,StringPrototypeMatch,10,1252 +block_count,StringPrototypeMatch,10,1251 block_count,StringPrototypeMatch,11,0 -block_count,StringPrototypeMatch,12,1252 +block_count,StringPrototypeMatch,12,1251 block_count,StringPrototypeMatch,13,0 -block_count,StringPrototypeMatch,14,1252 +block_count,StringPrototypeMatch,14,1251 block_count,StringPrototypeMatch,15,0 -block_count,StringPrototypeMatch,16,1252 +block_count,StringPrototypeMatch,16,1251 block_count,StringPrototypeMatch,17,0 -block_count,StringPrototypeMatch,18,1252 +block_count,StringPrototypeMatch,18,1251 block_count,StringPrototypeMatch,19,0 -block_count,StringPrototypeMatch,20,1252 +block_count,StringPrototypeMatch,20,1251 block_count,StringPrototypeSearch,0,1 block_count,StringPrototypeSearch,1,0 block_count,StringPrototypeSearch,2,1 @@ -54666,9 +55002,9 @@ block_count,StringPrototypeSlice,17,0 block_count,StringPrototypeSlice,18,11 block_count,StringPrototypeSlice,19,11 -block_count,StringPrototypeSlice,20,10 +block_count,StringPrototypeSlice,20,11 block_count,StringPrototypeSlice,21,0 -block_count,StringPrototypeSlice,22,10 +block_count,StringPrototypeSlice,22,11 block_count,StringPrototypeSlice,23,0 block_count,StringPrototypeSlice,24,0 block_count,StringPrototypeSlice,25,0 @@ -54712,11 +55048,11 @@ block_count,StringPrototypeSlice,63,7 block_count,StringPrototypeSlice,64,11 block_count,StringPrototypeSlice,65,10 -block_count,StringPrototypeSlice,66,9 -block_count,StringPrototypeSlice,67,9 -block_count,StringPrototypeSlice,68,6 +block_count,StringPrototypeSlice,66,10 +block_count,StringPrototypeSlice,67,10 +block_count,StringPrototypeSlice,68,7 block_count,StringPrototypeSlice,69,4 -block_count,StringPrototypeSlice,70,8 +block_count,StringPrototypeSlice,70,9 block_count,StringPrototypeSlice,71,0 block_count,StringPrototypeSlice,72,0 block_count,StringPrototypeSlice,73,0 @@ -54727,12 +55063,12 @@ block_count,StringPrototypeSlice,78,4 block_count,StringPrototypeSlice,79,0 block_count,StringPrototypeSlice,80,2 -block_count,StringPrototypeSlice,81,6 +block_count,StringPrototypeSlice,81,7 block_count,StringPrototypeSlice,82,3 -block_count,StringPrototypeSlice,83,0 +block_count,StringPrototypeSlice,83,1 block_count,StringPrototypeSlice,84,0 -block_count,StringPrototypeSlice,85,0 -block_count,StringPrototypeSlice,86,0 +block_count,StringPrototypeSlice,85,1 +block_count,StringPrototypeSlice,86,1 block_count,StringPrototypeSlice,87,2 block_count,StringPrototypeSlice,88,0 block_count,StringPrototypeSlice,89,2 @@ -54766,7 +55102,7 @@ block_count,StringPrototypeSlice,117,0 block_count,StringPrototypeSlice,118,0 block_count,StringPrototypeSlice,119,0 -block_count,StringPrototypeSlice,120,0 +block_count,StringPrototypeSlice,120,1 block_count,StringPrototypeSlice,121,0 block_count,StringPrototypeSlice,122,0 block_count,StringPrototypeSlice,123,0 @@ -58049,38 +58385,38 @@ block_count,NewStrictArgumentsElements,16,0 block_count,NewStrictArgumentsElements,17,0 block_count,NewStrictArgumentsElements,18,0 -block_count,NewRestArgumentsElements,0,15 -block_count,NewRestArgumentsElements,1,15 +block_count,NewRestArgumentsElements,0,14 +block_count,NewRestArgumentsElements,1,14 block_count,NewRestArgumentsElements,2,0 -block_count,NewRestArgumentsElements,3,15 -block_count,NewRestArgumentsElements,4,15 -block_count,NewRestArgumentsElements,5,15 -block_count,NewRestArgumentsElements,6,15 -block_count,NewRestArgumentsElements,7,15 +block_count,NewRestArgumentsElements,3,14 +block_count,NewRestArgumentsElements,4,14 +block_count,NewRestArgumentsElements,5,14 +block_count,NewRestArgumentsElements,6,14 +block_count,NewRestArgumentsElements,7,14 block_count,NewRestArgumentsElements,8,0 -block_count,NewRestArgumentsElements,9,15 +block_count,NewRestArgumentsElements,9,14 block_count,NewRestArgumentsElements,10,0 block_count,NewRestArgumentsElements,11,0 -block_count,NewRestArgumentsElements,12,15 -block_count,NewRestArgumentsElements,13,45 +block_count,NewRestArgumentsElements,12,14 +block_count,NewRestArgumentsElements,13,43 block_count,NewRestArgumentsElements,14,29 block_count,NewRestArgumentsElements,15,29 block_count,NewRestArgumentsElements,16,29 block_count,NewRestArgumentsElements,17,0 block_count,NewRestArgumentsElements,18,29 block_count,NewRestArgumentsElements,19,0 -block_count,NewRestArgumentsElements,20,15 +block_count,NewRestArgumentsElements,20,14 block_count,NewRestArgumentsElements,21,0 block_count,NewRestArgumentsElements,22,0 block_count,NewRestArgumentsElements,23,0 block_count,NewRestArgumentsElements,24,0 block_count,NewRestArgumentsElements,25,0 -block_count,FastNewSloppyArguments,0,5 -block_count,FastNewSloppyArguments,1,5 -block_count,FastNewSloppyArguments,2,5 +block_count,FastNewSloppyArguments,0,6 +block_count,FastNewSloppyArguments,1,6 +block_count,FastNewSloppyArguments,2,6 block_count,FastNewSloppyArguments,3,0 -block_count,FastNewSloppyArguments,4,5 -block_count,FastNewSloppyArguments,5,5 +block_count,FastNewSloppyArguments,4,6 +block_count,FastNewSloppyArguments,5,6 block_count,FastNewSloppyArguments,6,0 block_count,FastNewSloppyArguments,7,0 block_count,FastNewSloppyArguments,8,0 @@ -58123,11 +58459,11 @@ block_count,FastNewSloppyArguments,45,0 block_count,FastNewSloppyArguments,46,2 block_count,FastNewSloppyArguments,47,8 -block_count,FastNewSloppyArguments,48,5 -block_count,FastNewSloppyArguments,49,5 -block_count,FastNewSloppyArguments,50,5 +block_count,FastNewSloppyArguments,48,6 +block_count,FastNewSloppyArguments,49,6 +block_count,FastNewSloppyArguments,50,6 block_count,FastNewSloppyArguments,51,0 -block_count,FastNewSloppyArguments,52,5 +block_count,FastNewSloppyArguments,52,6 block_count,FastNewSloppyArguments,53,0 block_count,FastNewSloppyArguments,54,2 block_count,FastNewSloppyArguments,55,0 @@ -58135,7 +58471,7 @@ block_count,FastNewSloppyArguments,57,0 block_count,FastNewSloppyArguments,58,2 block_count,FastNewSloppyArguments,59,5 -block_count,FastNewSloppyArguments,60,5 +block_count,FastNewSloppyArguments,60,6 block_count,FastNewSloppyArguments,61,0 block_count,FastNewSloppyArguments,62,0 block_count,FastNewSloppyArguments,63,0 @@ -58655,7 +58991,7 @@ block_count,StringIndexOf,9,184 block_count,StringIndexOf,10,214 block_count,StringIndexOf,11,49 -block_count,StringIndexOf,12,30 +block_count,StringIndexOf,12,29 block_count,StringIndexOf,13,28 block_count,StringIndexOf,14,1 block_count,StringIndexOf,15,0 @@ -58692,7 +59028,7 @@ block_count,StringIndexOf,46,0 block_count,StringIndexOf,47,0 block_count,StringIndexOf,48,1 -block_count,StringIndexOf,49,30 +block_count,StringIndexOf,49,29 block_count,StringIndexOf,50,19 block_count,StringIndexOf,51,19 block_count,StringIndexOf,52,19 @@ -58859,14 +59195,14 @@ block_count,SortCompareDefault,9,3 block_count,SortCompareDefault,10,0 block_count,SortCompareDefault,11,3 -block_count,SortCompareUserFn,0,781 +block_count,SortCompareUserFn,0,780 block_count,SortCompareUserFn,1,0 block_count,SortCompareUserFn,2,0 block_count,SortCompareUserFn,3,0 block_count,SortCompareUserFn,4,0 -block_count,SortCompareUserFn,5,781 -block_count,SortCompareUserFn,6,781 -block_count,SortCompareUserFn,7,781 +block_count,SortCompareUserFn,5,780 +block_count,SortCompareUserFn,6,780 +block_count,SortCompareUserFn,7,780 block_count,Copy,0,2 block_count,Copy,1,1 block_count,Copy,2,141 @@ -59381,8 +59717,8 @@ block_count,ArrayTimSort,104,0 block_count,ArrayTimSort,105,39 block_count,ArrayTimSort,106,184 -block_count,ArrayTimSort,107,145 -block_count,ArrayTimSort,108,145 +block_count,ArrayTimSort,107,144 +block_count,ArrayTimSort,108,144 block_count,ArrayTimSort,109,546 block_count,ArrayTimSort,110,401 block_count,ArrayTimSort,111,401 @@ -59394,20 +59730,20 @@ block_count,ArrayTimSort,117,0 block_count,ArrayTimSort,118,401 block_count,ArrayTimSort,119,187 -block_count,ArrayTimSort,120,214 +block_count,ArrayTimSort,120,213 block_count,ArrayTimSort,121,187 -block_count,ArrayTimSort,122,214 +block_count,ArrayTimSort,122,213 block_count,ArrayTimSort,123,401 block_count,ArrayTimSort,124,0 -block_count,ArrayTimSort,125,145 +block_count,ArrayTimSort,125,144 block_count,ArrayTimSort,126,767 block_count,ArrayTimSort,127,622 block_count,ArrayTimSort,128,622 block_count,ArrayTimSort,129,622 block_count,ArrayTimSort,130,0 block_count,ArrayTimSort,131,0 -block_count,ArrayTimSort,132,145 -block_count,ArrayTimSort,133,145 +block_count,ArrayTimSort,132,144 +block_count,ArrayTimSort,133,144 block_count,ArrayTimSort,134,0 block_count,ArrayTimSort,135,0 block_count,ArrayTimSort,136,39 @@ -60030,12 +60366,12 @@ block_count,StringFastLocaleCompare,325,0 block_count,StringFastLocaleCompare,326,425 block_count,StringFastLocaleCompare,327,1347 -block_count,StringFastLocaleCompare,328,6597 -block_count,StringFastLocaleCompare,329,6586 -block_count,StringFastLocaleCompare,330,6586 -block_count,StringFastLocaleCompare,331,6529 -block_count,StringFastLocaleCompare,332,6529 -block_count,StringFastLocaleCompare,333,5250 +block_count,StringFastLocaleCompare,328,6596 +block_count,StringFastLocaleCompare,329,6585 +block_count,StringFastLocaleCompare,330,6585 +block_count,StringFastLocaleCompare,331,6528 +block_count,StringFastLocaleCompare,332,6528 +block_count,StringFastLocaleCompare,333,5249 block_count,StringFastLocaleCompare,334,1279 block_count,StringFastLocaleCompare,335,842 block_count,StringFastLocaleCompare,336,436 @@ -60735,7 +61071,7 @@ block_count,LdaZeroHandler,1,19 block_count,LdaZeroHandler,2,7 block_count,LdaSmiHandler,0,27 -block_count,LdaSmiHandler,1,17 +block_count,LdaSmiHandler,1,18 block_count,LdaSmiHandler,2,9 block_count,LdaUndefinedHandler,0,14 block_count,LdaUndefinedHandler,1,14 @@ -60747,14 +61083,14 @@ block_count,LdaTheHoleHandler,1,0 block_count,LdaTheHoleHandler,2,0 block_count,LdaTrueHandler,0,4 -block_count,LdaFalseHandler,0,6 +block_count,LdaFalseHandler,0,5 block_count,LdaConstantHandler,0,24 block_count,LdaConstantHandler,1,13 block_count,LdaConstantHandler,2,10 block_count,LdaContextSlotHandler,0,1 block_count,LdaContextSlotHandler,1,1 -block_count,LdaContextSlotHandler,2,2 -block_count,LdaContextSlotHandler,3,2 +block_count,LdaContextSlotHandler,2,1 +block_count,LdaContextSlotHandler,3,1 block_count,LdaContextSlotHandler,4,0 block_count,LdaContextSlotHandler,5,1 block_count,LdaContextSlotHandler,6,0 @@ -60815,22 +61151,22 @@ block_count,LdaScriptContextSlotHandler,48,0 block_count,LdaScriptContextSlotHandler,49,0 block_count,LdaScriptContextSlotHandler,50,0 -block_count,LdaImmutableContextSlotHandler,0,10 -block_count,LdaImmutableContextSlotHandler,1,7 -block_count,LdaImmutableContextSlotHandler,2,9 -block_count,LdaImmutableContextSlotHandler,3,9 -block_count,LdaImmutableContextSlotHandler,4,2 -block_count,LdaImmutableContextSlotHandler,5,7 +block_count,LdaImmutableContextSlotHandler,0,9 +block_count,LdaImmutableContextSlotHandler,1,6 +block_count,LdaImmutableContextSlotHandler,2,8 +block_count,LdaImmutableContextSlotHandler,3,8 +block_count,LdaImmutableContextSlotHandler,4,1 +block_count,LdaImmutableContextSlotHandler,5,6 block_count,LdaImmutableContextSlotHandler,6,0 block_count,LdaImmutableContextSlotHandler,7,3 -block_count,LdaImmutableContextSlotHandler,8,10 +block_count,LdaImmutableContextSlotHandler,8,9 block_count,LdaImmutableContextSlotHandler,9,0 -block_count,LdaImmutableContextSlotHandler,10,10 +block_count,LdaImmutableContextSlotHandler,10,9 block_count,LdaImmutableContextSlotHandler,11,2 -block_count,LdaImmutableContextSlotHandler,12,8 -block_count,LdaCurrentContextSlotHandler,0,20 +block_count,LdaImmutableContextSlotHandler,12,7 +block_count,LdaCurrentContextSlotHandler,0,19 block_count,LdaCurrentContextSlotHandler,1,0 -block_count,LdaCurrentContextSlotHandler,2,20 +block_count,LdaCurrentContextSlotHandler,2,19 block_count,LdaCurrentContextSlotHandler,3,8 block_count,LdaCurrentContextSlotHandler,4,11 block_count,LdaCurrentScriptContextSlotHandler,0,0 @@ -60876,12 +61212,12 @@ block_count,LdaCurrentScriptContextSlotHandler,40,0 block_count,LdaCurrentScriptContextSlotHandler,41,0 block_count,LdaCurrentScriptContextSlotHandler,42,0 -block_count,LdaImmutableCurrentContextSlotHandler,0,34 +block_count,LdaImmutableCurrentContextSlotHandler,0,35 block_count,LdaImmutableCurrentContextSlotHandler,1,0 -block_count,LdaImmutableCurrentContextSlotHandler,2,34 +block_count,LdaImmutableCurrentContextSlotHandler,2,35 block_count,LdaImmutableCurrentContextSlotHandler,3,5 block_count,LdaImmutableCurrentContextSlotHandler,4,29 -block_count,StarHandler,0,35 +block_count,StarHandler,0,34 block_count,MovHandler,0,45 block_count,PushContextHandler,0,3 block_count,PopContextHandler,0,0 @@ -61481,9 +61817,9 @@ block_count,StaContextSlotHandler,8,0 block_count,StaContextSlotHandler,9,0 block_count,StaContextSlotHandler,10,0 -block_count,StaCurrentContextSlotHandler,0,12 +block_count,StaCurrentContextSlotHandler,0,10 block_count,StaCurrentContextSlotHandler,1,0 -block_count,StaCurrentContextSlotHandler,2,12 +block_count,StaCurrentContextSlotHandler,2,10 block_count,StaScriptContextSlotHandler,0,0 block_count,StaScriptContextSlotHandler,1,0 block_count,StaScriptContextSlotHandler,2,0 @@ -62342,11 +62678,11 @@ block_count,StaLookupSlotHandler,3,0 block_count,StaLookupSlotHandler,4,0 block_count,StaLookupSlotHandler,5,0 -block_count,GetNamedPropertyHandler,0,167 -block_count,GetNamedPropertyHandler,1,139 -block_count,GetNamedPropertyHandler,2,139 +block_count,GetNamedPropertyHandler,0,168 +block_count,GetNamedPropertyHandler,1,140 +block_count,GetNamedPropertyHandler,2,140 block_count,GetNamedPropertyHandler,3,0 -block_count,GetNamedPropertyHandler,4,139 +block_count,GetNamedPropertyHandler,4,140 block_count,GetNamedPropertyHandler,5,12 block_count,GetNamedPropertyHandler,6,0 block_count,GetNamedPropertyHandler,7,12 @@ -62358,8 +62694,8 @@ block_count,GetNamedPropertyHandler,13,0 block_count,GetNamedPropertyHandler,14,6 block_count,GetNamedPropertyHandler,15,127 -block_count,GetNamedPropertyHandler,16,133 -block_count,GetNamedPropertyHandler,17,44 +block_count,GetNamedPropertyHandler,16,134 +block_count,GetNamedPropertyHandler,17,45 block_count,GetNamedPropertyHandler,18,44 block_count,GetNamedPropertyHandler,19,40 block_count,GetNamedPropertyHandler,20,40 @@ -62453,12 +62789,12 @@ block_count,GetNamedPropertyHandler,108,0 block_count,GetNamedPropertyHandler,109,0 block_count,GetNamedPropertyHandler,110,0 -block_count,GetNamedPropertyHandler,111,88 -block_count,GetNamedPropertyHandler,112,128 +block_count,GetNamedPropertyHandler,111,89 +block_count,GetNamedPropertyHandler,112,129 block_count,GetNamedPropertyHandler,113,41 block_count,GetNamedPropertyHandler,114,6 block_count,GetNamedPropertyHandler,115,5 -block_count,GetNamedPropertyHandler,116,4 +block_count,GetNamedPropertyHandler,116,5 block_count,GetNamedPropertyHandler,117,0 block_count,GetNamedPropertyHandler,118,0 block_count,GetNamedPropertyHandler,119,0 @@ -62590,15 +62926,15 @@ block_count,GetNamedPropertyHandler,245,0 block_count,GetNamedPropertyHandler,246,1 block_count,GetNamedPropertyHandler,247,34 -block_count,GetNamedPropertyHandler,248,87 -block_count,GetNamedPropertyHandler,249,87 +block_count,GetNamedPropertyHandler,248,88 +block_count,GetNamedPropertyHandler,249,88 block_count,GetNamedPropertyHandler,250,16 block_count,GetNamedPropertyHandler,251,71 -block_count,GetNamedPropertyHandler,252,87 -block_count,GetNamedPropertyHandler,253,81 -block_count,GetNamedPropertyHandler,254,5 -block_count,GetNamedPropertyHandler,255,5 -block_count,GetNamedPropertyHandler,256,5 +block_count,GetNamedPropertyHandler,252,88 +block_count,GetNamedPropertyHandler,253,82 +block_count,GetNamedPropertyHandler,254,6 +block_count,GetNamedPropertyHandler,255,6 +block_count,GetNamedPropertyHandler,256,6 block_count,GetNamedPropertyHandler,257,0 block_count,GetNamedPropertyHandler,258,0 block_count,GetNamedPropertyHandler,259,0 @@ -62649,14 +62985,14 @@ block_count,GetNamedPropertyHandler,304,0 block_count,GetNamedPropertyHandler,305,0 block_count,GetNamedPropertyHandler,306,0 -block_count,GetNamedPropertyHandler,307,5 +block_count,GetNamedPropertyHandler,307,6 block_count,GetNamedPropertyHandler,308,0 -block_count,GetNamedPropertyHandler,309,5 -block_count,GetNamedPropertyHandler,310,5 +block_count,GetNamedPropertyHandler,309,6 +block_count,GetNamedPropertyHandler,310,6 block_count,GetNamedPropertyHandler,311,0 block_count,GetNamedPropertyHandler,312,28 -block_count,GetNamedPropertyHandler,313,167 -block_count,GetNamedPropertyHandler,314,43 +block_count,GetNamedPropertyHandler,313,168 +block_count,GetNamedPropertyHandler,314,44 block_count,GetNamedPropertyHandler,315,124 block_count,GetNamedPropertyFromSuperHandler,0,0 block_count,GetKeyedPropertyHandler,0,63 @@ -62665,12 +63001,12 @@ block_count,GetEnumeratedKeyedPropertyHandler,0,1 block_count,SetNamedPropertyHandler,0,20 block_count,DefineNamedOwnPropertyHandler,0,4 -block_count,SetKeyedPropertyHandler,0,43 +block_count,SetKeyedPropertyHandler,0,44 block_count,DefineKeyedOwnPropertyHandler,0,0 block_count,StaInArrayLiteralHandler,0,4 block_count,DefineKeyedOwnPropertyInLiteralHandler,0,0 -block_count,AddHandler,0,37 -block_count,AddHandler,1,14 +block_count,AddHandler,0,38 +block_count,AddHandler,1,15 block_count,AddHandler,2,0 block_count,AddHandler,3,0 block_count,AddHandler,4,0 @@ -62751,7 +63087,7 @@ block_count,AddHandler,79,0 block_count,AddHandler,80,13 block_count,AddHandler,81,13 -block_count,AddHandler,82,37 +block_count,AddHandler,82,38 block_count,AddHandler,83,21 block_count,AddHandler,84,16 block_count,SubHandler,0,7 @@ -62832,7 +63168,7 @@ block_count,MulHandler,5,2 block_count,MulHandler,6,2 block_count,MulHandler,7,2 -block_count,MulHandler,8,1 +block_count,MulHandler,8,2 block_count,MulHandler,9,0 block_count,MulHandler,10,0 block_count,MulHandler,11,0 @@ -62900,7 +63236,7 @@ block_count,MulHandler,73,15 block_count,MulHandler,74,15 block_count,MulHandler,75,0 -block_count,MulHandler,76,14 +block_count,MulHandler,76,15 block_count,MulHandler,77,0 block_count,MulHandler,78,15 block_count,MulHandler,79,0 @@ -63320,8 +63656,8 @@ block_count,BitwiseXorHandler,93,3 block_count,BitwiseAndHandler,0,2 block_count,BitwiseAndHandler,1,1 -block_count,BitwiseAndHandler,2,0 -block_count,BitwiseAndHandler,3,0 +block_count,BitwiseAndHandler,2,1 +block_count,BitwiseAndHandler,3,1 block_count,BitwiseAndHandler,4,0 block_count,BitwiseAndHandler,5,0 block_count,BitwiseAndHandler,6,0 @@ -63369,7 +63705,7 @@ block_count,BitwiseAndHandler,48,0 block_count,BitwiseAndHandler,49,0 block_count,BitwiseAndHandler,50,0 -block_count,BitwiseAndHandler,51,0 +block_count,BitwiseAndHandler,51,1 block_count,BitwiseAndHandler,52,2 block_count,BitwiseAndHandler,53,1 block_count,BitwiseAndHandler,54,1 @@ -64164,7 +64500,7 @@ block_count,BitwiseAndSmiHandler,36,3 block_count,BitwiseAndSmiHandler,37,3 block_count,BitwiseAndSmiHandler,38,0 -block_count,BitwiseAndSmiHandler,39,2 +block_count,BitwiseAndSmiHandler,39,3 block_count,BitwiseAndSmiHandler,40,0 block_count,BitwiseAndSmiHandler,41,3 block_count,ShiftLeftSmiHandler,0,5 @@ -64311,8 +64647,8 @@ block_count,ShiftRightLogicalSmiHandler,48,1 block_count,ShiftRightLogicalSmiHandler,49,0 block_count,ShiftRightLogicalSmiHandler,50,1 -block_count,IncHandler,0,46 -block_count,IncHandler,1,46 +block_count,IncHandler,0,47 +block_count,IncHandler,1,47 block_count,IncHandler,2,0 block_count,IncHandler,3,0 block_count,IncHandler,4,0 @@ -64329,19 +64665,19 @@ block_count,IncHandler,15,0 block_count,IncHandler,16,0 block_count,IncHandler,17,0 -block_count,IncHandler,18,46 -block_count,IncHandler,19,46 +block_count,IncHandler,18,47 +block_count,IncHandler,19,47 block_count,IncHandler,20,0 block_count,IncHandler,21,0 block_count,IncHandler,22,0 block_count,IncHandler,23,0 block_count,IncHandler,24,0 -block_count,IncHandler,25,46 -block_count,IncHandler,26,45 +block_count,IncHandler,25,47 +block_count,IncHandler,26,46 block_count,IncHandler,27,0 block_count,IncHandler,28,45 block_count,IncHandler,29,0 -block_count,IncHandler,30,46 +block_count,IncHandler,30,47 block_count,IncHandler,31,3 block_count,IncHandler,32,43 block_count,DecHandler,0,8 @@ -64704,7 +65040,7 @@ block_count,CallPropertyHandler,67,0 block_count,CallPropertyHandler,68,4 block_count,CallProperty0Handler,0,14 -block_count,CallProperty0Handler,1,12 +block_count,CallProperty0Handler,1,13 block_count,CallProperty0Handler,2,0 block_count,CallProperty0Handler,3,0 block_count,CallProperty0Handler,4,0 @@ -64773,7 +65109,7 @@ block_count,CallProperty0Handler,67,1 block_count,CallProperty0Handler,68,14 block_count,CallProperty1Handler,0,31 -block_count,CallProperty1Handler,1,26 +block_count,CallProperty1Handler,1,27 block_count,CallProperty1Handler,2,0 block_count,CallProperty1Handler,3,0 block_count,CallProperty1Handler,4,0 @@ -65183,7 +65519,7 @@ block_count,CallUndefinedReceiver2Handler,63,0 block_count,CallUndefinedReceiver2Handler,64,0 block_count,CallUndefinedReceiver2Handler,65,0 -block_count,CallUndefinedReceiver2Handler,66,4 +block_count,CallUndefinedReceiver2Handler,66,5 block_count,CallUndefinedReceiver2Handler,67,1 block_count,CallUndefinedReceiver2Handler,68,7 block_count,CallWithSpreadHandler,0,0 @@ -65361,10 +65697,10 @@ block_count,ConstructHandler,43,0 block_count,ConstructHandler,44,3 block_count,ConstructHandler,45,3 -block_count,ConstructHandler,46,7 -block_count,ConstructHandler,47,7 +block_count,ConstructHandler,46,6 +block_count,ConstructHandler,47,6 block_count,ConstructHandler,48,0 -block_count,ConstructHandler,49,7 +block_count,ConstructHandler,49,6 block_count,ConstructHandler,50,0 block_count,ConstructHandler,51,0 block_count,ConstructHandler,52,7 @@ -65445,11 +65781,11 @@ block_count,ConstructForwardAllArgsHandler,45,0 block_count,ConstructForwardAllArgsHandler,46,0 block_count,ConstructForwardAllArgsHandler,47,0 -block_count,TestEqualHandler,0,13 -block_count,TestEqualHandler,1,13 +block_count,TestEqualHandler,0,14 +block_count,TestEqualHandler,1,14 block_count,TestEqualHandler,2,11 -block_count,TestEqualHandler,3,6 -block_count,TestEqualHandler,4,6 +block_count,TestEqualHandler,3,7 +block_count,TestEqualHandler,4,7 block_count,TestEqualHandler,5,0 block_count,TestEqualHandler,6,0 block_count,TestEqualHandler,7,0 @@ -65592,12 +65928,12 @@ block_count,TestEqualHandler,144,1 block_count,TestEqualHandler,145,2 block_count,TestEqualHandler,146,4 -block_count,TestEqualHandler,147,13 -block_count,TestEqualHandler,148,12 +block_count,TestEqualHandler,147,14 +block_count,TestEqualHandler,148,13 block_count,TestEqualHandler,149,0 -block_count,TestEqualHandler,150,12 +block_count,TestEqualHandler,150,13 block_count,TestEqualHandler,151,0 -block_count,TestEqualHandler,152,13 +block_count,TestEqualHandler,152,14 block_count,TestEqualStrictHandler,0,12 block_count,TestEqualStrictHandler,1,10 block_count,TestEqualStrictHandler,2,8 @@ -65621,7 +65957,7 @@ block_count,TestEqualStrictHandler,20,0 block_count,TestEqualStrictHandler,21,0 block_count,TestEqualStrictHandler,22,0 -block_count,TestEqualStrictHandler,23,0 +block_count,TestEqualStrictHandler,23,1 block_count,TestEqualStrictHandler,24,0 block_count,TestEqualStrictHandler,25,0 block_count,TestEqualStrictHandler,26,0 @@ -66262,19 +66598,19 @@ block_count,ToNumberHandler,8,0 block_count,ToNumberHandler,9,0 block_count,ToNumberHandler,10,0 -block_count,ToNumericHandler,0,16 +block_count,ToNumericHandler,0,17 block_count,ToNumericHandler,1,0 block_count,ToNumericHandler,2,0 block_count,ToNumericHandler,3,0 block_count,ToNumericHandler,4,0 block_count,ToNumericHandler,5,0 -block_count,ToNumericHandler,6,16 -block_count,ToNumericHandler,7,16 +block_count,ToNumericHandler,6,17 +block_count,ToNumericHandler,7,17 block_count,ToNumericHandler,8,16 block_count,ToNumericHandler,9,0 block_count,ToNumericHandler,10,16 block_count,ToNumericHandler,11,0 -block_count,ToNumericHandler,12,16 +block_count,ToNumericHandler,12,17 block_count,ToObjectHandler,0,0 block_count,ToStringHandler,0,0 block_count,ToStringHandler,1,0 @@ -66433,7 +66769,7 @@ block_count,CreateObjectLiteralHandler,2,0 block_count,CreateObjectLiteralHandler,3,0 block_count,CreateObjectLiteralHandler,4,0 -block_count,CreateObjectLiteralHandler,5,0 +block_count,CreateObjectLiteralHandler,5,1 block_count,CreateObjectLiteralHandler,6,0 block_count,CreateObjectLiteralHandler,7,0 block_count,CreateObjectLiteralHandler,8,0 @@ -66632,26 +66968,26 @@ block_count,CreateClosureHandler,7,6 block_count,CreateBlockContextHandler,0,0 block_count,CreateCatchContextHandler,0,0 -block_count,CreateFunctionContextHandler,0,3 -block_count,CreateFunctionContextHandler,1,3 +block_count,CreateFunctionContextHandler,0,2 +block_count,CreateFunctionContextHandler,1,2 block_count,CreateFunctionContextHandler,2,0 -block_count,CreateFunctionContextHandler,3,3 +block_count,CreateFunctionContextHandler,3,2 block_count,CreateFunctionContextHandler,4,0 block_count,CreateFunctionContextHandler,5,0 -block_count,CreateFunctionContextHandler,6,3 +block_count,CreateFunctionContextHandler,6,2 block_count,CreateFunctionContextHandler,7,0 -block_count,CreateFunctionContextHandler,8,3 +block_count,CreateFunctionContextHandler,8,2 block_count,CreateFunctionContextHandler,9,0 -block_count,CreateFunctionContextHandler,10,3 +block_count,CreateFunctionContextHandler,10,2 block_count,CreateFunctionContextHandler,11,1 block_count,CreateFunctionContextHandler,12,1 -block_count,CreateFunctionContextHandler,13,3 -block_count,CreateFunctionContextHandler,14,2 +block_count,CreateFunctionContextHandler,13,2 +block_count,CreateFunctionContextHandler,14,1 block_count,CreateFunctionContextHandler,15,1 -block_count,CreateFunctionContextHandler,16,3 -block_count,CreateFunctionContextHandler,17,1 +block_count,CreateFunctionContextHandler,16,2 +block_count,CreateFunctionContextHandler,17,0 block_count,CreateFunctionContextHandler,18,2 -block_count,CreateFunctionContextHandler,19,3 +block_count,CreateFunctionContextHandler,19,2 block_count,CreateMappedArgumentsHandler,0,0 block_count,CreateMappedArgumentsHandler,1,0 block_count,CreateMappedArgumentsHandler,2,0 @@ -66961,7 +67297,7 @@ block_count,JumpIfToBooleanTrueHandler,22,8 block_count,JumpIfToBooleanFalseHandler,0,30 block_count,JumpIfToBooleanFalseHandler,1,15 -block_count,JumpIfToBooleanFalseHandler,2,10 +block_count,JumpIfToBooleanFalseHandler,2,11 block_count,JumpIfToBooleanFalseHandler,3,8 block_count,JumpIfToBooleanFalseHandler,4,8 block_count,JumpIfToBooleanFalseHandler,5,4 @@ -66977,16 +67313,16 @@ block_count,JumpIfToBooleanFalseHandler,15,0 block_count,JumpIfToBooleanFalseHandler,16,2 block_count,JumpIfToBooleanFalseHandler,17,4 -block_count,JumpIfToBooleanFalseHandler,18,14 +block_count,JumpIfToBooleanFalseHandler,18,15 block_count,JumpIfToBooleanFalseHandler,19,14 block_count,JumpIfToBooleanFalseHandler,20,0 -block_count,JumpIfToBooleanFalseHandler,21,21 +block_count,JumpIfToBooleanFalseHandler,21,22 block_count,JumpIfToBooleanFalseHandler,22,8 block_count,JumpIfTrueHandler,0,13 block_count,JumpIfTrueHandler,1,9 block_count,JumpIfTrueHandler,2,3 block_count,JumpIfFalseHandler,0,69 -block_count,JumpIfFalseHandler,1,43 +block_count,JumpIfFalseHandler,1,44 block_count,JumpIfFalseHandler,2,25 block_count,JumpIfNullHandler,0,0 block_count,JumpIfNullHandler,1,0 @@ -67093,7 +67429,7 @@ block_count,ReThrowHandler,0,0 block_count,ReturnHandler,0,44 block_count,ReturnHandler,1,0 -block_count,ReturnHandler,2,43 +block_count,ReturnHandler,2,44 block_count,ThrowReferenceErrorIfHoleHandler,0,1 block_count,ThrowReferenceErrorIfHoleHandler,1,1 block_count,ThrowReferenceErrorIfHoleHandler,2,0