Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
nine_patch_converter.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <vector>
6
8
9namespace impeller {
10
12
14
15std::vector<double> NinePatchConverter::InitSlices(double img0,
16 double imgC0,
17 double imgC1,
18 double img1,
19 double dst0,
20 double dst1) {
21 auto imageDim = img1 - img0;
22 auto destDim = dst1 - dst0;
23
24 if (imageDim == destDim) {
25 // If the src and dest are the same size then we do not need scaling
26 // We return 4 values for a single slice
27 return {img0, dst0, img1, dst1};
28 }
29
30 auto edge0Dim = imgC0 - img0;
31 auto edge1Dim = img1 - imgC1;
32 auto edgesDim = edge0Dim + edge1Dim;
33
34 if (edgesDim >= destDim) {
35 // the center portion has disappeared, leaving only the edges to scale to a
36 // common center position in the destination this produces only 2 slices
37 // which is 8 values
38 auto dstC = dst0 + destDim * edge0Dim / edgesDim;
39 // clang-format off
40 return {
41 img0, dst0, imgC0, dstC,
42 imgC1, dstC, img1, dst1,
43 };
44 // clang-format on
45 }
46
47 // center portion is nonEmpty and only that part is scaled
48 // we need 3 slices which is 12 values
49 auto dstC0 = dst0 + edge0Dim;
50 auto dstC1 = dst1 - edge1Dim;
51 // clang-format off
52 return {
53 img0, dst0, imgC0, dstC0,
54 imgC0, dstC0, imgC1, dstC1,
55 imgC1, dstC1, img1, dst1,
56 };
57 // clang-format on
58}
59
60void NinePatchConverter::DrawNinePatch(const std::shared_ptr<Image>& image,
62 Rect dst,
63 const SamplerDescriptor& sampler,
64 CanvasType* canvas,
65 Paint* paint) {
66 if (dst.IsEmpty()) {
67 return;
68 }
69 auto image_size = image->GetSize();
70 auto hSlices = InitSlices(0, center.GetLeft(), center.GetRight(),
71 image_size.width, dst.GetLeft(), dst.GetRight());
72 auto vSlices = InitSlices(0, center.GetTop(), center.GetBottom(),
73 image_size.height, dst.GetTop(), dst.GetBottom());
74
75 for (size_t yi = 0; yi < vSlices.size(); yi += 4) {
76 auto srcY0 = vSlices[yi];
77 auto dstY0 = vSlices[yi + 1];
78 auto srcY1 = vSlices[yi + 2];
79 auto dstY1 = vSlices[yi + 3];
80 for (size_t xi = 0; xi < hSlices.size(); xi += 4) {
81 auto srcX0 = hSlices[xi];
82 auto dstX0 = hSlices[xi + 1];
83 auto srcX1 = hSlices[xi + 2];
84 auto dstX1 = hSlices[xi + 3];
85 // TODO(jonahwilliams): consider converting this into a single call to
86 // DrawImageAtlas.
87 canvas->DrawImageRect(image, Rect::MakeLTRB(srcX0, srcY0, srcX1, srcY1),
88 Rect::MakeLTRB(dstX0, dstY0, dstX1, dstY1), *paint,
90 }
91 }
92}
93
94} // namespace impeller
static SkScalar center(float pos0, float pos1)
void DrawImageRect(const std::shared_ptr< Image > &image, Rect source, Rect dest, const Paint &paint, SamplerDescriptor sampler={}, SourceRectConstraint src_rect_constraint=SourceRectConstraint::kFast)
Definition canvas.cc:764
void DrawNinePatch(const std::shared_ptr< Image > &image, Rect center, Rect dst, const SamplerDescriptor &sampler, CanvasType *canvas, Paint *paint)
const Paint & paint
sk_sp< SkImage > image
Definition examples.cpp:29
@ kStrict
Sample only within the source rectangle. May be slower.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129