2104 {
2105
2107
2108 FT_StreamRec streamRec;
2109 SkUniqueFTFace face(this->openFace(
stream, (instanceIndex << 16) + faceIndex, &streamRec));
2110 if (!face) {
2111 return false;
2112 }
2113
2117 if (face->style_flags & FT_STYLE_FLAG_BOLD) {
2119 }
2120 if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
2122 }
2123
2124 bool hasAxes = face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
2125 TT_OS2* os2 = static_cast<TT_OS2*>(FT_Get_Sfnt_Table(face.get(), ft_sfnt_os2));
2126 bool hasOs2 = os2 && os2->version != 0xffff;
2127
2128 PS_FontInfoRec psFontInfo;
2129
2130 if (hasOs2) {
2131 weight = os2->usWeightClass;
2132 width = os2->usWidthClass;
2133
2134
2135 if (
SkToBool(os2->fsSelection & (1u << 9))) {
2137 }
2138 }
2139
2140
2141 if (hasAxes) {
2143 if (
GetAxes(face.get(), &axisDefinitions)) {
2144 size_t numAxes = axisDefinitions.size();
2148 std::optional<size_t> wghtIndex;
2149 std::optional<size_t> wdthIndex;
2150 std::optional<size_t> slntIndex;
2151 for(
size_t i = 0;
i < numAxes; ++
i) {
2152 if (axisDefinitions[
i].fTag == wghtTag) {
2153
2154 SkScalar wghtRange = axisDefinitions[
i].fMaximum - axisDefinitions[
i].fMinimum;
2155 if (wghtRange > 5 && wghtRange <= 1000 && axisDefinitions[
i].fMaximum <= 1000) {
2157 }
2158 }
2159 if (axisDefinitions[
i].fTag == wdthTag) {
2160
2161 SkScalar wdthRange = axisDefinitions[
i].fMaximum - axisDefinitions[
i].fMinimum;
2162 if (wdthRange > 0 && wdthRange <= 500 && axisDefinitions[
i].fMaximum <= 500) {
2164 }
2165 }
2166 if (axisDefinitions[
i].fTag == slntTag) {
2168 }
2169 }
2171 if ((wghtIndex || wdthIndex || slntIndex) &&
2172 !FT_Get_Var_Design_Coordinates(face.get(), numAxes, coords.get())) {
2173 if (wghtIndex) {
2176 }
2177 if (wdthIndex) {
2181 }
2182 if (slntIndex) {
2184
2185
2186
2187
2190 }
2191 }
2192 }
2193 }
2194 }
2195
2196 if (!hasOs2 && !hasAxes && 0 == FT_Get_PS_Font_Info(face.get(), &psFontInfo) && psFontInfo.weight) {
2197 static const struct {
2198 char const *
const name;
2199 int const weight;
2200 } commonWeights [] = {
2201
2227 };
2229 psFontInfo.weight, sizeof(commonWeights[0]));
2230 if (index >= 0) {
2231 weight = commonWeights[index].weight;
2232 } else {
2233 LOG_INFO(
"Do not know weight for: %s (%s) \n", face->family_name, psFontInfo.weight);
2234 }
2235 }
2236
2237 if (
name !=
nullptr) {
2238 name->set(face->family_name);
2239 }
2240 if (style != nullptr) {
2242 }
2243 if (isFixedPitch != nullptr) {
2244 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
2245 }
2246
2247 if (axes !=
nullptr && !
GetAxes(face.get(), axes)) {
2248 return false;
2249 }
2250 return true;
2251}
int SkStrLCSearch(const char *const *base, int count, const char target[], size_t len, size_t elemSize)
static constexpr bool SkToBool(const T &x)
static bool GetAxes(FT_Face face, AxisDefinitions *axes)
skia_private::STArray< 4, AxisDefinition, true > AxisDefinitions
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size