| /* | |
| * Copyright 2026 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/core/SkStrikeRef.h" | |
| #include "include/core/SkRect.h" | |
| #include "include/private/SkTemplates.h" | |
| #include "include/private/SkTo.h" | |
| #include "src/core/SkGlyph.h" | |
| #include "src/core/SkStrike.h" | |
| #include "src/core/SkZip.h" | |
| #include <algorithm> | |
| using namespace skia_private; | |
| namespace { | |
| constexpr SkRect scale_rect(SkRect r, SkScalar s) { | |
| return {r.fLeft * s, r.fTop * s, r.fRight * s, r.fBottom * s}; | |
| } | |
| } // namespace | |
| SkStrikeRef::SkStrikeRef() = default; | |
| SkStrikeRef::~SkStrikeRef() = default; | |
| SkStrikeRef::SkStrikeRef(const SkStrikeRef&) = default; | |
| SkStrikeRef& SkStrikeRef::operator=(const SkStrikeRef&) = default; | |
| SkStrikeRef::SkStrikeRef(SkStrikeRef&&) = default; | |
| SkStrikeRef& SkStrikeRef::operator=(SkStrikeRef&&) = default; | |
| SkStrikeRef::SkStrikeRef(sk_sp<SkStrike> strike, | |
| SkScalar strikeToSourceScale) | |
| : fStrike(std::move(strike)) | |
| , fStrikeToSourceScale(strikeToSourceScale) {} | |
| void SkStrikeRef::getWidths(SkSpan<const SkGlyphID> glyphs, SkSpan<SkScalar> widths) const { | |
| this->getWidthsBounds(glyphs, widths, {}); | |
| } | |
| SkScalar SkStrikeRef::getWidth(SkGlyphID glyph) const { | |
| SkScalar width; | |
| this->getWidths({&glyph, 1}, {&width, 1}); | |
| return width; | |
| } | |
| void SkStrikeRef::getWidthsBounds(SkSpan<const SkGlyphID> glyphs, | |
| SkSpan<SkScalar> widths, | |
| SkSpan<SkRect> bounds) const { | |
| SkASSERT(fStrike); | |
| AutoSTArray<64, const SkGlyph*> glyphPtrs(SkTo<int>(glyphs.size())); | |
| SkSpan<const SkGlyph*> results = fStrike->metrics(glyphs, glyphPtrs.get()); | |
| if (bounds.size()) { | |
| const auto n = std::min(bounds.size(), results.size()); | |
| for (auto [bound, glyph] : SkMakeZip(bounds.first(n), results.first(n))) { | |
| bound = scale_rect(glyph->rect(), fStrikeToSourceScale); | |
| } | |
| } | |
| if (widths.size()) { | |
| const auto n = std::min(widths.size(), results.size()); | |
| for (auto [width, glyph] : SkMakeZip(widths.first(n), results.first(n))) { | |
| width = glyph->advanceX() * fStrikeToSourceScale; | |
| } | |
| } | |
| } | |
| void SkStrikeRef::getWidthsStrided(unsigned count, | |
| const uint32_t* first_glyph, | |
| unsigned glyph_stride_32, | |
| SkScalar* first_advance, | |
| unsigned advance_stride_32) const { | |
| SkASSERT(fStrike); | |
| fStrike->getWidthsStrided(count, first_glyph, glyph_stride_32, first_advance, | |
| advance_stride_32, fStrikeToSourceScale); | |
| } |