| 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 |