| OLD | NEW | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |    1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "config.h" |    5 #include "config.h" | 
|    6 #include "core/paint/SVGInlineTextBoxPainter.h" |    6 #include "core/paint/SVGInlineTextBoxPainter.h" | 
|    7  |    7  | 
|    8 #include "core/dom/DocumentMarkerController.h" |    8 #include "core/dom/DocumentMarkerController.h" | 
|    9 #include "core/dom/RenderedDocumentMarker.h" |    9 #include "core/dom/RenderedDocumentMarker.h" | 
|   10 #include "core/editing/Editor.h" |   10 #include "core/editing/Editor.h" | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  197         if (renderer->style() && renderer->style()->textDecoration() != TextDeco
     rationNone) |  197         if (renderer->style() && renderer->style()->textDecoration() != TextDeco
     rationNone) | 
|  198             break; |  198             break; | 
|  199  |  199  | 
|  200         parentBox = parentBox->parent(); |  200         parentBox = parentBox->parent(); | 
|  201     } |  201     } | 
|  202  |  202  | 
|  203     ASSERT(renderer); |  203     ASSERT(renderer); | 
|  204     return renderer; |  204     return renderer; | 
|  205 } |  205 } | 
|  206  |  206  | 
|  207 void SVGInlineTextBoxPainter::paintDecoration(GraphicsContext* context, TextDeco
     ration decoration, const SVGTextFragment& fragment) |  | 
|  208 { |  | 
|  209     if (m_svgInlineTextBox.renderer().style()->textDecorationsInEffect() == Text
     DecorationNone) |  | 
|  210         return; |  | 
|  211  |  | 
|  212     // Find out which render style defined the text-decoration, as its fill/stro
     ke properties have to be used for drawing instead of ours. |  | 
|  213     RenderObject* decorationRenderer = findRenderObjectDefininingTextDecoration(
     m_svgInlineTextBox.parent()); |  | 
|  214     RenderStyle* decorationStyle = decorationRenderer->style(); |  | 
|  215     ASSERT(decorationStyle); |  | 
|  216  |  | 
|  217     if (decorationStyle->visibility() == HIDDEN) |  | 
|  218         return; |  | 
|  219  |  | 
|  220     const SVGRenderStyle& svgDecorationStyle = decorationStyle->svgStyle(); |  | 
|  221  |  | 
|  222     for (int i = 0; i < 3; i++) { |  | 
|  223         switch (svgDecorationStyle.paintOrderType(i)) { |  | 
|  224         case PT_FILL: |  | 
|  225             if (svgDecorationStyle.hasFill()) |  | 
|  226                 paintDecorationWithStyle(context, decoration, fragment, decorati
     onRenderer, ApplyToFillMode); |  | 
|  227             break; |  | 
|  228         case PT_STROKE: |  | 
|  229             if (svgDecorationStyle.hasVisibleStroke()) |  | 
|  230                 paintDecorationWithStyle(context, decoration, fragment, decorati
     onRenderer, ApplyToStrokeMode); |  | 
|  231             break; |  | 
|  232         case PT_MARKERS: |  | 
|  233             break; |  | 
|  234         default: |  | 
|  235             ASSERT_NOT_REACHED(); |  | 
|  236         } |  | 
|  237     } |  | 
|  238 } |  | 
|  239  |  207  | 
|  240 // Offset from the baseline for |decoration|. Positive offsets are above the bas
     eline. |  208 // Offset from the baseline for |decoration|. Positive offsets are above the bas
     eline. | 
|  241 static inline float baselineOffsetForDecoration(TextDecoration decoration, const
      FontMetrics& fontMetrics, float thickness) |  209 static inline float baselineOffsetForDecoration(TextDecoration decoration, const
      FontMetrics& fontMetrics, float thickness) | 
