xref: /aosp_15_r20/frameworks/base/libs/hwui/hwui/MinikinUtils.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /**
18  * Utilities for making Minikin work, especially from existing objects like
19  * Paint and so on.
20  **/
21 
22 // TODO: does this really need to be separate from MinikinSkia?
23 
24 #ifndef _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
25 #define _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
26 
27 #include <cutils/compiler.h>
28 #include <log/log.h>
29 #include <minikin/Layout.h>
30 
31 #include "FeatureFlags.h"
32 #include "MinikinSkia.h"
33 #include "Paint.h"
34 #include "Typeface.h"
35 
36 namespace minikin {
37 class MeasuredText;
38 }  // namespace minikin
39 
40 namespace android {
41 
42 class MinikinUtils {
43 public:
44     static minikin::MinikinPaint prepareMinikinPaint(const Paint* paint,
45                                                                  const Typeface* typeface);
46 
47     static minikin::Layout doLayout(const Paint* paint, minikin::Bidi bidiFlags,
48                                                 const Typeface* typeface, const uint16_t* buf,
49                                                 size_t bufSize, size_t start, size_t count,
50                                                 size_t contextStart, size_t contextCount,
51                                                 minikin::MeasuredText* mt);
52 
53     static void getBounds(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface,
54                           const uint16_t* buf, size_t bufSize, minikin::MinikinRect* out);
55 
56     static float measureText(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface,
57                              const uint16_t* buf, size_t start, size_t count, size_t bufSize,
58                              float* advances, minikin::MinikinRect* bounds, uint32_t* clusterCount);
59 
60     static minikin::MinikinExtent getFontExtent(const Paint* paint, minikin::Bidi bidiFlags,
61                                                 const Typeface* typeface, const uint16_t* buf,
62                                                 size_t start, size_t count, size_t bufSize);
63 
64     static bool hasVariationSelector(const Typeface* typeface, uint32_t codepoint,
65                                                  uint32_t vs);
66 
67     static float xOffsetForTextAlign(Paint* paint, const minikin::Layout& layout);
68 
69     static float hOffsetForTextAlign(Paint* paint, const minikin::Layout& layout,
70                                                  const SkPath& path);
71     // f is a functor of type void f(size_t start, size_t end);
72     template <typename F>
forFontRun(const minikin::Layout & layout,Paint * paint,F & f)73     static void forFontRun(const minikin::Layout& layout, Paint* paint, F& f) {
74         float saveSkewX = paint->getSkFont().getSkewX();
75         bool savefakeBold = paint->getSkFont().isEmbolden();
76         if (text_feature::typeface_redesign_readonly()) {
77             for (uint32_t runIdx = 0; runIdx < layout.getFontRunCount(); ++runIdx) {
78                 uint32_t start = layout.getFontRunStart(runIdx);
79                 uint32_t end = layout.getFontRunEnd(runIdx);
80                 const minikin::FakedFont& fakedFont = layout.getFontRunFont(runIdx);
81 
82                 std::shared_ptr<minikin::MinikinFont> font = fakedFont.typeface();
83                 SkFont* skfont = &paint->getSkFont();
84                 MinikinFontSkia::populateSkFont(skfont, font.get(), fakedFont.fakery);
85                 f(start, end);
86                 skfont->setSkewX(saveSkewX);
87                 skfont->setEmbolden(savefakeBold);
88             }
89         } else {
90             const minikin::MinikinFont* curFont = nullptr;
91             size_t start = 0;
92             size_t nGlyphs = layout.nGlyphs();
93             for (size_t i = 0; i < nGlyphs; i++) {
94                 const minikin::MinikinFont* nextFont = layout.typeface(i).get();
95                 if (i > 0 && nextFont != curFont) {
96                     SkFont* skfont = &paint->getSkFont();
97                     MinikinFontSkia::populateSkFont(skfont, curFont, layout.getFakery(start));
98                     f(start, i);
99                     skfont->setSkewX(saveSkewX);
100                     skfont->setEmbolden(savefakeBold);
101                     start = i;
102                 }
103                 curFont = nextFont;
104             }
105             if (nGlyphs > start) {
106                 SkFont* skfont = &paint->getSkFont();
107                 MinikinFontSkia::populateSkFont(skfont, curFont, layout.getFakery(start));
108                 f(start, nGlyphs);
109                 skfont->setSkewX(saveSkewX);
110                 skfont->setEmbolden(savefakeBold);
111             }
112         }
113     }
114 };
115 
116 }  // namespace android
117 
118 #endif  // _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
119