| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "third_party/blink/renderer/core/layout/layout_font_accessor_win.h" |
| |
| #include "third_party/blink/renderer/core/frame/local_frame.h" |
| #include "third_party/blink/renderer/core/layout/inline/fragment_item.h" |
| #include "third_party/blink/renderer/core/layout/inline/inline_cursor.h" |
| #include "third_party/blink/renderer/core/layout/layout_block_flow.h" |
| #include "third_party/blink/renderer/core/layout/layout_box.h" |
| #include "third_party/blink/renderer/core/layout/layout_object.h" |
| #include "third_party/blink/renderer/core/layout/layout_view.h" |
| #include "third_party/blink/renderer/core/layout/physical_box_fragment.h" |
| #include "third_party/blink/renderer/core/layout/physical_fragment_link.h" |
| #include "third_party/blink/renderer/platform/fonts/font_platform_data.h" |
| #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" |
| #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" |
| #include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| void GetFontsUsedByLayoutObject(const LayoutObject& layout_object, |
| FontFamilyNames& result); |
| |
| void GetFontsUsedByFragment(const PhysicalBoxFragment& fragment, |
| FontFamilyNames& result) { |
| for (InlineCursor cursor(fragment); cursor; cursor.MoveToNext()) { |
| const FragmentItem& item = *cursor.Current().Item(); |
| if (item.IsText()) { |
| const ShapeResultView* shape_result_view = item.TextShapeResult(); |
| if (shape_result_view) { |
| const String font_family = |
| shape_result_view->PrimaryFont()->PlatformData().FontFamilyName(); |
| if (!font_family.empty()) |
| result.font_names.insert(font_family); |
| HeapHashSet<Member<const SimpleFontData>> fallback_font_data; |
| ClearCollectionScope clear_scope(&fallback_font_data); |
| shape_result_view->FallbackFonts(&fallback_font_data); |
| for (const SimpleFontData* font_data : fallback_font_data) { |
| result.font_names.insert(font_data->PlatformData().FontFamilyName()); |
| } |
| } |
| continue; |
| } |
| |
| // If this is a nested BFC (e.g., inline block, floats), compute its area. |
| if (item.Type() == FragmentItem::kBox) { |
| if (const auto* layout_box = DynamicTo<LayoutBox>(item.GetLayoutObject())) |
| GetFontsUsedByLayoutObject(*layout_box, result); |
| } |
| } |
| |
| // Traverse out-of-flow children. They are not in |FragmentItems|. |
| for (const PhysicalFragmentLink& child : fragment.Children()) { |
| if (const auto* child_layout_box = |
| DynamicTo<LayoutBox>(child->GetLayoutObject())) |
| GetFontsUsedByLayoutObject(*child_layout_box, result); |
| } |
| } |
| |
| void GetFontsUsedByLayoutObject(const LayoutObject& layout_object, |
| FontFamilyNames& result) { |
| const LayoutObject* target = &layout_object; |
| while (target) { |
| // Use |InlineCursor| to traverse if |target| is an IFC. |
| if (const auto* block_flow = DynamicTo<LayoutBlockFlow>(target)) { |
| if (block_flow->HasFragmentItems()) { |
| for (const PhysicalBoxFragment& fragment : |
| block_flow->PhysicalFragments()) { |
| GetFontsUsedByFragment(fragment, result); |
| } |
| target = target->NextInPreOrderAfterChildren(&layout_object); |
| continue; |
| } |
| } |
| target = target->NextInPreOrder(&layout_object); |
| } |
| } |
| |
| } // namespace |
| |
| void GetFontsUsedByFrame(const LocalFrame& frame, FontFamilyNames& result) { |
| GetFontsUsedByLayoutObject(frame.ContentLayoutObject()->RootBox(), result); |
| } |
| |
| } // namespace blink |