int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const { 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; }
float Font::floatWidthForComplexText(const TextRun& run) const { 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; }
float Font::floatWidthForComplexText(const TextRun& run, const TextStyle& style) const { if (run.length() == 0) return 0.0f; PangoLayout* layout = getDefaultPangoLayout(run); setPangoAttributes(this, run, layout, style.rtl()); gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), 0, run.length()); pango_layout_set_text(layout, utf8, -1); g_free(utf8); int layoutWidth; pango_layout_get_size(layout, &layoutWidth, 0); float width = (float)layoutWidth / (double)PANGO_SCALE; g_object_unref(layout); return width; }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int h, int from, int to) const { #if 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 xPos; xPos = 0; if (from < layoutLine->length) pango_layout_line_index_to_x(layoutLine, from, FALSE, &xPos); float beforeWidth = PANGO_PIXELS_FLOOR(xPos); xPos = 0; if (run.ltr() || to < layoutLine->length) pango_layout_line_index_to_x(layoutLine, to, FALSE, &xPos); float afterWidth = PANGO_PIXELS(xPos); g_free(utf8); g_object_unref(layout); return FloatRect(point.x() + beforeWidth, point.y(), afterWidth - beforeWidth, h); }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const TextStyle& style, const IntPoint& point, int h, int from, int to) const { FloatRect rect; float tw; PangoLayout* layout = getDefaultPangoLayout(run); setPangoAttributes(this, run, layout, style.rtl()); float beforeWidth = getWidth (layout, run, 0, from); float afterWidth = getWidth (layout, run, 0, to); if (style.rtl()) { float totalWidth = getWidth (layout, run, 0, run.length()); tw = totalWidth; rect = FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h); } else rect = FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); g_object_unref(layout); return rect; }
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* overflow) const { #if USE(FREETYPE) if (!primaryFont()->platformData().m_pattern) return floatWidthForSimpleText(run, 0, fallbackFonts, overflow); #endif if (!run.length()) 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; }