|  242 { |  210 { | 
|  243     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
     ace> if specified. |  211     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
     ace> if specified. | 
|  244     // Compatible with Batik/Presto. |  212     // Compatible with Batik/Presto. | 
|  245     if (decoration == TextDecorationUnderline) |  213     if (decoration == TextDecorationUnderline) | 
|  246         return -thickness * 1.5f; |  214         return -thickness * 1.5f; | 
|  247     if (decoration == TextDecorationOverline) |  215     if (decoration == TextDecorationOverline) | 
|  248         return fontMetrics.floatAscent() - thickness; |  216         return fontMetrics.floatAscent() - thickness; | 
|  249     if (decoration == TextDecorationLineThrough) |  217     if (decoration == TextDecorationLineThrough) | 
|  250         return fontMetrics.floatAscent() * 3 / 8.0f; |  218         return fontMetrics.floatAscent() * 3 / 8.0f; | 
|  251  |  219  | 
|  252     ASSERT_NOT_REACHED(); |  220     ASSERT_NOT_REACHED(); | 
|  253     return 0.0f; |  221     return 0.0f; | 
|  254 } |  222 } | 
|  255  |  223  | 
|  256 static inline float thicknessForDecoration(TextDecoration, const Font& font) |  224 static inline float thicknessForDecoration(TextDecoration, const Font& font) | 
|  257 { |  225 { | 
|  258     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
     ace> if specified. |  226     // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
     ace> if specified. | 
|  259     // Compatible with Batik/Presto |  227     // Compatible with Batik/Presto | 
|  260     return font.fontDescription().computedSize() / 20.0f; |  228     return font.fontDescription().computedSize() / 20.0f; | 
|  261 } |  229 } | 
|  262  |  230  | 
|  263 void SVGInlineTextBoxPainter::paintDecorationWithStyle(GraphicsContext* context,
      TextDecoration decoration, |  231 void SVGInlineTextBoxPainter::paintDecoration(GraphicsContext* context, TextDeco
     ration decoration, const SVGTextFragment& fragment) | 
|  264     const SVGTextFragment& fragment, RenderObject* decorationRenderer, RenderSVG
     ResourceMode resourceMode) |  | 
|  265 { |  232 { | 
 |  233     if (m_svgInlineTextBox.renderer().style()->textDecorationsInEffect() == Text
     DecorationNone) | 
 |  234         return; | 
 |  235  | 
 |  236     if (fragment.width <= 0) | 
 |  237         return; | 
 |  238  | 
 |  239     // Find out which render style defined the text-decoration, as its fill/stro
     ke properties have to be used for drawing instead of ours. | 
 |  240     RenderObject* decorationRenderer = findRenderObjectDefininingTextDecoration(
     m_svgInlineTextBox.parent()); | 
|  266     RenderStyle* decorationStyle = decorationRenderer->style(); |  241     RenderStyle* decorationStyle = decorationRenderer->style(); | 
|  267     ASSERT(decorationStyle); |  242     ASSERT(decorationStyle); | 
|  268  |  243  | 
 |  244     if (decorationStyle->visibility() == HIDDEN) | 
 |  245         return; | 
 |  246  | 
|  269     float scalingFactor = 1; |  247     float scalingFactor = 1; | 
|  270     Font scaledFont; |  248     Font scaledFont; | 
|  271     RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decora
     tionStyle, scalingFactor, scaledFont); |  249     RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decora
     tionStyle, scalingFactor, scaledFont); | 
|  272     ASSERT(scalingFactor); |  250     ASSERT(scalingFactor); | 
|  273  |  251  | 
|  274     float thickness = thicknessForDecoration(decoration, scaledFont); |  252     float thickness = thicknessForDecoration(decoration, scaledFont); | 
|  275  |  253     if (thickness <= 0) | 
|  276     if (fragment.width <= 0 && thickness <= 0) |  | 
|  277         return; |  254         return; | 
|  278  |  255  | 
|  279     float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.
     fontMetrics(), thickness); |  256     float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.
     fontMetrics(), thickness); | 
