diff options
Diffstat (limited to 'Source/WebCore/platform/graphics/gtk')
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/ColorGtk.cpp | 55 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/FontGtk.cpp | 439 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp | 39 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.h | 31 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/IconGtk.cpp | 127 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp | 73 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/ImageGtk.cpp | 158 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/IntPointGtk.cpp | 41 | ||||
-rw-r--r-- | Source/WebCore/platform/graphics/gtk/IntRectGtk.cpp | 41 |
9 files changed, 1004 insertions, 0 deletions
diff --git a/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp b/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp new file mode 100644 index 0000000..8f56ba6 --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/ColorGtk.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2011 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "Color.h" + +#include <gdk/gdk.h> + +namespace WebCore { + +Color::Color(const GdkColor& c) + : m_color(makeRGB(c.red >> 8, c.green >> 8, c.blue >> 8)) + , m_valid(true) +{ +} + +#ifndef GTK_API_VERSION_2 +Color::Color(const GdkRGBA& c) + : m_color(makeRGBA(static_cast<int>(c.red * 255), + static_cast<int>(c.green * 255), + static_cast<int>(c.blue * 255), + static_cast<int>(c.alpha * 255))) + , m_valid(true) +{ +} + +Color::operator GdkRGBA() const +{ + double red, green, blue, alpha; + getRGBA(red, green, blue, alpha); + GdkRGBA rgba = { red, green, blue, alpha }; + return rgba; +} +#endif + +} + +// vim: ts=4 sw=4 et diff --git a/Source/WebCore/platform/graphics/gtk/FontGtk.cpp b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp new file mode 100644 index 0000000..fdf91db --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/FontGtk.cpp @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * Copyright (c) 2007 Hiroyuki Ikezoe + * Copyright (c) 2007 Kouhei Sutou + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * Copyright (C) 2008 Xan Lopez <xan@gnome.org> + * Copyright (C) 2008 Nuanti Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Font.h" + +#include "CairoUtilities.h" +#include "ContextShadow.h" +#include "GraphicsContext.h" +#include "NotImplemented.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) + +static void utf16_to_utf8(const UChar* aText, gint aLength, char* &text, gint &length) +{ + gboolean need_copy = FALSE; + int i; + + for (i = 0; i < aLength; i++) { + if (!aText[i] || IS_LOW_SURROGATE(aText[i])) { + need_copy = TRUE; + break; + } + else if (IS_HIGH_SURROGATE(aText[i])) { + if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1])) + i++; + else { + need_copy = TRUE; + break; + } + } + } + + if (need_copy) { + + /* Pango doesn't correctly handle nuls. We convert them to 0xff. */ + /* Also "validate" UTF-16 text to make sure conversion doesn't fail. */ + + UChar* p = (UChar*)g_memdup(aText, aLength * sizeof(aText[0])); + + /* don't need to reset i */ + for (i = 0; i < aLength; i++) { + if (!p[i] || IS_LOW_SURROGATE(p[i])) + p[i] = 0xFFFD; + else if (IS_HIGH_SURROGATE(p[i])) { + if (i < aLength - 1 && IS_LOW_SURROGATE(aText[i+1])) + i++; + else + p[i] = 0xFFFD; + } + } + + aText = p; + } + + glong items_written; + text = g_utf16_to_utf8(reinterpret_cast<const gunichar2*>(aText), aLength, NULL, &items_written, NULL); + length = items_written; + + if (need_copy) + g_free((gpointer)aText); + +} + +static gchar* convertUniCharToUTF8(const UChar* characters, gint length, int from, int to) +{ + gchar* utf8 = 0; + gint new_length = 0; + utf16_to_utf8(characters, length, utf8, new_length); + if (!utf8) + return NULL; + + if (from > 0) { + // discard the first 'from' characters + // FIXME: we should do this before the conversion probably + gchar* str_left = g_utf8_offset_to_pointer(utf8, from); + gchar* tmp = g_strdup(str_left); + g_free(utf8); + utf8 = tmp; + } + + gchar* pos = utf8; + gint len = strlen(pos); + GString* ret = g_string_new_len(NULL, len); + + // replace line break by space + while (len > 0) { + gint index, start; + pango_find_paragraph_boundary(pos, len, &index, &start); + g_string_append_len(ret, pos, index); + if (index == start) + break; + g_string_append_c(ret, ' '); + pos += start; + len -= start; + } + return g_string_free(ret, FALSE); +} + +static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout* layout) +{ +#if defined(USE_FREETYPE) + if (font->primaryFont()->platformData().m_pattern) { + PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->platformData().m_pattern.get(), FALSE); + pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); + } +#elif defined(USE_PANGO) + if (font->primaryFont()->platformData().m_font) { + PangoFontDescription* desc = pango_font_describe(font->primaryFont()->platformData().m_font); + pango_layout_set_font_description(layout, desc); + pango_font_description_free(desc); + } +#endif + + pango_layout_set_auto_dir(layout, FALSE); + + PangoContext* pangoContext = pango_layout_get_context(layout); + PangoDirection direction = run.rtl() ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; + pango_context_set_base_dir(pangoContext, direction); + PangoAttrList* list = pango_attr_list_new(); + PangoAttribute* attr; + + attr = pango_attr_size_new_absolute(font->pixelSize() * PANGO_SCALE); + attr->end_index = G_MAXUINT; + pango_attr_list_insert_before(list, attr); + + if (!run.spacingDisabled()) { + attr = pango_attr_letter_spacing_new(font->letterSpacing() * PANGO_SCALE); + attr->end_index = G_MAXUINT; + pango_attr_list_insert_before(list, attr); + } + + // Pango does not yet support synthesising small caps + // See http://bugs.webkit.org/show_bug.cgi?id=15610 + + pango_layout_set_attributes(layout, list); + pango_attr_list_unref(list); +} + +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() & TextModeFill) || 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->mustUseContextShadow(graphicsContext)) { + 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(graphicsContext, 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(graphicsContext); + cairo_restore(context); + } +} + +void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const +{ +#if defined(USE_FREETYPE) + if (!primaryFont()->platformData().m_pattern) { + drawSimpleText(context, run, point, from, to); + return; + } +#endif + + cairo_t* cr = context->platformContext(); + PangoLayout* layout = pango_cairo_create_layout(cr); + setPangoAttributes(this, run, layout); + + gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); + pango_layout_set_text(layout, utf8, -1); + + // Our layouts are single line + PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); + + // 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); + + drawGlyphsShadow(context, cr, point, layoutLine, partialRegion); + + cairo_save(cr); + cairo_translate(cr, point.x(), point.y()); + + float red, green, blue, alpha; + context->fillColor().getRGBA(red, green, blue, alpha); + cairo_set_source_rgba(cr, red, green, blue, alpha); + gdk_cairo_region(cr, partialRegion); + cairo_clip(cr); + + pango_cairo_show_layout_line(cr, layoutLine); + + if (context->textDrawingMode() & TextModeStroke) { + Color strokeColor = context->strokeColor(); + strokeColor.getRGBA(red, green, blue, alpha); + cairo_set_source_rgba(cr, red, green, blue, alpha); + pango_cairo_layout_line_path(cr, layoutLine); + cairo_set_line_width(cr, context->strokeThickness()); + cairo_stroke(cr); + } + + // Pango sometimes leaves behind paths we don't want + cairo_new_path(cr); + + destroyPangoRegion(partialRegion); + g_free(utf8); + g_object_unref(layout); + + cairo_restore(cr); +} + +void Font::drawEmphasisMarksForComplexText(GraphicsContext* /* context */, const TextRun& /* run */, const AtomicString& /* mark */, const FloatPoint& /* point */, int /* from */, int /* to */) const +{ + notImplemented(); +} + +// We should create the layout with our actual context but we can't access it from here. +static PangoLayout* getDefaultPangoLayout(const TextRun& run) +{ + static PangoFontMap* map = pango_cairo_font_map_get_default(); +#if PANGO_VERSION_CHECK(1,21,5) + static PangoContext* pangoContext = pango_font_map_create_context(map); +#else + // Deprecated in Pango 1.21. + static PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(map)); +#endif + PangoLayout* layout = pango_layout_new(pangoContext); + + return layout; +} + +float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* overflow) const +{ +#if defined(USE_FREETYPE) + if (!primaryFont()->platformData().m_pattern) + return floatWidthForSimpleText(run, 0, fallbackFonts, overflow); +#endif + + if (run.length() == 0) + return 0.0f; + + PangoLayout* layout = getDefaultPangoLayout(run); + setPangoAttributes(this, run, layout); + + gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); + pango_layout_set_text(layout, utf8, -1); + + int width; + pango_layout_get_pixel_size(layout, &width, 0); + + g_free(utf8); + g_object_unref(layout); + + return width; +} + +int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, bool includePartialGlyphs) const +{ +#if defined(USE_FREETYPE) + if (!primaryFont()->platformData().m_pattern) + return offsetForPositionForSimpleText(run, xFloat, includePartialGlyphs); +#endif + // FIXME: This truncation is not a problem for HTML, but only affects SVG, which passes floating-point numbers + // to Font::offsetForPosition(). Bug http://webkit.org/b/40673 tracks fixing this problem. + int x = static_cast<int>(xFloat); + + PangoLayout* layout = getDefaultPangoLayout(run); + setPangoAttributes(this, run, layout); + + gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); + pango_layout_set_text(layout, utf8, -1); + + int index, trailing; + pango_layout_xy_to_index(layout, x * PANGO_SCALE, 1, &index, &trailing); + glong offset = g_utf8_pointer_to_offset(utf8, utf8 + index); + if (includePartialGlyphs) + offset += trailing; + + g_free(utf8); + g_object_unref(layout); + + return offset; +} + +FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const +{ +#if defined(USE_FREETYPE) + if (!primaryFont()->platformData().m_pattern) + return selectionRectForSimpleText(run, point, h, from, to); +#endif + + PangoLayout* layout = getDefaultPangoLayout(run); + setPangoAttributes(this, run, layout); + + gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); + pango_layout_set_text(layout, utf8, -1); + + char* start = g_utf8_offset_to_pointer(utf8, from); + char* end = g_utf8_offset_to_pointer(start, to - from); + + if (run.ltr()) { + from = start - utf8; + to = end - utf8; + } else { + from = end - utf8; + to = start - utf8; + } + + PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); + int x_pos; + + x_pos = 0; + if (from < layoutLine->length) + pango_layout_line_index_to_x(layoutLine, from, FALSE, &x_pos); + float beforeWidth = PANGO_PIXELS_FLOOR(x_pos); + + x_pos = 0; + if (run.ltr() || to < layoutLine->length) + pango_layout_line_index_to_x(layoutLine, to, FALSE, &x_pos); + float afterWidth = PANGO_PIXELS(x_pos); + + g_free(utf8); + g_object_unref(layout); + + return FloatRect(point.x() + beforeWidth, point.y(), afterWidth - beforeWidth, h); +} + +} diff --git a/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp b/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp new file mode 100644 index 0000000..d8018a3 --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "GdkCairoUtilities.h" +#include "GtkVersioning.h" + +#include <cairo.h> +#include <gtk/gtk.h> + +GdkPixbuf* cairoImageSurfaceToGdkPixbuf(cairo_surface_t* surface) +{ + return gdk_pixbuf_get_from_surface(surface, 0, 0, + cairo_image_surface_get_width(surface), + cairo_image_surface_get_height(surface)); +} + diff --git a/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.h b/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.h new file mode 100644 index 0000000..ff5b3ed --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/GdkCairoUtilities.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GdkCairoUtilities_h +#define GdkCairoUtilities_h + +GdkPixbuf* cairoImageSurfaceToGdkPixbuf(cairo_surface_t* surface); + +#endif // GdkCairoUtilities_h diff --git a/Source/WebCore/platform/graphics/gtk/IconGtk.cpp b/Source/WebCore/platform/graphics/gtk/IconGtk.cpp new file mode 100644 index 0000000..d56b52d --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/IconGtk.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007 Holger Hans Peter Freyther + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "Icon.h" + +#include "GraphicsContext.h" +#include "MIMETypeRegistry.h" +#include "PassRefPtr.h" +#include <wtf/text/CString.h> + +#include <gtk/gtk.h> + +namespace WebCore { + +Icon::Icon() + : m_icon(0) +{ +} + +Icon::~Icon() +{ + if (m_icon) + g_object_unref(m_icon); +} + +static String lookupIconName(String MIMEType) +{ + /* + Lookup an appropriate icon according to either the Icon Naming Spec + or conventional Gnome icon names respectively. + + See http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html + + The icon theme is probed for the following names: + 1. media-subtype + 2. gnome-mime-media-subtype + 3. media-x-generic + 4. gnome-mime-media + + In the worst case it falls back to the stock file icon. + */ + int pos = MIMEType.find('/'); + if(pos >= 0) { + String media = MIMEType.substring(0, pos); + String subtype = MIMEType.substring(pos + 1); + GtkIconTheme* iconTheme = gtk_icon_theme_get_default(); + String iconName = media + "-" + subtype; + if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data())) + return iconName; + iconName = "gnome-mime-" + media + "-" + subtype; + if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data())) + return iconName; + iconName = media + "-x-generic"; + if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data())) + return iconName; + iconName = media + "gnome-mime-" + media; + if(gtk_icon_theme_has_icon(iconTheme, iconName.utf8().data())) + return iconName; + } + return GTK_STOCK_FILE; +} + +// FIXME: Move the code to ChromeClient::iconForFiles(). +PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames) +{ + if (filenames.isEmpty()) + return 0; + + if (filenames.size() == 1) { + if (!g_path_skip_root(filenames[0].utf8().data())) + return 0; + + String MIMEType = MIMETypeRegistry::getMIMETypeForPath(filenames[0]); + String iconName = lookupIconName(MIMEType); + + RefPtr<Icon> icon = adoptRef(new Icon); + icon->m_icon = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), iconName.utf8().data(), 16, GTK_ICON_LOOKUP_USE_BUILTIN, 0); + if (!icon->m_icon) + return 0; + return icon.release(); + } + + //FIXME: Implement this + return 0; +} + +void Icon::paint(GraphicsContext* context, const IntRect& rect) +{ + if (context->paintingDisabled()) + return; + + // TODO: Scale/clip the image if necessary. + cairo_t* cr = context->platformContext(); + cairo_save(cr); + gdk_cairo_set_source_pixbuf(cr, m_icon, rect.x(), rect.y()); + cairo_paint(cr); + cairo_restore(cr); +} + +} diff --git a/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp b/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp new file mode 100644 index 0000000..2aa016e --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "config.h" +#include "ImageBuffer.h" + +#include "Base64.h" +#include "GdkCairoUtilities.h" +#include "GOwnPtr.h" +#include "GRefPtrGtk.h" +#include "MIMETypeRegistry.h" +#include <cairo.h> +#include <gtk/gtk.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringConcatenate.h> + +namespace WebCore { + +String ImageBuffer::toDataURL(const String& mimeType, const double* quality) const +{ + ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); + + if (!mimeType.startsWith("image/")) + return "data:,"; + + // List of supported image types comes from the GdkPixbuf documentation. + // http://library.gnome.org/devel/gdk-pixbuf/stable/gdk-pixbuf-file-saving.html#gdk-pixbuf-save-to-bufferv + String type = mimeType.substring(sizeof "image"); + if (type != "jpeg" && type != "png" && type != "tiff" && type != "ico" && type != "bmp") + return "data:,"; + + GRefPtr<GdkPixbuf> pixbuf = cairoImageSurfaceToGdkPixbuf(m_data.m_surface); + if (!pixbuf) + return "data:,"; + + GOwnPtr<gchar> buffer(0); + gsize bufferSize; + GError* error = 0; + gboolean success = FALSE; + if (type == "jpeg" && quality && *quality >= 0.0 && *quality <= 1.0) { + String qualityString = String::format("%f", *quality); + success = gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, + type.utf8().data(), &error, "quality", qualityString.utf8().data(), NULL); + } else { + success = gdk_pixbuf_save_to_buffer(pixbuf.get(), &buffer.outPtr(), &bufferSize, type.utf8().data(), &error, NULL); + } + + if (!success) + return "data:,"; + + Vector<char> out; + base64Encode(reinterpret_cast<const char*>(buffer.get()), bufferSize, out); + + return makeString("data:", mimeType, ";base64,", out); +} + +} diff --git a/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp b/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp new file mode 100644 index 0000000..623ace6 --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/ImageGtk.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "BitmapImage.h" +#include "GdkCairoUtilities.h" +#include "GOwnPtrGtk.h" +#include "SharedBuffer.h" +#include <wtf/text/CString.h> +#include <cairo.h> +#include <gtk/gtk.h> + +#if PLATFORM(WIN) +#include <mbstring.h> +#include <shlobj.h> + +static HMODULE hmodule; + +extern "C" { +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + hmodule = hinstDLL; + return TRUE; +} +} + +static const char* getWebKitDataDirectory() +{ + static char* dataDirectory = 0; + if (dataDirectory) + return dataDirectory; + + dataDirectory = new char[PATH_MAX]; + if (!GetModuleFileName(hmodule, static_cast<CHAR*>(dataDirectory), sizeof(dataDirectory) - 10)) + return DATA_DIR; + + // FIXME: This is pretty ugly. Ideally we should be using Windows API + // functions or GLib methods to calculate paths. + unsigned char *p; + p = _mbsrchr(static_cast<const unsigned char *>(dataDirectory), '\\'); + *p = '\0'; + p = _mbsrchr(static_cast<const unsigned char *>(dataDirectory), '\\'); + if (p) { + if (!stricmp((const char *) (p+1), "bin")) + *p = '\0'; + } + strcat(dataDirectory, "\\share"); + + return dataDirectory; +} + +#else + +static const char* getWebKitDataDirectory() +{ + return DATA_DIR; +} + +#endif + +namespace WebCore { + +static CString getThemeIconFileName(const char* name, int size) +{ + GtkIconInfo* iconInfo = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(), + name, size, GTK_ICON_LOOKUP_NO_SVG); + // Try to fallback on MISSING_IMAGE. + if (!iconInfo) + iconInfo = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(), + GTK_STOCK_MISSING_IMAGE, size, + GTK_ICON_LOOKUP_NO_SVG); + if (iconInfo) { + GOwnPtr<GtkIconInfo> info(iconInfo); + return CString(gtk_icon_info_get_filename(info.get())); + } + + // No icon was found, this can happen if not GTK theme is set. In + // that case an empty Image will be created. + return CString(); +} + +static PassRefPtr<SharedBuffer> loadResourceSharedBuffer(CString name) +{ + GOwnPtr<gchar> content; + gsize length; + if (!g_file_get_contents(name.data(), &content.outPtr(), &length, 0)) + return SharedBuffer::create(); + + return SharedBuffer::create(content.get(), length); +} + +void BitmapImage::initPlatformData() +{ +} + +void BitmapImage::invalidatePlatformData() +{ +} + +PassRefPtr<Image> loadImageFromFile(CString fileName) +{ + RefPtr<BitmapImage> img = BitmapImage::create(); + if (!fileName.isNull()) { + RefPtr<SharedBuffer> buffer = loadResourceSharedBuffer(fileName); + img->setData(buffer.release(), true); + } + return img.release(); +} + +PassRefPtr<Image> Image::loadPlatformResource(const char* name) +{ + CString fileName; + if (!strcmp("missingImage", name)) + fileName = getThemeIconFileName(GTK_STOCK_MISSING_IMAGE, 16); + if (fileName.isNull()) { + GOwnPtr<gchar> imageName(g_strdup_printf("%s.png", name)); + GOwnPtr<gchar> glibFileName(g_build_filename(getWebKitDataDirectory(), "webkitgtk-"WEBKITGTK_API_VERSION_STRING, "images", imageName.get(), NULL)); + fileName = glibFileName.get(); + } + + return loadImageFromFile(fileName); +} + +PassRefPtr<Image> Image::loadPlatformThemeIcon(const char* name, int size) +{ + return loadImageFromFile(getThemeIconFileName(name, size)); +} + +GdkPixbuf* BitmapImage::getGdkPixbuf() +{ + return cairoImageSurfaceToGdkPixbuf(frameAtIndex(currentFrame())); +} + +} diff --git a/Source/WebCore/platform/graphics/gtk/IntPointGtk.cpp b/Source/WebCore/platform/graphics/gtk/IntPointGtk.cpp new file mode 100644 index 0000000..c402158 --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/IntPointGtk.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "IntPoint.h" + +#include <gdk/gdk.h> + +namespace WebCore { + +IntPoint::IntPoint(const GdkPoint& p) + : m_x(p.x) + , m_y(p.y) +{ +} + +IntPoint::operator GdkPoint() const +{ + GdkPoint p = { x(), y() }; + return p; +} + +} + +// vim: ts=4 sw=4 et diff --git a/Source/WebCore/platform/graphics/gtk/IntRectGtk.cpp b/Source/WebCore/platform/graphics/gtk/IntRectGtk.cpp new file mode 100644 index 0000000..aaa1944 --- /dev/null +++ b/Source/WebCore/platform/graphics/gtk/IntRectGtk.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2007 Alp Toker <alp@atoker.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "IntRect.h" + +#include <gdk/gdk.h> + +namespace WebCore { + +IntRect::IntRect(const GdkRectangle& r) + : m_location(IntPoint(r.x, r.y)) + , m_size(r.width, r.height) +{ +} + +IntRect::operator GdkRectangle() const +{ + GdkRectangle r = { x(), y(), width(), height() }; + return r; +} + +} + +// vim: ts=4 sw=4 et |