Source/WebCore/platform/graphics/Font.cpp

@@RefPtr<Font> Font::createScaledFont(const FontDescription& fontDescription, floa
541541 return platformCreateScaledFont(fontDescription, scaleFactor);
542542}
543543
544 #if !USE(CORE_TEXT)
 544#if USE(HARFBUZZ)
545545GlyphBufferAdvance Font::applyTransforms(GlyphBuffer&, unsigned, unsigned, bool, bool, const AtomString&, StringView, TextDirection) const
546546{
547547 return makeGlyphBufferAdvance();

Source/WebCore/platform/graphics/Font.h

@@public:
206206#endif
207207
208208 bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
209  GlyphBufferAdvance applyTransforms(GlyphBuffer&, unsigned beginningGlyphIndex, unsigned beginningStringIndex, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection) const;
 209 GlyphBufferAdvance applyTransforms(GlyphBuffer&, unsigned beginningGlyphIndex, unsigned beginningStringIndex, unsigned stringLength, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection) const;
210210
211211 // Returns nullopt if none of the glyphs are OT-SVG glyphs.
212212 std::optional<BitVector> findOTSVGGlyphs(const GlyphBufferGlyph*, unsigned count) const;

Source/WebCore/platform/graphics/FontCascade.cpp

@@float FontCascade::widthForSimpleText(StringView text, TextDirection textDirecti
321321 glyphBuffer.add(glyph, font, glyphWidth, i);
322322 }
323323
324  auto initialAdvance = font.applyTransforms(glyphBuffer, 0, 0, enableKerning(), requiresShaping(), fontDescription().computedLocale(), text, textDirection);
 324 auto initialAdvance = font.applyTransforms(glyphBuffer, 0, 0, text.length(), enableKerning(), requiresShaping(), fontDescription().computedLocale(), text, textDirection);
325325 // This is needed only to match the result of the slow path.
326326 // Same glyph widths but different floating point arithmetic can produce different run width.
327327 float runWidthDifferenceWithTransformApplied = -runWidth;

Source/WebCore/platform/graphics/WidthIterator.cpp

@@static inline bool isSoftBankEmoji(UChar32 codepoint)
8080 return codepoint >= 0xE001 && codepoint <= 0xE537;
8181}
8282
83 inline auto WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, unsigned lastGlyphCount, const Font& font, CharactersTreatedAsSpace& charactersTreatedAsSpace) -> ApplyFontTransformsResult
 83inline auto WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, unsigned lastGlyphCount, unsigned stringLength, const Font& font, CharactersTreatedAsSpace& charactersTreatedAsSpace) -> ApplyFontTransformsResult
