Open Bug 2009367 Opened 7 months ago Updated 7 months ago

Italic correction should be taken into account for operators built via a glyph assembly

Categories

(Core :: MathML, enhancement)

enhancement

Tracking

()

People

(Reporter: fwang, Unassigned)

References

(Blocks 1 open bug)

Details

Follow-up of bug 2008690.

See NonNull Italic Correction (GlyphAssembly) at https://wpt.fyi/results/mathml/presentation-markup/scripts/subsup-parameters-2.html

For the record, a quick attempt that failed to make the WPT test pass. I haven't had time to debug in details.

diff --git a/gfx/thebes/gfxMathTable.cpp b/gfx/thebes/gfxMathTable.cpp
index a4e5c35d68cb..b1a9b8602a8e 100644
--- a/gfx/thebes/gfxMathTable.cpp
+++ b/gfx/thebes/gfxMathTable.cpp
@@ -75,10 +75,18 @@ bool gfxMathTable::VariantsParts(uint32_t aGlyphID, bool aVertical, bool aRTL,
   return mMathVariantCache.arePartsValid;
 }
 
+gfxFloat gfxMathTable::ItalicCorrectionForGlyphAssembly(uint32_t aGlyphID,
+                                                        bool aVertical,
+                                                        bool aRTL) const {
+  UpdateMathVariantCache(aGlyphID, aVertical, aRTL);
+  return mMathVariantCache.glyphAssemblyItalicCorrection;
+}
+
 void gfxMathTable::ClearCache() const {
   memset(mMathVariantCache.sizes, 0, sizeof(mMathVariantCache.sizes));
   memset(mMathVariantCache.parts, 0, sizeof(mMathVariantCache.parts));
   mMathVariantCache.arePartsValid = false;
+  mMathVariantCache.glyphAssemblyItalicCorrection = 0;
 }
 
 void gfxMathTable::UpdateMathVariantCache(uint32_t aGlyphID, bool aVertical,
@@ -124,8 +132,10 @@ void gfxMathTable::UpdateMathVariantCache(uint32_t aGlyphID, bool aVertical,
   hb_ot_math_glyph_part_t parts[5];
   count = std::size(parts);
   unsigned int offset = 0;
+  hb_position_t italicCorrection;
   if (hb_ot_math_get_glyph_assembly(mHBFont, aGlyphID, direction, offset,
-                                    &count, parts, NULL) > std::size(parts))
+                                    &count, parts,
+                                    &italicCorrection) > std::size(parts))
     return;                // Not supported: Too many pieces.
   if (count <= 0) return;  // Not supported: No pieces.
 
@@ -208,4 +218,6 @@ void gfxMathTable::UpdateMathVariantCache(uint32_t aGlyphID, bool aVertical,
   }
 
   mMathVariantCache.arePartsValid = true;
+  mMathVariantCache.glyphAssemblyItalicCorrection =
+      FixedToFloat(italicCorrection);
 }

diff --git a/layout/mathml/nsIMathMLFrame.h b/layout/mathml/nsIMathMLFrame.h
index 634a67ad3e74..2c367043afb7 100644
--- a/layout/mathml/nsIMathMLFrame.h
+++ b/layout/mathml/nsIMathMLFrame.h
@@ -269,6 +269,10 @@ class nsIMathMLFrame {
   // child.  In the latter case, the child is to be treated as if it wasn't
   // within an mrow, so we pretend the mrow isn't mrow-like.
   virtual bool IsMrowLike() = 0;
+
+  // Return the italic correction of this frame.
+  // https:// w3c.github.io/mathml-core/#dfn-italic-correction
+  virtual nscoord ItalicCorrection() = 0;
 };
 
 // struct used by a container frame to keep track of its embellishments.
diff --git a/layout/mathml/nsMathMLChar.cpp b/layout/mathml/nsMathMLChar.cpp
index 6f9255318124..13fca216aa83 100644
--- a/layout/mathml/nsMathMLChar.cpp
+++ b/layout/mathml/nsMathMLChar.cpp
@@ -92,6 +92,14 @@ class nsGlyphTable {
                           gfxFontGroup* aFontGroup, char16_t aChar,
                           bool aVertical) = 0;
 
+  virtual nscoord GlyphAssemblyItalicCorrection(DrawTarget* aDrawTarget,
+                                                int32_t aAppUnitsPerDevPixel,
+                                                gfxFontGroup* aFontGroup,
+                                                char16_t aChar,
+                                                bool aVertical) {
+    return 0;
+  }
+
   virtual already_AddRefed<gfxTextRun> MakeTextRun(
       DrawTarget* aDrawTarget, int32_t aAppUnitsPerDevPixel,
       gfxFontGroup* aFontGroup, const nsGlyphCode& aGlyph) = 0;
@@ -295,6 +303,10 @@ class nsOpenTypeTable final : public nsGlyphTable {
   virtual bool HasPartsOf(DrawTarget* aDrawTarget, int32_t aAppUnitsPerDevPixel,
                           gfxFontGroup* aFontGroup, char16_t aChar,
                           bool aVertical) override;
+  nscoord GlyphAssemblyItalicCorrection(DrawTarget* aDrawTarget,
+                                        int32_t aAppUnitsPerDevPixel,
+                                        gfxFontGroup* aFontGroup,
+                                        char16_t aChar, bool aVertical) final;
 
   const nsCString& FontNameFor(const nsGlyphCode& aGlyphCode) const override {
     NS_ASSERTION(aGlyphCode.isGlyphID,
@@ -380,6 +392,16 @@ nsGlyphCode nsOpenTypeTable::ElementAt(DrawTarget* aDrawTarget,
   return glyph;
 }
 
+/* virtual */
+nscoord nsOpenTypeTable::GlyphAssemblyItalicCorrection(
+    DrawTarget* aDrawTarget, int32_t aAppUnitsPerDevPixel,
+    gfxFontGroup* aFontGroup, char16_t aChar, bool aVertical) {
+  UpdateCache(aDrawTarget, aAppUnitsPerDevPixel, aFontGroup, aChar);
+  return NSToCoordRound(mFont->MathTable()->ItalicCorrectionForGlyphAssembly(
+                            mGlyphID, aVertical, IsRtl()) *
+                        aAppUnitsPerDevPixel);
+}
+
 /* virtual */
 nsGlyphCode nsOpenTypeTable::BigOf(DrawTarget* aDrawTarget,
                                    int32_t aAppUnitsPerDevPixel,
@@ -1054,6 +1066,9 @@ bool nsMathMLChar::StretchEnumContext::TryParts(
     mBoundingMetrics.leftBearing = 0;
     mBoundingMetrics.rightBearing = computedSize;
   }
+  mChar->mItalicCorrection = aGlyphTable->GlyphAssemblyItalicCorrection(
+      mDrawTarget, oneDevPixel, *aFontGroup, uchar, isVertical);
+
   mGlyphFound = true;
   if (maxWidth) {
     return false;  // Continue to check other sizes

You need to log in before you can comment on or make changes to this bug.