summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/gtk/FontGtk.cpp
diff options
context:
space:
mode:
authorRussell Brenner <russellbrenner@google.com>2010-11-18 17:33:13 -0800
committerRussell Brenner <russellbrenner@google.com>2010-12-02 13:47:21 -0800
commit6b70adc33054f8aee8c54d0f460458a9df11b8a5 (patch)
tree103a13998c33944d6ab3b8318c509a037e639460 /WebCore/platform/graphics/gtk/FontGtk.cpp
parentbdf4ebc8e70b2d221b6ee7a65660918ecb1d33aa (diff)
downloadexternal_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.zip
external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.gz
external_webkit-6b70adc33054f8aee8c54d0f460458a9df11b8a5.tar.bz2
Merge WebKit at r72274: Initial merge by git.
Change-Id: Ie51f0b4a16da82942bd516dce59cfb79ebbe25fb
Diffstat (limited to 'WebCore/platform/graphics/gtk/FontGtk.cpp')
-rw-r--r--WebCore/platform/graphics/gtk/FontGtk.cpp159
1 files changed, 95 insertions, 64 deletions
diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp
index 328ec4a..54e18c9 100644
--- a/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -33,19 +33,51 @@
#include "config.h"
#include "Font.h"
+#include "CairoUtilities.h"
+#include "ContextShadow.h"
#include "GraphicsContext.h"
#include "SimpleFontData.h"
-
#include <cairo.h>
#include <gdk/gdk.h>
#include <pango/pango.h>
#include <pango/pangocairo.h>
+
#if defined(USE_FREETYPE)
#include <pango/pangofc-fontmap.h>
#endif
namespace WebCore {
+#ifdef GTK_API_VERSION_2
+typedef GdkRegion* PangoRegionType;
+
+void destroyPangoRegion(PangoRegionType region)
+{
+ gdk_region_destroy(region);
+}
+
+IntRect getPangoRegionExtents(PangoRegionType region)
+{
+ GdkRectangle rectangle;
+ gdk_region_get_clipbox(region, &rectangle);
+ return IntRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+#else
+typedef cairo_region_t* PangoRegionType;
+
+void destroyPangoRegion(PangoRegionType region)
+{
+ cairo_region_destroy(region);
+}
+
+IntRect getPangoRegionExtents(PangoRegionType region)
+{
+ cairo_rectangle_int_t rectangle;
+ cairo_region_get_extents(region, &rectangle);
+ return IntRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+}
+#endif
+
#define IS_HIGH_SURROGATE(u) ((UChar)(u) >= (UChar)0xd800 && (UChar)(u) <= (UChar)0xdbff)
#define IS_LOW_SURROGATE(u) ((UChar)(u) >= (UChar)0xdc00 && (UChar)(u) <= (UChar)0xdfff)
@@ -181,6 +213,52 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
+{
+ ContextShadow* shadow = graphicsContext->contextShadow();
+ ASSERT(shadow);
+
+ if (!(graphicsContext->textDrawingMode() & cTextFill) || shadow->m_type == ContextShadow::NoShadow)
+ return;
+
+ FloatPoint totalOffset(point + shadow->m_offset);
+
+ // Optimize non-blurry shadows, by just drawing text without the ContextShadow.
+ if (shadow->m_type == ContextShadow::SolidShadow) {
+ cairo_save(context);
+ cairo_translate(context, totalOffset.x(), totalOffset.y());
+
+ setSourceRGBAFromColor(context, shadow->m_color);
+ gdk_cairo_region(context, renderRegion);
+ cairo_clip(context);
+ pango_cairo_show_layout_line(context, layoutLine);
+
+ cairo_restore(context);
+ return;
+ }
+
+ FloatRect extents(getPangoRegionExtents(renderRegion));
+ extents.setLocation(FloatPoint(point.x(), point.y() - extents.height()));
+ cairo_t* shadowContext = shadow->beginShadowLayer(context, extents);
+ if (shadowContext) {
+ cairo_translate(shadowContext, point.x(), point.y());
+ pango_cairo_show_layout_line(shadowContext, layoutLine);
+
+ // We need the clipping region to be active when we blit the blurred shadow back,
+ // because we don't want any bits and pieces of characters out of range to be
+ // drawn. Since ContextShadow expects a consistent transform, we have to undo the
+ // translation before calling endShadowLayer as well.
+ cairo_save(context);
+ cairo_translate(context, totalOffset.x(), totalOffset.y());
+ gdk_cairo_region(context, renderRegion);
+ cairo_clip(context);
+ cairo_translate(context, -totalOffset.x(), -totalOffset.y());
+
+ shadow->endShadowLayer(context);
+ cairo_restore(context);
+ }
+}
+
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
{
#if defined(USE_FREETYPE)
@@ -191,9 +269,6 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
#endif
cairo_t* cr = context->platformContext();
- cairo_save(cr);
- cairo_translate(cr, point.x(), point.y());
-
PangoLayout* layout = pango_cairo_create_layout(cr);
setPangoAttributes(this, run, layout);
@@ -203,59 +278,25 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
// Our layouts are single line
PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);
-#ifdef GTK_API_VERSION_2
- GdkRegion* partialRegion = 0;
-#else
- cairo_region_t* partialRegion = 0;
-#endif
-
- if (to - from != run.length()) {
- // Clip the region of the run to be rendered
- char* start = g_utf8_offset_to_pointer(utf8, from);
- char* end = g_utf8_offset_to_pointer(start, to - from);
- int ranges[] = {start - utf8, end - utf8};
- partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
- }
-
- Color fillColor = context->fillColor();
- float red, green, blue, alpha;
-
- // Text shadow, inspired by FontMac
- FloatSize shadowOffset;
- float shadowBlur = 0;
- Color shadowColor;
- bool hasShadow = context->textDrawingMode() == cTextFill &&
- context->getShadow(shadowOffset, shadowBlur, shadowColor);
-
- // TODO: Blur support
- if (hasShadow) {
- // Disable graphics context shadows (not yet implemented) and paint them manually
- context->clearShadow();
- Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
- cairo_save(cr);
-
- shadowFillColor.getRGBA(red, green, blue, alpha);
- cairo_set_source_rgba(cr, red, green, blue, alpha);
-
- cairo_translate(cr, shadowOffset.width(), shadowOffset.height());
-
- if (partialRegion) {
- gdk_cairo_region(cr, partialRegion);
- cairo_clip(cr);
- }
+ // Get the region where this text will be laid out. We will use it to clip
+ // the Cairo context, for when we are only painting part of the text run and
+ // to calculate the size of the shadow buffer.
+ PangoRegionType partialRegion = 0;
+ char* start = g_utf8_offset_to_pointer(utf8, from);
+ char* end = g_utf8_offset_to_pointer(start, to - from);
+ int ranges[] = {start - utf8, end - utf8};
+ partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
- pango_cairo_show_layout_line(cr, layoutLine);
+ drawGlyphsShadow(context, cr, point, layoutLine, partialRegion);
- cairo_restore(cr);
- }
+ cairo_save(cr);
+ cairo_translate(cr, point.x(), point.y());
- fillColor.getRGBA(red, green, blue, alpha);
+ float red, green, blue, alpha;
+ context->fillColor().getRGBA(red, green, blue, alpha);
cairo_set_source_rgba(cr, red, green, blue, alpha);
-
- if (partialRegion) {
- gdk_cairo_region(cr, partialRegion);
- cairo_clip(cr);
- }
+ gdk_cairo_region(cr, partialRegion);
+ cairo_clip(cr);
pango_cairo_show_layout_line(cr, layoutLine);
@@ -268,20 +309,10 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
cairo_stroke(cr);
}
- // Re-enable the platform shadow we disabled earlier
- if (hasShadow)
- context->setShadow(shadowOffset, shadowBlur, shadowColor, ColorSpaceDeviceRGB);
-
// Pango sometimes leaves behind paths we don't want
cairo_new_path(cr);
- if (partialRegion)
-#ifdef GTK_API_VERSION_2
- gdk_region_destroy(partialRegion);
-#else
- cairo_region_destroy(partialRegion);
-#endif
-
+ destroyPangoRegion(partialRegion);
g_free(utf8);
g_object_unref(layout);