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) {
2156 wghtIndex = i;
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) {
2163 wdthIndex = i;
2164 }
2165 }
2166 if (axisDefinitions[i].fTag == slntTag) {
2167 slntIndex = i;
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 };
2228 int const index =
SkStrLCSearch(&commonWeights[0].
name, std::size(commonWeights),
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