gfx/cairo/dwrite-glyph-extents.patch
author Mats Palmgren <matspal@gmail.com>
Wed, 31 Oct 2012 06:10:38 +0100
changeset 112005 3781f04d144d29aba4a14813ea18ae2a82e96948
parent 43476 6efd0963eae957d88ef96f2e1597b1142f3cf824
permissions -rw-r--r--
Bug 803995 - Dispatch an nsAsyncRollup event (that calls RollupFromList) only if we're dropped down since otherwise it might reset mouse capturing for other content. r=roc

diff --git a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
--- a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
+++ b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
@@ -582,22 +582,37 @@ _cairo_dwrite_scaled_font_init_glyph_met
     DWRITE_FONT_METRICS fontMetrics;
     font_face->dwriteface->GetMetrics(&fontMetrics);
     HRESULT hr = font_face->dwriteface->GetDesignGlyphMetrics(&charIndex, 1, &metrics);
     if (FAILED(hr)) {
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
     // TODO: Treat swap_xy.
-    extents.width = (FLOAT)(metrics.advanceWidth - metrics.leftSideBearing - metrics.rightSideBearing) / fontMetrics.designUnitsPerEm;
-    extents.height = (FLOAT)(metrics.advanceHeight - metrics.topSideBearing - metrics.bottomSideBearing) / fontMetrics.designUnitsPerEm;
+    extents.width = (FLOAT)(metrics.advanceWidth - metrics.leftSideBearing - metrics.rightSideBearing) /
+        fontMetrics.designUnitsPerEm;
+    extents.height = (FLOAT)(metrics.advanceHeight - metrics.topSideBearing - metrics.bottomSideBearing) /
+        fontMetrics.designUnitsPerEm;
     extents.x_advance = (FLOAT)metrics.advanceWidth / fontMetrics.designUnitsPerEm;
     extents.x_bearing = (FLOAT)metrics.leftSideBearing / fontMetrics.designUnitsPerEm;
     extents.y_advance = 0.0;
-    extents.y_bearing = (FLOAT)(metrics.topSideBearing - metrics.verticalOriginY) / fontMetrics.designUnitsPerEm;
+    extents.y_bearing = (FLOAT)(metrics.topSideBearing - metrics.verticalOriginY) /
+        fontMetrics.designUnitsPerEm;
+
+    // We pad the extents here because GetDesignGlyphMetrics returns "ideal" metrics
+    // for the glyph outline, without accounting for hinting/gridfitting/antialiasing,
+    // and therefore it does not always cover all pixels that will actually be touched.
+    if (scaled_font->base.options.antialias != CAIRO_ANTIALIAS_NONE &&
+        extents.width > 0 && extents.height > 0) {
+        extents.width += scaled_font->mat_inverse.xx * 2;
+        extents.x_bearing -= scaled_font->mat_inverse.xx;
+        extents.height += scaled_font->mat_inverse.yy * 2;
+        extents.y_bearing -= scaled_font->mat_inverse.yy;
+    }
+
     _cairo_scaled_glyph_set_metrics (scaled_glyph,
 				     &scaled_font->base,
 				     &extents);
     return CAIRO_INT_STATUS_SUCCESS;
 }
 
 /**
  * Stack-based helper implementing IDWriteGeometrySink.