void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, const FloatPoint& point, int from, int to) const { if (!run.length()) return; TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode(); bool fill = textMode & TextModeFill; bool stroke = (textMode & TextModeStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0; if (!fill && !stroke) return; SkPaint strokePaint, fillPaint; if (fill) { gc->platformContext()->setupPaintForFilling(&fillPaint); setupForTextPainting(&fillPaint, gc->fillColor().rgb()); } if (stroke) { gc->platformContext()->setupPaintForStroking(&strokePaint, 0, 0); setupForTextPainting(&strokePaint, gc->strokeColor().rgb()); } GlyphBuffer glyphBuffer; HarfBuzzShaper shaper(this, run); shaper.setDrawRange(from, to); if (!shaper.shape(&glyphBuffer)) return; FloatPoint adjustedPoint = shaper.adjustStartPoint(point); drawGlyphBuffer(gc, run, glyphBuffer, adjustedPoint); }
void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, const FloatPoint& point, int from, int to) const { if (!run.length()) return; SkCanvas* canvas = gc->platformContext()->canvas(); TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode(); bool fill = textMode & TextModeFill; bool stroke = (textMode & TextModeStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0; if (!fill && !stroke) return; SkPaint strokePaint, fillPaint; if (fill) { gc->platformContext()->setupPaintForFilling(&fillPaint); setupForTextPainting(&fillPaint, gc->fillColor().rgb()); } if (stroke) { gc->platformContext()->setupPaintForStroking(&strokePaint, 0, 0); setupForTextPainting(&strokePaint, gc->strokeColor().rgb()); } ComplexTextController controller(run, point.x(), point.y(), this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); controller.setPadding(run.expansion()); if (run.rtl()) { // FIXME: this causes us to shape the text twice -- once to compute the width and then again // below when actually rendering. Change ComplexTextController to match platform/mac and // platform/chromium/win by having it store the shaped runs, so we can reuse the results. controller.reset(point.x() + controller.widthOfFullRun()); // We need to set the padding again because ComplexTextController layout consumed the value. // Fixing the above problem would help here too. controller.setPadding(run.expansion()); } while (controller.nextScriptRun()) { if (fill) { controller.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); adjustTextRenderMode(&fillPaint, gc->platformContext()); canvas->drawPosText(controller.glyphs(), controller.length() << 1, controller.positions(), fillPaint); } if (stroke) { controller.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); adjustTextRenderMode(&strokePaint, gc->platformContext()); canvas->drawPosText(controller.glyphs(), controller.length() << 1, controller.positions(), strokePaint); } } }
void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, const FloatPoint& point, int from, int to) const { if (!run.length()) return; SkCanvas* canvas = gc->platformContext()->canvas(); TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode(); bool fill = textMode & TextModeFill; bool stroke = (textMode & TextModeStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0; if (!fill && !stroke) return; SkPaint strokePaint, fillPaint; if (fill) { gc->platformContext()->setupPaintForFilling(&fillPaint); setupForTextPainting(&fillPaint, gc->fillColor().rgb()); } if (stroke) { gc->platformContext()->setupPaintForStroking(&strokePaint, 0, 0); setupForTextPainting(&strokePaint, gc->strokeColor().rgb()); } ComplexTextController controller(this, run, point.x(), point.y()); if (run.rtl()) controller.setupForRTL(); while (controller.nextScriptRun()) { // Check if there is any glyph found in the current script run. int fromGlyph, glyphLength; controller.glyphsForRange(from, to, fromGlyph, glyphLength); if (fromGlyph < 0 || glyphLength <= 0) continue; if (fill) { controller.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); adjustTextRenderMode(&fillPaint, gc->platformContext()); canvas->drawPosText(controller.glyphs() + fromGlyph, glyphLength << 1, controller.positions() + fromGlyph, fillPaint); } if (stroke) { controller.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); adjustTextRenderMode(&strokePaint, gc->platformContext()); canvas->drawPosText(controller.glyphs() + fromGlyph, glyphLength << 1, controller.positions() + fromGlyph, strokePaint); } } }
void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, const FloatPoint& point, int from, int to) const { if (!run.length()) return; SkCanvas* canvas = gc->platformContext()->canvas(); int textMode = gc->platformContext()->getTextDrawingMode(); bool fill = textMode & cTextFill; bool stroke = (textMode & cTextStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0; if (!fill && !stroke) return; SkPaint strokePaint, fillPaint; if (fill) { gc->platformContext()->setupPaintForFilling(&fillPaint); setupForTextPainting(&fillPaint, gc->fillColor().rgb()); } if (stroke) { gc->platformContext()->setupPaintForStroking(&strokePaint, 0, 0); setupForTextPainting(&strokePaint, gc->strokeColor().rgb()); } TextRunWalker walker(run, point.x(), this); walker.setWordSpacingAdjustment(wordSpacing()); walker.setLetterSpacingAdjustment(letterSpacing()); walker.setPadding(run.padding()); while (walker.nextScriptRun()) { if (fill) { walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint); adjustTextRenderMode(&fillPaint, gc->platformContext()); canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), fillPaint); } if (stroke) { walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint); adjustTextRenderMode(&strokePaint, gc->platformContext()); canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), strokePaint); } } }