void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const TextStyle& style, const FloatPoint& point, int from, int to) const { cairo_t* cr = context->platformContext(); cairo_save(cr); PangoLayout* layout = pango_cairo_create_layout(cr); gchar* utf8 = convertUniCharToUTF8(run.characters(), run.length(), from, run.length()); pango_layout_set_text(layout, utf8, -1); setPangoAttributes(this, run, layout, style.rtl()); // Set the text color to use for drawing. float red, green, blue, alpha; Color penColor = context->fillColor(); penColor.getRGBA(red, green, blue, alpha); cairo_set_source_rgba(cr, red, green, blue, alpha); cairo_move_to(cr, point.x(), point.y()); PangoLayoutLine* layoutLine = pango_layout_get_line(layout, 0); pango_cairo_show_layout_line(cr, layoutLine); g_free(utf8); g_object_unref(layout); cairo_restore(cr); }
void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const TextStyle& style, const FloatPoint& point, int from, int to) const { // This glyph buffer holds our glyphs + advances + font data for each glyph. GlyphBuffer glyphBuffer; float startX = point.x(); UniscribeController controller(this, run, style); controller.advance(from); float beforeWidth = controller.runWidthSoFar(); controller.advance(to, &glyphBuffer); // We couldn't generate any glyphs for the run. Give up. if (glyphBuffer.isEmpty()) return; float afterWidth = controller.runWidthSoFar(); if (style.rtl()) { controller.advance(run.length()); startX += controller.runWidthSoFar() - afterWidth; } else startX += beforeWidth; // Draw the glyph buffer now at the starting point returned in startX. FloatPoint startPoint(startX, point.y()); drawGlyphBuffer(context, glyphBuffer, run, style, startPoint); }
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; }
int Font::offsetForPositionForComplexText(const TextRun& run, const TextStyle& style, int x, bool includePartialGlyphs) const { 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); 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); g_object_unref(layout); g_free(utf8); return offset; }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const TextStyle& style, const IntPoint& point, int h, int from, int to) const { UniscribeController it(this, run, style); it.advance(from); float beforeWidth = it.runWidthSoFar(); it.advance(to); float afterWidth = it.runWidthSoFar(); // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning if (style.rtl()) { it.advance(run.length()); float totalWidth = it.runWidthSoFar(); return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h); } return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); }
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; }