• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "MinikinUtils.h"
18 
19 #include <string>
20 
21 #include <log/log.h>
22 
23 #include <minikin/MeasuredText.h>
24 #include <minikin/Measurement.h>
25 #include "Paint.h"
26 #include "SkPathMeasure.h"
27 #include "Typeface.h"
28 
29 namespace android {
30 
prepareMinikinPaint(const Paint * paint,const Typeface * typeface)31 minikin::MinikinPaint MinikinUtils::prepareMinikinPaint(const Paint* paint,
32                                                         const Typeface* typeface) {
33     const Typeface* resolvedFace = Typeface::resolveDefault(typeface);
34     const SkFont& font = paint->getSkFont();
35 
36     minikin::MinikinPaint minikinPaint(resolvedFace->fFontCollection);
37     /* Prepare minikin Paint */
38     minikinPaint.size =
39             font.isLinearMetrics() ? font.getSize() : static_cast<int>(font.getSize());
40     minikinPaint.scaleX = font.getScaleX();
41     minikinPaint.skewX = font.getSkewX();
42     minikinPaint.letterSpacing = paint->getLetterSpacing();
43     minikinPaint.wordSpacing = paint->getWordSpacing();
44     minikinPaint.fontFlags = MinikinFontSkia::packFontFlags(font);
45     minikinPaint.localeListId = paint->getMinikinLocaleListId();
46     minikinPaint.familyVariant = paint->getFamilyVariant();
47     minikinPaint.fontStyle = resolvedFace->fStyle;
48     minikinPaint.fontFeatureSettings = paint->getFontFeatureSettings();
49     return minikinPaint;
50 }
51 
doLayout(const Paint * paint,minikin::Bidi bidiFlags,const Typeface * typeface,const uint16_t * buf,size_t bufSize,size_t start,size_t count,size_t contextStart,size_t contextCount,minikin::MeasuredText * mt)52 minikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFlags,
53                                        const Typeface* typeface, const uint16_t* buf,
54                                        size_t bufSize, size_t start, size_t count,
55                                        size_t contextStart, size_t contextCount,
56                                        minikin::MeasuredText* mt) {
57     minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
58 
59     const minikin::U16StringPiece textBuf(buf, bufSize);
60     const minikin::Range range(start, start + count);
61     const minikin::Range contextRange(contextStart, contextStart + contextCount);
62     const minikin::StartHyphenEdit startHyphen = paint->getStartHyphenEdit();
63     const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
64 
65     if (mt == nullptr) {
66         return minikin::Layout(textBuf.substr(contextRange), range - contextStart, bidiFlags,
67                                minikinPaint, startHyphen, endHyphen);
68     } else {
69         return mt->buildLayout(textBuf, range, contextRange, minikinPaint, startHyphen, endHyphen);
70     }
71 }
72 
getBounds(const Paint * paint,minikin::Bidi bidiFlags,const Typeface * typeface,const uint16_t * buf,size_t bufSize,minikin::MinikinRect * out)73 void MinikinUtils::getBounds(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface,
74                              const uint16_t* buf, size_t bufSize, minikin::MinikinRect* out) {
75     minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
76 
77     const minikin::U16StringPiece textBuf(buf, bufSize);
78     const minikin::StartHyphenEdit startHyphen = paint->getStartHyphenEdit();
79     const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
80 
81     minikin::getBounds(textBuf, minikin::Range(0, textBuf.size()), bidiFlags, minikinPaint,
82         startHyphen, endHyphen, out);
83 }
84 
measureText(const Paint * paint,minikin::Bidi bidiFlags,const Typeface * typeface,const uint16_t * buf,size_t start,size_t count,size_t bufSize,float * advances)85 float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags,
86                                 const Typeface* typeface, const uint16_t* buf, size_t start,
87                                 size_t count, size_t bufSize, float* advances) {
88     minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
89     const minikin::U16StringPiece textBuf(buf, bufSize);
90     const minikin::Range range(start, start + count);
91     const minikin::StartHyphenEdit startHyphen = paint->getStartHyphenEdit();
92     const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
93 
94     return minikin::Layout::measureText(textBuf, range, bidiFlags, minikinPaint, startHyphen,
95                                         endHyphen, advances);
96 }
97 
getFontExtent(const Paint * paint,minikin::Bidi bidiFlags,const Typeface * typeface,const uint16_t * buf,size_t start,size_t count,size_t bufSize)98 minikin::MinikinExtent MinikinUtils::getFontExtent(const Paint* paint, minikin::Bidi bidiFlags,
99                                                    const Typeface* typeface, const uint16_t* buf,
100                                                    size_t start, size_t count, size_t bufSize) {
101     minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
102     const minikin::U16StringPiece textBuf(buf, bufSize);
103     const minikin::Range range(start, start + count);
104 
105     return minikin::getFontExtent(textBuf, range, bidiFlags, minikinPaint);
106 }
107 
hasVariationSelector(const Typeface * typeface,uint32_t codepoint,uint32_t vs)108 bool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) {
109     const Typeface* resolvedFace = Typeface::resolveDefault(typeface);
110     return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs);
111 }
112 
xOffsetForTextAlign(Paint * paint,const minikin::Layout & layout)113 float MinikinUtils::xOffsetForTextAlign(Paint* paint, const minikin::Layout& layout) {
114     switch (paint->getTextAlign()) {
115         case Paint::kCenter_Align:
116             return layout.getAdvance() * -0.5f;
117             break;
118         case Paint::kRight_Align:
119             return -layout.getAdvance();
120             break;
121         default:
122             break;
123     }
124     return 0;
125 }
126 
hOffsetForTextAlign(Paint * paint,const minikin::Layout & layout,const SkPath & path)127 float MinikinUtils::hOffsetForTextAlign(Paint* paint, const minikin::Layout& layout,
128                                         const SkPath& path) {
129     float align = 0;
130     switch (paint->getTextAlign()) {
131         case Paint::kCenter_Align:
132             align = -0.5f;
133             break;
134         case Paint::kRight_Align:
135             align = -1;
136             break;
137         default:
138             return 0;
139     }
140     SkPathMeasure measure(path, false);
141     return align * (layout.getAdvance() - measure.getLength());
142 }
143 }  // namespace android
144