|  280     FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal
     ingFactor); |  257     FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal
     ingFactor); | 
|  281  |  258  | 
|  282     Path path; |  259     Path path; | 
|  283     path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness
      / scalingFactor))); |  260     path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness
      / scalingFactor))); | 
|  284  |  261  | 
|  285     GraphicsContextStateSaver stateSaver(*context, false); |  262     const SVGRenderStyle& svgDecorationStyle = decorationStyle->svgStyle(); | 
|  286     if (!SVGRenderSupport::updateGraphicsContext(stateSaver, decorationStyle, *d
     ecorationRenderer, resourceMode)) |  263  | 
|  287         return; |  264     for (int i = 0; i < 3; i++) { | 
|  288     SVGRenderSupport::fillOrStrokePath(context, resourceMode, path); |  265         switch (svgDecorationStyle.paintOrderType(i)) { | 
 |  266         case PT_FILL: | 
 |  267             if (svgDecorationStyle.hasFill()) { | 
 |  268                 GraphicsContextStateSaver stateSaver(*context, false); | 
 |  269                 if (!SVGRenderSupport::updateGraphicsContext(stateSaver, decorat
     ionStyle, *decorationRenderer, ApplyToFillMode)) | 
 |  270                     break; | 
 |  271                 context->fillPath(path); | 
 |  272             } | 
 |  273             break; | 
 |  274         case PT_STROKE: | 
 |  275             if (svgDecorationStyle.hasVisibleStroke()) { | 
 |  276                 GraphicsContextStateSaver stateSaver(*context, false); | 
 |  277                 if (!SVGRenderSupport::updateGraphicsContext(stateSaver, decorat
     ionStyle, *decorationRenderer, ApplyToStrokeMode)) | 
 |  278                     break; | 
 |  279                 context->strokePath(path); | 
 |  280             } | 
 |  281             break; | 
 |  282         case PT_MARKERS: | 
 |  283             break; | 
 |  284         default: | 
 |  285             ASSERT_NOT_REACHED(); | 
 |  286         } | 
 |  287     } | 
|  289 } |  288 } | 
|  290  |  289  | 
|  291 void SVGInlineTextBoxPainter::paintTextWithShadows(GraphicsContext* context, Ren
     derStyle* style, |  290 void SVGInlineTextBoxPainter::paintTextWithShadows(GraphicsContext* context, Ren
     derStyle* style, | 
|  292     TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
     dPosition, |  291     TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
     dPosition, | 
|  293     RenderSVGResourceMode resourceMode) |  292     RenderSVGResourceMode resourceMode) | 
|  294 { |  293 { | 
|  295     RenderSVGInlineText& textRenderer = toRenderSVGInlineText(m_svgInlineTextBox
     .renderer()); |  294     RenderSVGInlineText& textRenderer = toRenderSVGInlineText(m_svgInlineTextBox
     .renderer()); | 
|  296  |  295  | 
|  297     float scalingFactor = textRenderer.scalingFactor(); |  296     float scalingFactor = textRenderer.scalingFactor(); | 
|  298     ASSERT(scalingFactor); |  297     ASSERT(scalingFactor); | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  432  |  431  | 
|  433             fragmentRect = fragmentTransform.mapRect(fragmentRect); |  432             fragmentRect = fragmentTransform.mapRect(fragmentRect); | 
|  434             markerRect.unite(fragmentRect); |  433             markerRect.unite(fragmentRect); | 
|  435         } |  434         } | 
|  436     } |  435     } | 
|  437  |  436  | 
|  438     toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu
     teQuad(markerRect).enclosingBoundingBox()); |  437     toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsolu
     teQuad(markerRect).enclosingBoundingBox()); | 
|  439 } |  438 } | 
|  440  |  439  | 
|  441 } // namespace blink |  440 } // namespace blink | 
| OLD | NEW |