// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/paint/SVGInlineTextBoxPainter.h"

#include <memory>
#include "core/editing/Editor.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/editing/markers/TextMatchMarker.h"
#include "core/frame/LocalFrame.h"
#include "core/layout/LayoutTheme.h"
#include "core/layout/api/LineLayoutAPIShim.h"
#include "core/layout/api/SelectionState.h"
#include "core/layout/line/InlineFlowBox.h"
#include "core/layout/svg/LayoutSVGInlineText.h"
#include "core/layout/svg/SVGLayoutSupport.h"
#include "core/layout/svg/SVGResourcesCache.h"
#include "core/layout/svg/line/SVGInlineTextBox.h"
#include "core/paint/InlineTextBoxPainter.h"
#include "core/paint/LayoutObjectDrawingRecorder.h"
#include "core/paint/PaintInfo.h"
#include "core/paint/SVGPaintContext.h"
#include "core/style/AppliedTextDecoration.h"
#include "core/style/ShadowList.h"
#include "platform/graphics/GraphicsContextStateSaver.h"

namespace blink {

static inline bool TextShouldBePainted(
    const LayoutSVGInlineText& text_layout_object) {
  // Font::pixelSize(), returns FontDescription::computedPixelSize(), which
  // returns "int(x + 0.5)".  If the absolute font size on screen is below
  // x=0.5, don't render anything.
  return text_layout_object.ScaledFont()
      .GetFontDescription()
      .ComputedPixelSize();
}

bool SVGInlineTextBoxPainter::ShouldPaintSelection(
    const PaintInfo& paint_info) const {
  // Don't paint selections when printing.
  if (paint_info.IsPrinting())
    return false;
  // Don't paint selections when rendering a mask, clip-path (as a mask),
  // pattern or feImage (element reference.)
  if (paint_info.IsRenderingResourceSubtree())
    return false;
  return svg_inline_text_box_.GetSelectionState() != SelectionState::kNone;
}

static bool HasShadow(const PaintInfo& paint_info, const ComputedStyle& style) {
  // Text shadows are disabled when printing. http://crbug.com/258321
  return style.TextShadow() && !paint_info.IsPrinting();
}

FloatRect SVGInlineTextBoxPainter::BoundsForDrawingRecorder(
    const PaintInfo& paint_info,
    const ComputedStyle& style,
    const LayoutPoint& paint_offset,
    bool include_selection_rect) const {
  LayoutRect bounds(svg_inline_text_box_.Location() + paint_offset,
                    svg_inline_text_box_.Size());
  if (HasShadow(paint_info, style))
    bounds.Expand(style.TextShadow()->RectOutsetsIncludingOriginal());
  if (include_selection_rect) {
    bounds.Unite(svg_inline_text_box_.LocalSelectionRect(
        svg_inline_text_box_.Start(),
        svg_inline_text_box_.Start() + svg_inline_text_box_.Len()));
  }
  return FloatRect(bounds);
}

LayoutObject& SVGInlineTextBoxPainter::InlineLayoutObject() const {
  return *LineLayoutAPIShim::LayoutObjectFrom(
      svg_inline_text_box_.GetLineLayoutItem());
}

LayoutObject& SVGInlineTextBoxPainter::ParentInlineLayoutObject() const {
  return *LineLayoutAPIShim::LayoutObjectFrom(
      svg_inline_text_box_.Parent()->GetLineLayoutItem());
}

LayoutSVGInlineText& SVGInlineTextBoxPainter::InlineText() const {
  return ToLayoutSVGInlineText(InlineLayoutObject());
}

void SVGInlineTextBoxPainter::Paint(const PaintInfo& paint_info,
                                    const LayoutPoint& paint_offset) {
  DCHECK(paint_info.phase == kPaintPhaseForeground ||
         paint_info.phase == kPaintPhaseSelection);
  DCHECK(svg_inline_text_box_.Truncation() == kCNoTruncation);

  if (svg_inline_text_box_.GetLineLayoutItem().Style()->Visibility() !=
          EVisibility::kVisible ||
      !svg_inline_text_box_.Len())
    return;

  // We're explicitly not supporting composition & custom underlines and custom
  // highlighters -- unlike InlineTextBox.  If we ever need that for SVG, it's
  // very easy to refactor and reuse the code.

  bool have_selection = ShouldPaintSelection(paint_info);
  if (!have_selection && paint_info.phase == kPaintPhaseSelection)
    return;

  LayoutSVGInlineText& text_layout_object = InlineText();
  if (!TextShouldBePainted(text_layout_object))
    return;

  DisplayItem::Type display_item_type =
      DisplayItem::PaintPhaseToDrawingType(paint_info.phase);
  if (!DrawingRecorder::UseCachedDrawingIfPossible(
          paint_info.context, svg_inline_text_box_, display_item_type)) {
    LayoutObject& parent_layout_object = ParentInlineLayoutObject();
    const ComputedStyle& style = parent_layout_object.StyleRef();

    bool include_selection_rect =
        paint_info.phase != kPaintPhaseSelection &&
        (have_selection ||
         InlineTextBoxPainter::PaintsMarkerHighlights(text_layout_object));
    DrawingRecorder recorder(
        paint_info.context, svg_inline_text_box_, display_item_type,
        BoundsForDrawingRecorder(paint_info, style, paint_offset,
                                 include_selection_rect));
    InlineTextBoxPainter text_painter(svg_inline_text_box_);
    text_painter.PaintDocumentMarkers(paint_info, paint_offset, style,
                                      text_layout_object.ScaledFont(),
                                      DocumentMarkerPaintPhase::kBackground);

    if (!svg_inline_text_box_.TextFragments().IsEmpty())
      PaintTextFragments(paint_info, parent_layout_object);

    text_painter.PaintDocumentMarkers(paint_info, paint_offset, style,
                                      text_layout_object.ScaledFont(),
                                      DocumentMarkerPaintPhase::kForeground);
  }
}

void SVGInlineTextBoxPainter::PaintTextFragments(
    const PaintInfo& paint_info,
    LayoutObject& parent_layout_object) {
  const ComputedStyle& style = parent_layout_object.StyleRef();
  const SVGComputedStyle& svg_style = style.SvgStyle();

  bool has_fill = svg_style.HasFill();
  bool has_visible_stroke = svg_style.HasVisibleStroke();

  const ComputedStyle* selection_style = &style;
  bool should_paint_selection = this->ShouldPaintSelection(paint_info);
  if (should_paint_selection) {
    selection_style =
        parent_layout_object.GetCachedPseudoStyle(kPseudoIdSelection);
    if (selection_style) {
      const SVGComputedStyle& svg_selection_style = selection_style->SvgStyle();

      if (!has_fill)
        has_fill = svg_selection_style.HasFill();
      if (!has_visible_stroke)
        has_visible_stroke = svg_selection_style.HasVisibleStroke();
    } else {
      selection_style = &style;
    }
  }

  if (paint_info.IsRenderingClipPathAsMaskImage()) {
    has_fill = true;
    has_visible_stroke = false;
  }

  for (const SVGTextFragment& fragment : svg_inline_text_box_.TextFragments()) {
    GraphicsContextStateSaver state_saver(paint_info.context, false);
    if (fragment.IsTransformed()) {
      state_saver.Save();
      paint_info.context.ConcatCTM(fragment.BuildFragmentTransform());
    }

    // Spec: All text decorations except line-through should be drawn before the
    // text is filled and stroked; thus, the text is rendered on top of these
    // decorations.
    const Vector<AppliedTextDecoration>& decorations =
        style.AppliedTextDecorations();
    for (const AppliedTextDecoration& decoration : decorations) {
      if (EnumHasFlags(decoration.Lines(), TextDecoration::kUnderline))
        PaintDecoration(paint_info, TextDecoration::kUnderline, fragment);
      if (EnumHasFlags(decoration.Lines(), TextDecoration::kOverline))
        PaintDecoration(paint_info, TextDecoration::kOverline, fragment);
    }

    for (int i = 0; i < 3; i++) {
      switch (svg_style.PaintOrderType(i)) {
        case PT_FILL:
          if (has_fill)
            PaintText(paint_info, style, *selection_style, fragment,
                      kApplyToFillMode, should_paint_selection);
          break;
        case PT_STROKE:
          if (has_visible_stroke)
            PaintText(paint_info, style, *selection_style, fragment,
                      kApplyToStrokeMode, should_paint_selection);
          break;
        case PT_MARKERS:
          // Markers don't apply to text
          break;
        default:
          NOTREACHED();
          break;
      }
    }

    // Spec: Line-through should be drawn after the text is filled and stroked;
    // thus, the line-through is rendered on top of the text.
    for (const AppliedTextDecoration& decoration : decorations) {
      if (EnumHasFlags(decoration.Lines(), TextDecoration::kLineThrough))
        PaintDecoration(paint_info, TextDecoration::kLineThrough, fragment);
    }
  }
}

void SVGInlineTextBoxPainter::PaintSelectionBackground(
    const PaintInfo& paint_info) {
  if (svg_inline_text_box_.GetLineLayoutItem().Style()->Visibility() !=
      EVisibility::kVisible)
    return;

  DCHECK(!paint_info.IsPrinting());

  if (paint_info.phase == kPaintPhaseSelection ||
      !ShouldPaintSelection(paint_info))
    return;

  Color background_color =
      svg_inline_text_box_.GetLineLayoutItem().SelectionBackgroundColor();
  if (!background_color.Alpha())
    return;

  LayoutSVGInlineText& text_layout_object = InlineText();
  if (!TextShouldBePainted(text_layout_object))
    return;

  const ComputedStyle& style =
      svg_inline_text_box_.Parent()->GetLineLayoutItem().StyleRef();

  int start_position, end_position;
  svg_inline_text_box_.SelectionStartEnd(start_position, end_position);

  const Vector<SVGTextFragmentWithRange> fragment_info_list =
      CollectFragmentsInRange(start_position, end_position);
  for (const SVGTextFragmentWithRange& fragment_with_range :
       fragment_info_list) {
    const SVGTextFragment& fragment = fragment_with_range.fragment;
    GraphicsContextStateSaver state_saver(paint_info.context);
    if (fragment.IsTransformed())
      paint_info.context.ConcatCTM(fragment.BuildFragmentTransform());

    paint_info.context.SetFillColor(background_color);
    paint_info.context.FillRect(
        svg_inline_text_box_.SelectionRectForTextFragment(
            fragment, fragment_with_range.start_position,
            fragment_with_range.end_position, style),
        background_color);
  }
}

static inline LayoutObject* FindLayoutObjectDefininingTextDecoration(
    InlineFlowBox* parent_box) {
  // Lookup first layout object in parent hierarchy which has text-decoration
  // set.
  LayoutObject* layout_object = nullptr;
  while (parent_box) {
    layout_object =
        LineLayoutAPIShim::LayoutObjectFrom(parent_box->GetLineLayoutItem());

    if (layout_object->Style() &&
        layout_object->Style()->GetTextDecoration() != TextDecoration::kNone)
      break;

    parent_box = parent_box->Parent();
  }

  DCHECK(layout_object);
  return layout_object;
}

// Offset from the baseline for |decoration|. Positive offsets are above the
// baseline.
static inline float BaselineOffsetForDecoration(TextDecoration decoration,
                                                const FontMetrics& font_metrics,
                                                float thickness) {
  // FIXME: For SVG Fonts we need to use the attributes defined in the
  // <font-face> if specified.
  // Compatible with Batik/Presto.
  if (decoration == TextDecoration::kUnderline)
    return -thickness * 1.5f;
  if (decoration == TextDecoration::kOverline)
    return font_metrics.FloatAscent() - thickness;
  if (decoration == TextDecoration::kLineThrough)
    return font_metrics.FloatAscent() * 3 / 8.0f;

  NOTREACHED();
  return 0.0f;
}

static inline float ThicknessForDecoration(TextDecoration, const Font& font) {
  // FIXME: For SVG Fonts we need to use the attributes defined in the
  // <font-face> if specified.
  // Compatible with Batik/Presto
  return font.GetFontDescription().ComputedSize() / 20.0f;
}

void SVGInlineTextBoxPainter::PaintDecoration(const PaintInfo& paint_info,
                                              TextDecoration decoration,
                                              const SVGTextFragment& fragment) {
  if (svg_inline_text_box_.GetLineLayoutItem()
          .Style()
          ->TextDecorationsInEffect() == TextDecoration::kNone)
    return;

  if (fragment.width <= 0)
    return;

  // Find out which style defined the text-decoration, as its fill/stroke
  // properties have to be used for drawing instead of ours.
  LayoutObject* decoration_layout_object =
      FindLayoutObjectDefininingTextDecoration(svg_inline_text_box_.Parent());
  const ComputedStyle& decoration_style = decoration_layout_object->StyleRef();

  if (decoration_style.Visibility() != EVisibility::kVisible)
    return;

  float scaling_factor = 1;
  Font scaled_font;
  LayoutSVGInlineText::ComputeNewScaledFontForStyle(
      *decoration_layout_object, scaling_factor, scaled_font);
  DCHECK(scaling_factor);

  float thickness = ThicknessForDecoration(decoration, scaled_font);
  if (thickness <= 0)
    return;

  const SimpleFontData* font_data = scaled_font.PrimaryFont();
  DCHECK(font_data);
  if (!font_data)
    return;

  float decoration_offset = BaselineOffsetForDecoration(
      decoration, font_data->GetFontMetrics(), thickness);
  FloatPoint decoration_origin(fragment.x,
                               fragment.y - decoration_offset / scaling_factor);

  Path path;
  path.AddRect(
      FloatRect(decoration_origin,
                FloatSize(fragment.width, thickness / scaling_factor)));

  const SVGComputedStyle& svg_decoration_style = decoration_style.SvgStyle();

  for (int i = 0; i < 3; i++) {
    switch (svg_decoration_style.PaintOrderType(i)) {
      case PT_FILL:
        if (svg_decoration_style.HasFill()) {
          PaintFlags fill_flags;
          if (!SVGPaintContext::PaintForLayoutObject(
                  paint_info, decoration_style, *decoration_layout_object,
                  kApplyToFillMode, fill_flags))
            break;
          fill_flags.setAntiAlias(true);
          paint_info.context.DrawPath(path.GetSkPath(), fill_flags);
        }
        break;
      case PT_STROKE:
        if (svg_decoration_style.HasVisibleStroke()) {
          PaintFlags stroke_flags;
          if (!SVGPaintContext::PaintForLayoutObject(
                  paint_info, decoration_style, *decoration_layout_object,
                  kApplyToStrokeMode, stroke_flags))
            break;
          stroke_flags.setAntiAlias(true);
          float stroke_scale_factor =
              svg_decoration_style.VectorEffect() == VE_NON_SCALING_STROKE
                  ? 1 / scaling_factor
                  : 1;
          StrokeData stroke_data;
          SVGLayoutSupport::ApplyStrokeStyleToStrokeData(
              stroke_data, decoration_style, *decoration_layout_object,
              stroke_scale_factor);
          if (stroke_scale_factor != 1)
            stroke_data.SetThickness(stroke_data.Thickness() *
                                     stroke_scale_factor);
          stroke_data.SetupPaint(&stroke_flags);
          paint_info.context.DrawPath(path.GetSkPath(), stroke_flags);
        }
        break;
      case PT_MARKERS:
        break;
      default:
        NOTREACHED();
    }
  }
}

bool SVGInlineTextBoxPainter::SetupTextPaint(
    const PaintInfo& paint_info,
    const ComputedStyle& style,
    LayoutSVGResourceMode resource_mode,
    PaintFlags& flags) {
  LayoutSVGInlineText& text_layout_object = InlineText();

  float scaling_factor = text_layout_object.ScalingFactor();
  DCHECK(scaling_factor);

  AffineTransform paint_server_transform;
  const AffineTransform* additional_paint_server_transform = nullptr;

  if (scaling_factor != 1) {
    // Adjust the paint-server coordinate space.
    paint_server_transform.Scale(scaling_factor);
    additional_paint_server_transform = &paint_server_transform;
  }

  if (!SVGPaintContext::PaintForLayoutObject(
          paint_info, style, ParentInlineLayoutObject(), resource_mode, flags,
          additional_paint_server_transform))
    return false;
  flags.setAntiAlias(true);

  if (HasShadow(paint_info, style)) {
    flags.setLooper(style.TextShadow()->CreateDrawLooper(
        DrawLooperBuilder::kShadowRespectsAlpha,
        style.VisitedDependentColor(CSSPropertyColor)));
  }

  if (resource_mode == kApplyToStrokeMode) {
    // The stroke geometry needs be generated based on the scaled font.
    float stroke_scale_factor =
        style.SvgStyle().VectorEffect() != VE_NON_SCALING_STROKE
            ? scaling_factor
            : 1;
    StrokeData stroke_data;
    SVGLayoutSupport::ApplyStrokeStyleToStrokeData(
        stroke_data, style, ParentInlineLayoutObject(), stroke_scale_factor);
    if (stroke_scale_factor != 1)
      stroke_data.SetThickness(stroke_data.Thickness() * stroke_scale_factor);
    stroke_data.SetupPaint(&flags);
  }
  return true;
}

void SVGInlineTextBoxPainter::PaintText(const PaintInfo& paint_info,
                                        TextRun& text_run,
                                        const SVGTextFragment& fragment,
                                        int start_position,
                                        int end_position,
                                        const PaintFlags& flags) {
  LayoutSVGInlineText& text_layout_object = InlineText();
  const Font& scaled_font = text_layout_object.ScaledFont();

  float scaling_factor = text_layout_object.ScalingFactor();
  DCHECK(scaling_factor);

  FloatPoint text_origin(fragment.x, fragment.y);
  FloatSize text_size(fragment.width, fragment.height);

  GraphicsContext& context = paint_info.context;
  GraphicsContextStateSaver state_saver(context, false);
  if (scaling_factor != 1) {
    text_origin.Scale(scaling_factor, scaling_factor);
    text_size.Scale(scaling_factor);
    state_saver.Save();
    context.Scale(1 / scaling_factor, 1 / scaling_factor);
  }

  TextRunPaintInfo text_run_paint_info(text_run);
  text_run_paint_info.from = start_position;
  text_run_paint_info.to = end_position;

  const SimpleFontData* font_data = scaled_font.PrimaryFont();
  DCHECK(font_data);
  if (!font_data)
    return;
  float baseline = font_data->GetFontMetrics().FloatAscent();
  text_run_paint_info.bounds =
      FloatRect(text_origin.X(), text_origin.Y() - baseline, text_size.Width(),
                text_size.Height());

  context.DrawText(scaled_font, text_run_paint_info, text_origin, flags);
}

void SVGInlineTextBoxPainter::PaintText(const PaintInfo& paint_info,
                                        const ComputedStyle& style,
                                        const ComputedStyle& selection_style,
                                        const SVGTextFragment& fragment,
                                        LayoutSVGResourceMode resource_mode,
                                        bool should_paint_selection) {
  int start_position = 0;
  int end_position = 0;
  if (should_paint_selection) {
    svg_inline_text_box_.SelectionStartEnd(start_position, end_position);
    should_paint_selection =
        svg_inline_text_box_.MapStartEndPositionsIntoFragmentCoordinates(
            fragment, start_position, end_position);
  }

  // Fast path if there is no selection, just draw the whole chunk part using
  // the regular style.
  TextRun text_run = svg_inline_text_box_.ConstructTextRun(style, fragment);
  if (!should_paint_selection || start_position >= end_position) {
    PaintFlags flags;
    if (SetupTextPaint(paint_info, style, resource_mode, flags))
      PaintText(paint_info, text_run, fragment, 0, fragment.length, flags);
    return;
  }

  // Eventually draw text using regular style until the start position of the
  // selection.
  bool paint_selected_text_only = paint_info.phase == kPaintPhaseSelection;
  if (start_position > 0 && !paint_selected_text_only) {
    PaintFlags flags;
    if (SetupTextPaint(paint_info, style, resource_mode, flags))
      PaintText(paint_info, text_run, fragment, 0, start_position, flags);
  }

  // Draw text using selection style from the start to the end position of the
  // selection.
  {
    SVGResourcesCache::TemporaryStyleScope scope(ParentInlineLayoutObject(),
                                                 style, selection_style);

    PaintFlags flags;
    if (SetupTextPaint(paint_info, selection_style, resource_mode, flags)) {
      PaintText(paint_info, text_run, fragment, start_position, end_position,
                flags);
    }
  }

  // Eventually draw text using regular style from the end position of the
  // selection to the end of the current chunk part.
  if (end_position < static_cast<int>(fragment.length) &&
      !paint_selected_text_only) {
    PaintFlags flags;
    if (SetupTextPaint(paint_info, style, resource_mode, flags)) {
      PaintText(paint_info, text_run, fragment, end_position, fragment.length,
                flags);
    }
  }
}

Vector<SVGTextFragmentWithRange> SVGInlineTextBoxPainter::CollectTextMatches(
    const DocumentMarker& marker) const {
  const Vector<SVGTextFragmentWithRange> empty_text_match_list;

  // SVG does not support grammar or spellcheck markers, so skip anything but
  // TextMatch.
  if (marker.GetType() != DocumentMarker::kTextMatch)
    return empty_text_match_list;

  if (!InlineLayoutObject()
           .GetFrame()
           ->GetEditor()
           .MarkedTextMatchesAreHighlighted())
    return empty_text_match_list;

  int marker_start_position =
      std::max<int>(marker.StartOffset() - svg_inline_text_box_.Start(), 0);
  int marker_end_position =
      std::min<int>(marker.EndOffset() - svg_inline_text_box_.Start(),
                    svg_inline_text_box_.Len());

  if (marker_start_position >= marker_end_position)
    return empty_text_match_list;

  return CollectFragmentsInRange(marker_start_position, marker_end_position);
}

Vector<SVGTextFragmentWithRange>
SVGInlineTextBoxPainter::CollectFragmentsInRange(int start_position,
                                                 int end_position) const {
  Vector<SVGTextFragmentWithRange> fragment_info_list;
  for (const SVGTextFragment& fragment : svg_inline_text_box_.TextFragments()) {
    // TODO(ramya.v): If these can't be negative we should use unsigned.
    int fragment_start_position = start_position;
    int fragment_end_position = end_position;
    if (!svg_inline_text_box_.MapStartEndPositionsIntoFragmentCoordinates(
            fragment, fragment_start_position, fragment_end_position))
      continue;

    fragment_info_list.push_back(SVGTextFragmentWithRange(
        fragment, fragment_start_position, fragment_end_position));
  }
  return fragment_info_list;
}

void SVGInlineTextBoxPainter::PaintTextMatchMarkerForeground(
    const PaintInfo& paint_info,
    const LayoutPoint& point,
    const TextMatchMarker& marker,
    const ComputedStyle& style,
    const Font& font) {
  const Vector<SVGTextFragmentWithRange> text_match_info_list =
      CollectTextMatches(marker);
  if (text_match_info_list.IsEmpty())
    return;

  Color text_color =
      LayoutTheme::GetTheme().PlatformTextSearchColor(marker.IsActiveMatch());

  PaintFlags fill_flags;
  fill_flags.setColor(text_color.Rgb());
  fill_flags.setAntiAlias(true);

  PaintFlags stroke_flags;
  bool should_paint_stroke = false;
  if (SetupTextPaint(paint_info, style, kApplyToStrokeMode, stroke_flags)) {
    should_paint_stroke = true;
    stroke_flags.setLooper(nullptr);
    stroke_flags.setColor(text_color.Rgb());
  }

  for (const SVGTextFragmentWithRange& text_match_info : text_match_info_list) {
    const SVGTextFragment& fragment = text_match_info.fragment;
    GraphicsContextStateSaver state_saver(paint_info.context);
    if (fragment.IsTransformed())
      paint_info.context.ConcatCTM(fragment.BuildFragmentTransform());

    TextRun text_run = svg_inline_text_box_.ConstructTextRun(style, fragment);
    PaintText(paint_info, text_run, fragment, text_match_info.start_position,
              text_match_info.end_position, fill_flags);
    if (should_paint_stroke) {
      PaintText(paint_info, text_run, fragment, text_match_info.start_position,
                text_match_info.end_position, stroke_flags);
    }
  }
}

void SVGInlineTextBoxPainter::PaintTextMatchMarkerBackground(
    const PaintInfo& paint_info,
    const LayoutPoint& point,
    const TextMatchMarker& marker,
    const ComputedStyle& style,
    const Font& font) {
  const Vector<SVGTextFragmentWithRange> text_match_info_list =
      CollectTextMatches(marker);
  if (text_match_info_list.IsEmpty())
    return;

  Color color = LayoutTheme::GetTheme().PlatformTextSearchHighlightColor(
      marker.IsActiveMatch());
  for (const SVGTextFragmentWithRange& text_match_info : text_match_info_list) {
    const SVGTextFragment& fragment = text_match_info.fragment;

    GraphicsContextStateSaver state_saver(paint_info.context, false);
    if (fragment.IsTransformed()) {
      state_saver.Save();
      paint_info.context.ConcatCTM(fragment.BuildFragmentTransform());
    }
    FloatRect fragment_rect = svg_inline_text_box_.SelectionRectForTextFragment(
        fragment, text_match_info.start_position, text_match_info.end_position,
        style);
    paint_info.context.SetFillColor(color);
    paint_info.context.FillRect(fragment_rect);
  }
}

}  // namespace blink