8484{
8585 auto glyphBufferSize = glyphBuffer.size();
8686 ASSERT(lastGlyphCount <= glyphBufferSize);

@@inline auto WidthIterator::applyFontTransforms(GlyphBuffer& glyphBuffer, unsigne
9292 for (unsigned i = lastGlyphCount; i < glyphBufferSize; ++i)
9393 beforeWidth += width(advances[i]);
9494
95  auto initialAdvance = font.applyTransforms(glyphBuffer, lastGlyphCount, m_currentCharacterIndex, m_enableKerning, m_requiresShaping, m_font.fontDescription().computedLocale(), m_run.text(), m_run.direction());
 95 auto initialAdvance = font.applyTransforms(glyphBuffer, lastGlyphCount, m_currentCharacterIndex, stringLength,
 96 m_enableKerning, m_requiresShaping, m_font.fontDescription().computedLocale(), m_run.text(), m_run.direction());
9697
9798#if USE(CTFONTSHAPEGLYPHS_WORKAROUND)
9899 // <rdar://problem/80798113>: If a character is not in BMP, and we don't have a glyph for it,

@@void WidthIterator::commitCurrentFontRange(GlyphBuffer& glyphBuffer, unsigned& l
215216 ASSERT(&glyphBuffer.fontAt(i) == font);
216217#endif
217218
218  auto applyFontTransformsResult = applyFontTransforms(glyphBuffer, lastGlyphCount, *font, charactersTreatedAsSpace);
 219 auto applyFontTransformsResult = applyFontTransforms(glyphBuffer, lastGlyphCount, currentCharacterIndex - m_currentCharacterIndex, *font, charactersTreatedAsSpace);
219220 m_runWidthSoFar += applyFontTransformsResult.additionalAdvance;
220221 applyInitialAdvance(glyphBuffer, applyFontTransformsResult.initialAdvance, lastGlyphCount);
221222 m_currentCharacterIndex = currentCharacterIndex;

Source/WebCore/platform/graphics/WidthIterator.h

@@private:
6767 float additionalAdvance;
6868 GlyphBufferAdvance initialAdvance;
6969 };
70  ApplyFontTransformsResult applyFontTransforms(GlyphBuffer&, unsigned lastGlyphCount, const Font&, CharactersTreatedAsSpace&);
 70 ApplyFontTransformsResult applyFontTransforms(GlyphBuffer&, unsigned lastGlyphCount, unsigned stringLength, const Font&, CharactersTreatedAsSpace&);
7171 void commitCurrentFontRange(GlyphBuffer&, unsigned& lastGlyphCount, unsigned currentCharacterIndex, const Font*&, const Font& newFont, const Font& primaryFont, UChar32 character, float& widthOfCurrentFontRange, float nextCharacterWidth, CharactersTreatedAsSpace&);
7272 void applyInitialAdvance(GlyphBuffer&, GlyphBufferAdvance initialAdvance, unsigned lastGlyphCount);
7373

Source/WebCore/platform/graphics/win/ComplexTextControllerUniscribe.cpp

@@void ComplexTextController::collectComplexTextRunsForCharacters(const UChar* cp,
274274 }
275275}
276276
 277GlyphBufferAdvance Font::applyTransforms(GlyphBuffer& glyphBuffer, unsigned beginningGlyphIndex, unsigned beginningStringIndex, unsigned stringLength, bool enableKerning, bool requiresShaping, const AtomString& locale, StringView text, TextDirection textDirection) const
 278{
 279 glyphBuffer.remove(beginningGlyphIndex, glyphBuffer.size() - beginningGlyphIndex);
 280
 281 auto substring = text.substring(beginningStringIndex, stringLength);
 282 auto upconvertedCharacters = substring.upconvertedCharacters();
 283
 284 Vector<SCRIPT_ITEM> items(6);
 285 int numItems = 0;
 286 for (;;) {
 287 SCRIPT_CONTROL control { };
 288 SCRIPT_STATE state { };
 289 control.fMergeNeutralItems = true;
 290 // Set up the correct direction for the run.
 291 state.uBidiLevel = textDirection == TextDirection::RTL;
 292 // Lock the correct directional override.
 293 // state.fOverrideDirection = ?
 294
 295 // ScriptItemize may write (cMaxItems + 1) SCRIPT_ITEM.
 296 HRESULT hr = ScriptItemize(wcharFrom(upconvertedCharacters.get()), stringLength, items.size() - 1, &control, &state, items.data(), &numItems);
 297 if (hr != E_OUTOFMEMORY) {
 298 ASSERT(SUCCEEDED(hr));
 299 break;
 300 }
 301 items.resize(items.size() * 2);
 302 }
 303 items.resize(numItems + 1);
 304
 305 for (int i = 0; i < numItems; i++) {
 306 // Determine the string for this item.
 307 const UChar* str = upconvertedCharacters.get() + items[i].iCharPos;
 308 int length = items[i+1].iCharPos - items[i].iCharPos;
 309 SCRIPT_ITEM& item = items[i];
 310
 311 // Set up buffers to hold the results of shaping the item.
 312 Vector<WORD> glyphs;
 313 Vector<WORD> clusters;
 314 Vector<SCRIPT_VISATTR> visualAttributes;
 315 clusters.resize(length);
 316
 317 // Shape the item.
 318 // The recommended size for the glyph buffer is 1.5 * the character length + 16 in the uniscribe docs.
 319 // Apparently this is a good size to avoid having to make repeated calls to ScriptShape.
 320 glyphs.resize(1.5 * length + 16);
 321 visualAttributes.resize(glyphs.size());
 322
 323 if (!shapeByUniscribe(str, length, item, this, glyphs, clusters, visualAttributes))
 324 continue;
 325
 326 // We now have a collection of glyphs.
 327 Vector<GOFFSET> offsets;
 328 Vector<int> advances;
 329 offsets.resize(glyphs.size());
 330 advances.resize(glyphs.size());
 331 HRESULT placeResult = ScriptPlace(0, scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
 332 &item.a, advances.data(), offsets.data(), 0);
 333 if (placeResult == E_PENDING) {
 334 // The script cache isn't primed with enough info yet. We need to select our HFONT into
 335 // a DC and pass the DC in to ScriptPlace.
 336 HWndDC hdc(0);
 337 HFONT hfont = platformData().hfont();
 338 HGDIOBJ oldFont = SelectObject(hdc, hfont);
 339 placeResult = ScriptPlace(hdc, scriptCache(), glyphs.data(), glyphs.size(), visualAttributes.data(),
 340 &item.a, advances.data(), offsets.data(), 0);
 341 SelectObject(hdc, oldFont);
 342 }
 343
 344 if (FAILED(placeResult) || glyphs.isEmpty())
 345 continue;
 346
 347 bool ltr = !item.a.fRTL;
 348 auto stringIndices = stringIndicesFromClusters(clusters, StringView(str, length), beginningStringIndex + item.iCharPos, glyphs.size(), ltr);
 349
 350 for (unsigned k = 0; k < glyphs.size(); k++) {
 351 const float cLogicalScale = platformData().useGDI() ? 1 : 32;
 352 float advance = advances[k] / cLogicalScale;
 353 float offsetX = offsets[k].du / cLogicalScale;
 354 float offsetY = offsets[k].dv / cLogicalScale;
 355
 356 // Match AppKit's rules for the integer vs. non-integer rendering modes.
 357 if (!platformData().isSystemFont()) {
 358 advance = roundf(advance);
 359 offsetX = roundf(offsetX);
 360 offsetY = roundf(offsetY);
 361 }
 362
 363 glyphBuffer.add(glyphs[k], *this, { advance, 0 }, stringIndices[k]);
 364 glyphBuffer.origins(k)[0] = makeGlyphBufferOrigin(offsetX, offsetY);
 365 }
 366 }
 367 return makeGlyphBufferAdvance();
 368}
 369
277370}
278371
279372#endif // !USE(DIRECT2D)