Changeset 36309 in webkit
- Timestamp:
- Sep 9, 2008 6:26:20 PM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r36305 r36309 1 2008-09-09 Alp Toker <alp@nuanti.com> 2 3 Reviewed by Dave Hyatt. 4 5 https://bugs.webkit.org/show_bug.cgi?id=16792 6 [GTK] Fails to render Japanese/Chinese text with simple path 7 8 https://bugs.webkit.org/show_bug.cgi?id=16942 9 [GTK] Oddities in font selection and fall back 10 11 https://bugs.webkit.org/show_bug.cgi?id=16862 12 [GTK] Custom fonts hard-coded to use grayscale antialiasing and no hinting 13 14 GTK+ font fixes and enhancements. 15 16 Implement font fallback for the simple FontConfig-based text path and 17 improve the Pango-based complex text path to make use of requested 18 font properties and available font selection. 19 20 Add text shadow support to the complex path. 21 22 * platform/graphics/gtk/FontCacheGtk.cpp: 23 (WebCore::FontCache::getFontDataForCharacters): 24 (WebCore::FontCache::getSimilarFontPlatformData): 25 * platform/graphics/gtk/FontGtk.cpp: 26 (WebCore::setPangoAttributes): 27 (WebCore::Font::drawComplexText): 28 (WebCore::getDefaultPangoLayout): 29 (WebCore::Font::floatWidthForComplexText): 30 (WebCore::Font::offsetForPositionForComplexText): 31 (WebCore::Font::selectionRectForComplexText): 32 * platform/graphics/gtk/FontPlatformData.h: 33 (WebCore::FontPlatformData::FontPlatformData): 34 (WebCore::FontPlatformData::hash): 35 * platform/graphics/gtk/FontPlatformDataGtk.cpp: 36 (WebCore::FontPlatformData::FontPlatformData): 37 * platform/graphics/gtk/SimpleFontDataGtk.cpp: 38 (WebCore::SimpleFontData::platformDestroy): 39 1 40 2008-09-09 Dave Hyatt <hyatt@apple.com> 2 41 -
trunk/WebCore/platform/graphics/gtk/FontCacheGtk.cpp
r34794 r36309 1 1 /* 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 4 * All rights reserved. 2 * Copyright (C) 2008 Alp Toker <alp@atoker.com> 5 3 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 9 8 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 16 * its contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 18 13 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 * 29 19 */ 30 20 … … 46 36 const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) 47 37 { 48 return new SimpleFontData(FontPlatformData(font.fontDescription(), font.family().family())); 38 #if defined(USE_FREETYPE) 39 FcResult fresult; 40 FontPlatformData* prim = const_cast<FontPlatformData*>(&font.primaryFont()->m_font); 41 42 if (!prim->m_fallbacks) 43 prim->m_fallbacks = FcFontSort(NULL, prim->m_pattern, FcTrue, NULL, &fresult); 44 45 FcFontSet* fs = prim->m_fallbacks; 46 47 for (int i = 0; i < fs->nfont; i++) { 48 FcPattern* fin = FcFontRenderPrepare(NULL, prim->m_pattern, fs->fonts[i]); 49 cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_pattern(fin); 50 FontPlatformData alternateFont(fontFace, font.fontDescription().computedPixelSize(), false, false); 51 cairo_font_face_destroy(fontFace); 52 alternateFont.m_pattern = fin; 53 SimpleFontData* sfd = getCachedFontData(&alternateFont); 54 if (sfd->containsCharacters(characters, length)) 55 return sfd; 56 } 57 #endif 58 59 return 0; 49 60 } 50 61 51 62 FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font) 52 63 { 53 return new FontPlatformData(font.fontDescription(), font.family().family());64 return 0; 54 65 } 55 66 -
trunk/WebCore/platform/graphics/gtk/FontGtk.cpp
r34112 r36309 6 6 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 7 7 * Copyright (C) 2008 Xan Lopez <xan@gnome.org> 8 * Copyright (C) 2008 Nuanti Ltd. 8 9 * All rights reserved. 9 10 * … … 38 39 39 40 #include <cairo.h> 41 #include <gdk/gdk.h> 40 42 #include <pango/pango.h> 41 43 #include <pango/pangocairo.h> 44 #if defined(USE_FREETYPE) 45 #include <pango/pangofc-fontmap.h> 46 #endif 42 47 43 48 namespace WebCore { … … 134 139 static void setPangoAttributes(const Font* font, const TextRun& run, PangoLayout* layout) 135 140 { 141 #if defined(USE_FREETYPE) 142 if (font->primaryFont()->m_font.m_pattern) { 143 PangoFontDescription* desc = pango_fc_font_description_from_pattern(font->primaryFont()->m_font.m_pattern, FALSE); 144 pango_layout_set_font_description(layout, desc); 145 pango_font_description_free(desc); 146 } 147 #elif defined(USE_PANGO) 148 if (font->primaryFont()->m_font.m_font) { 149 PangoFontDescription* desc = pango_font_describe(font->primaryFont()->m_font.m_font); 150 pango_layout_set_font_description(layout, desc); 151 pango_font_description_free(desc); 152 } 153 #endif 154 155 pango_layout_set_auto_dir(layout, FALSE); 156 157 PangoContext* pangoContext = pango_layout_get_context(layout); 158 PangoDirection direction = run.rtl() ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; 159 pango_context_set_base_dir(pangoContext, direction); 136 160 PangoAttrList* list = pango_attr_list_new(); 137 161 PangoAttribute* attr; 138 162 139 attr = pango_attr_size_new_absolute( (int)(font->size() * PANGO_SCALE));163 attr = pango_attr_size_new_absolute(font->pixelSize() * PANGO_SCALE); 140 164 attr->end_index = G_MAXUINT; 141 165 pango_attr_list_insert_before(list, attr); … … 152 176 pango_layout_set_attributes(layout, list); 153 177 pango_attr_list_unref(list); 154 155 pango_layout_set_auto_dir(layout, FALSE);156 157 PangoContext* pangoContext = pango_layout_get_context(layout);158 PangoDirection direction = run.rtl() ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;159 pango_context_set_base_dir(pangoContext, direction);160 178 } 161 179 … … 164 182 cairo_t* cr = context->platformContext(); 165 183 cairo_save(cr); 184 cairo_translate(cr, point.x(), point.y()); 166 185 167 186 PangoLayout* layout = pango_cairo_create_layout(cr); 168 169 gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), from, to); 187 setPangoAttributes(this, run, layout); 188 189 gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); 170 190 pango_layout_set_text(layout, utf8, -1); 191 192 // Our layouts are single line 193 PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); 194 195 GdkRegion* partialRegion = NULL; 196 if (to - from != run.length()) { 197 // Clip the region of the run to be rendered 198 char* start = g_utf8_offset_to_pointer(utf8, from); 199 char* end = g_utf8_offset_to_pointer(start, to - from); 200 int ranges[] = {start - utf8, end - utf8}; 201 partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1); 202 gdk_region_shrink(partialRegion, 0, -pixelSize()); 203 } 204 205 Color fillColor = context->fillColor(); 206 float red, green, blue, alpha; 207 208 // Text shadow, inspired by FontMac 209 IntSize shadowSize; 210 int shadowBlur = 0; 211 Color shadowColor; 212 bool hasShadow = context->textDrawingMode() == cTextFill && 213 context->getShadow(shadowSize, shadowBlur, shadowColor); 214 215 // TODO: Blur support 216 if (hasShadow) { 217 // Disable graphics context shadows (not yet implemented) and paint them manually 218 context->clearShadow(); 219 Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); 220 cairo_save(cr); 221 222 shadowFillColor.getRGBA(red, green, blue, alpha); 223 cairo_set_source_rgba(cr, red, green, blue, alpha); 224 225 cairo_translate(cr, shadowSize.width(), shadowSize.height()); 226 227 if (partialRegion) { 228 gdk_cairo_region(cr, partialRegion); 229 cairo_clip(cr); 230 } 231 232 pango_cairo_show_layout_line(cr, layoutLine); 233 234 cairo_restore(cr); 235 } 236 237 fillColor.getRGBA(red, green, blue, alpha); 238 cairo_set_source_rgba(cr, red, green, blue, alpha); 239 240 if (partialRegion) { 241 gdk_cairo_region(cr, partialRegion); 242 cairo_clip(cr); 243 } 244 245 pango_cairo_show_layout_line(cr, layoutLine); 246 247 if (context->textDrawingMode() & cTextStroke) { 248 Color strokeColor = context->strokeColor(); 249 strokeColor.getRGBA(red, green, blue, alpha); 250 cairo_set_source_rgba(cr, red, green, blue, alpha); 251 pango_cairo_layout_line_path(cr, layoutLine); 252 cairo_set_line_width(cr, context->strokeThickness()); 253 cairo_stroke(cr); 254 } 255 256 // Re-enable the platform shadow we disabled earlier 257 if (hasShadow) 258 context->setShadow(shadowSize, shadowBlur, shadowColor); 259 260 // Pango sometimes leaves behind paths we don't want 261 cairo_new_path(cr); 262 263 if (partialRegion) 264 gdk_region_destroy(partialRegion); 265 171 266 g_free(utf8); 172 173 setPangoAttributes(this, run, layout);174 175 // Set the text color to use for drawing.176 float red, green, blue, alpha;177 Color penColor = context->fillColor();178 penColor.getRGBA(red, green, blue, alpha);179 cairo_set_source_rgba(cr, red, green, blue, alpha);180 181 // Our layouts are single line182 cairo_move_to(cr, point.x(), point.y());183 PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0);184 pango_cairo_show_layout_line(cr, layoutLine);185 186 267 g_object_unref(layout); 268 187 269 cairo_restore(cr); 188 270 } 189 271 190 // FIXME: we should create the layout with our actual context, but it seems 191 // we can't access it from here 272 // We should create the layout with our actual context but we can't access it from here. 192 273 static PangoLayout* getDefaultPangoLayout(const TextRun& run) 193 274 { 194 PangoFontMap* map = pango_cairo_font_map_get_default();195 PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(map));275 static PangoFontMap* map = pango_cairo_font_map_get_default(); 276 static PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(map)); 196 277 PangoLayout* layout = pango_layout_new(pangoContext); 197 g_object_unref(pangoContext);198 278 199 279 return layout; … … 210 290 gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); 211 291 pango_layout_set_text(layout, utf8, -1); 292 293 int width; 294 pango_layout_get_pixel_size(layout, &width, 0); 295 212 296 g_free(utf8); 213 214 int layoutWidth;215 pango_layout_get_size(layout, &layoutWidth, 0);216 float width = (float)layoutWidth / (double)PANGO_SCALE;217 297 g_object_unref(layout); 218 298 … … 231 311 pango_layout_xy_to_index(layout, x * PANGO_SCALE, 1, &index, &trailing); 232 312 glong offset = g_utf8_pointer_to_offset(utf8, utf8 + index); 313 if (includePartialGlyphs) 314 offset += trailing; 315 233 316 g_free(utf8); 234 317 g_object_unref(layout); … … 239 322 FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int from, int to) const 240 323 { 241 notImplemented(); 242 return FloatRect(); 243 } 244 245 } 324 PangoLayout* layout = getDefaultPangoLayout(run); 325 setPangoAttributes(this, run, layout); 326 327 gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); 328 pango_layout_set_text(layout, utf8, -1); 329 330 char* start = g_utf8_offset_to_pointer(utf8, from); 331 char* end = g_utf8_offset_to_pointer(start, to - from); 332 333 if (run.ltr()) { 334 from = start - utf8; 335 to = end - utf8; 336 } else { 337 from = end - utf8; 338 to = start - utf8; 339 } 340 341 PangoLayoutLine* layoutLine = pango_layout_get_line_readonly(layout, 0); 342 int x_pos; 343 344 x_pos = 0; 345 if (from < layoutLine->length) 346 pango_layout_line_index_to_x(layoutLine, from, FALSE, &x_pos); 347 float beforeWidth = PANGO_PIXELS_FLOOR(x_pos); 348 349 x_pos = 0; 350 if (run.ltr() || to < layoutLine->length) 351 pango_layout_line_index_to_x(layoutLine, to, FALSE, &x_pos); 352 float afterWidth = PANGO_PIXELS(x_pos); 353 354 g_free(utf8); 355 g_object_unref(layout); 356 357 return FloatRect(point.x() + beforeWidth, point.y(), afterWidth - beforeWidth, h); 358 } 359 360 } -
trunk/WebCore/platform/graphics/gtk/FontPlatformData.h
r32615 r36309 48 48 #if defined(USE_FREETYPE) 49 49 : m_pattern(hashTableDeletedFontValue()) 50 , m_fallbacks(0) 50 51 #elif defined(USE_PANGO) 51 52 : m_context(0) … … 60 61 #if defined(USE_FREETYPE) 61 62 : m_pattern(0) 63 , m_fallbacks(0) 62 64 #elif defined(USE_PANGO) 63 65 : m_context(0) … … 85 87 unsigned hash() const 86 88 { 89 #if defined(USE_FREETYPE) 90 if (m_pattern) 91 return FcPatternHash(m_pattern); 92 #endif 87 93 uintptr_t hashCodes[1] = { reinterpret_cast<uintptr_t>(m_scaledFont) }; 88 94 return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); … … 100 106 #if defined(USE_FREETYPE) 101 107 FcPattern* m_pattern; 108 FcFontSet* m_fallbacks; 102 109 #elif defined(USE_PANGO) 103 110 static PangoFontMap* m_fontMap; -
trunk/WebCore/platform/graphics/gtk/FontPlatformDataGtk.cpp
r31622 r36309 38 38 FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName) 39 39 : m_pattern(0) 40 , m_size(fontDescription.computedSize()) 40 , m_fallbacks(0) 41 , m_size(fontDescription.computedPixelSize()) 41 42 , m_syntheticBold(false) 42 43 , m_syntheticOblique(false) … … 50 51 // FIXME: Map all FontWeight values to fontconfig weights. 51 52 int fcweight = FC_WEIGHT_NORMAL; 52 float fcsize = fontDescription.computedSize();53 double fcsize = fontDescription.computedPixelSize(); 53 54 if (fontDescription.italic()) 54 55 fcslant = FC_SLANT_ITALIC; … … 68 69 69 70 switch (type) { 70 case FontDescription::SerifFamily: 71 fcfamily = "serif"; 72 break; 73 case FontDescription::SansSerifFamily: 74 fcfamily = "sans-serif"; 75 break; 76 case FontDescription::MonospaceFamily: 77 fcfamily = "monospace"; 78 break; 79 case FontDescription::NoFamily: 80 case FontDescription::StandardFamily: 81 default: 82 fcfamily = "sans-serif"; 71 case FontDescription::SerifFamily: 72 fcfamily = "serif"; 73 break; 74 case FontDescription::SansSerifFamily: 75 fcfamily = "sans-serif"; 76 break; 77 case FontDescription::MonospaceFamily: 78 fcfamily = "monospace"; 79 break; 80 case FontDescription::StandardFamily: 81 fcfamily = "sans-serif"; 82 break; 83 case FontDescription::NoFamily: 84 default: 85 fcfamily = NULL; 86 break; 83 87 } 84 88 85 if (!FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) 89 if (fcfamily && !FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily))) 90 goto freePattern; 91 if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight)) 86 92 goto freePattern; 87 93 if (!FcPatternAddInteger(pattern, FC_SLANT, fcslant)) 88 goto freePattern;89 if (!FcPatternAddInteger(pattern, FC_WEIGHT, fcweight))90 94 goto freePattern; 91 95 if (!FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fcsize)) … … 102 106 fontFace = cairo_ft_font_face_create_for_pattern(m_pattern); 103 107 cairo_matrix_t ctm; 104 cairo_matrix_init_scale(&fontMatrix, fontDescription.computed Size(), fontDescription.computedSize());108 cairo_matrix_init_scale(&fontMatrix, fontDescription.computedPixelSize(), fontDescription.computedPixelSize()); 105 109 cairo_matrix_init_identity(&ctm); 106 110 … … 123 127 FontPlatformData::FontPlatformData(float size, bool bold, bool italic) 124 128 : m_pattern(0) 129 , m_fallbacks(0) 125 130 , m_size(size) 126 131 , m_syntheticBold(bold) … … 132 137 FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, int size, bool bold, bool italic) 133 138 : m_pattern(0) 139 , m_fallbacks(0) 134 140 , m_size(size) 135 141 , m_syntheticBold(bold) … … 141 147 cairo_matrix_t ctm; 142 148 cairo_matrix_init_identity(&ctm); 143 cairo_font_options_t* options = cairo_font_options_create(); 144 145 // We force antialiasing and disable hinting to provide consistent 146 // typographic qualities for custom fonts on all platforms. 147 cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE); 148 cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY); 149 static const cairo_font_options_t* defaultOptions = cairo_font_options_create(); 150 const cairo_font_options_t* options = NULL; 151 152 #if GTK_CHECK_VERSION(2,10,0) 153 if (GdkScreen* screen = gdk_screen_get_default()) 154 options = gdk_screen_get_font_options(screen); 155 #endif 156 // gdk_screen_get_font_options() returns NULL if no default options are 157 // set, so we always have to check. 158 if (!options) 159 options = defaultOptions; 149 160 150 161 m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options); 151 cairo_font_options_destroy(options);152 162 } 153 163 -
trunk/WebCore/platform/graphics/gtk/SimpleFontDataGtk.cpp
r29961 r36309 63 63 void SimpleFontData::platformDestroy() 64 64 { 65 if (!isCustomFont()) { 66 if (m_font.m_pattern && ((FcPattern*)-1 != m_font.m_pattern)) { 67 FcPatternDestroy(m_font.m_pattern); 68 m_font.m_pattern = 0; 69 } 65 delete m_smallCapsFontData; 70 66 71 if (m_font.m_scaledFont) { 72 cairo_scaled_font_destroy(m_font.m_scaledFont); 73 m_font.m_scaledFont = 0; 74 } 67 if (isCustomFont()) 68 return; 69 70 if (m_font.m_pattern && ((FcPattern*)-1 != m_font.m_pattern)) { 71 FcPatternDestroy(m_font.m_pattern); 72 m_font.m_pattern = 0; 75 73 } 76 74 77 delete m_smallCapsFontData; 75 if (m_font.m_fallbacks) { 76 FcFontSetDestroy(m_font.m_fallbacks); 77 m_font.m_fallbacks = 0; 78 } 79 80 if (m_font.m_scaledFont) { 81 cairo_scaled_font_destroy(m_font.m_scaledFont); 82 m_font.m_scaledFont = 0; 83 } 78 84 } 79 85
Note: See TracChangeset
for help on using the changeset viewer.