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/editing/Editor.h" | 8 #include "core/editing/Editor.h" |
9 #include "core/editing/markers/DocumentMarkerController.h" | 9 #include "core/editing/markers/DocumentMarkerController.h" |
10 #include "core/editing/markers/RenderedDocumentMarker.h" | 10 #include "core/editing/markers/RenderedDocumentMarker.h" |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 } | 289 } |
290 break; | 290 break; |
291 case PT_MARKERS: | 291 case PT_MARKERS: |
292 break; | 292 break; |
293 default: | 293 default: |
294 ASSERT_NOT_REACHED(); | 294 ASSERT_NOT_REACHED(); |
295 } | 295 } |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 void SVGInlineTextBoxPainter::paintTextWithShadows(const PaintInfo& paintInfo, c
onst ComputedStyle& style, | 299 bool SVGInlineTextBoxPainter::setupTextPaint(const PaintInfo& paintInfo, const C
omputedStyle& style, |
300 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, | 300 LayoutSVGResourceMode resourceMode, SkPaint& paint) |
301 LayoutSVGResourceMode resourceMode) | |
302 { | 301 { |
303 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai
ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); | 302 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai
ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); |
304 | 303 |
305 float scalingFactor = textLayoutObject.scalingFactor(); | 304 float scalingFactor = textLayoutObject.scalingFactor(); |
306 ASSERT(scalingFactor); | 305 ASSERT(scalingFactor); |
307 | 306 |
308 const Font& scaledFont = textLayoutObject.scaledFont(); | |
309 const ShadowList* shadowList = style.textShadow(); | 307 const ShadowList* shadowList = style.textShadow(); |
310 GraphicsContext& context = paintInfo.context; | |
311 | 308 |
312 // Text shadows are disabled when printing. http://crbug.com/258321 | 309 // Text shadows are disabled when printing. http://crbug.com/258321 |
313 bool hasShadow = shadowList && !paintInfo.isPrinting(); | 310 bool hasShadow = shadowList && !paintInfo.isPrinting(); |
314 | 311 |
315 FloatPoint textOrigin(fragment.x, fragment.y); | |
316 FloatSize textSize(fragment.width, fragment.height); | |
317 AffineTransform paintServerTransform; | 312 AffineTransform paintServerTransform; |
318 const AffineTransform* additionalPaintServerTransform = 0; | 313 const AffineTransform* additionalPaintServerTransform = 0; |
319 | 314 |
320 GraphicsContextStateSaver stateSaver(context, false); | |
321 if (scalingFactor != 1) { | 315 if (scalingFactor != 1) { |
322 textOrigin.scale(scalingFactor, scalingFactor); | |
323 textSize.scale(scalingFactor); | |
324 stateSaver.save(); | |
325 context.scale(1 / scalingFactor, 1 / scalingFactor); | |
326 // Adjust the paint-server coordinate space. | 316 // Adjust the paint-server coordinate space. |
327 paintServerTransform.scale(scalingFactor); | 317 paintServerTransform.scale(scalingFactor); |
328 additionalPaintServerTransform = &paintServerTransform; | 318 additionalPaintServerTransform = &paintServerTransform; |
329 } | 319 } |
330 | 320 |
331 SkPaint paint; | |
332 if (!SVGPaintContext::paintForLayoutObject(paintInfo, style, *LineLayoutPain
tShim::layoutObjectFrom(m_svgInlineTextBox.parent()->lineLayoutItem()), resource
Mode, paint, additionalPaintServerTransform)) | 321 if (!SVGPaintContext::paintForLayoutObject(paintInfo, style, *LineLayoutPain
tShim::layoutObjectFrom(m_svgInlineTextBox.parent()->lineLayoutItem()), resource
Mode, paint, additionalPaintServerTransform)) |
333 return; | 322 return false; |
334 paint.setAntiAlias(true); | 323 paint.setAntiAlias(true); |
335 | 324 |
336 if (hasShadow) { | 325 if (hasShadow) { |
337 OwnPtr<DrawLooperBuilder> drawLooperBuilder = shadowList->createDrawLoop
er(DrawLooperBuilder::ShadowRespectsAlpha, style.visitedDependentColor(CSSProper
tyColor)); | 326 OwnPtr<DrawLooperBuilder> drawLooperBuilder = shadowList->createDrawLoop
er(DrawLooperBuilder::ShadowRespectsAlpha, style.visitedDependentColor(CSSProper
tyColor)); |
338 RefPtr<SkDrawLooper> drawLooper = drawLooperBuilder->detachDrawLooper(); | 327 RefPtr<SkDrawLooper> drawLooper = drawLooperBuilder->detachDrawLooper(); |
339 paint.setLooper(drawLooper.get()); | 328 paint.setLooper(drawLooper.get()); |
340 } | 329 } |
341 | 330 |
342 if (resourceMode == ApplyToStrokeMode) { | 331 if (resourceMode == ApplyToStrokeMode) { |
343 StrokeData strokeData; | 332 StrokeData strokeData; |
344 SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, style, *LineL
ayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.parent()->lineLayoutItem()))
; | 333 SVGLayoutSupport::applyStrokeStyleToStrokeData(strokeData, style, *LineL
ayoutPaintShim::layoutObjectFrom(m_svgInlineTextBox.parent()->lineLayoutItem()))
; |
345 if (style.svgStyle().vectorEffect() != VE_NON_SCALING_STROKE) | 334 if (style.svgStyle().vectorEffect() != VE_NON_SCALING_STROKE) |
346 strokeData.setThickness(strokeData.thickness() * scalingFactor); | 335 strokeData.setThickness(strokeData.thickness() * scalingFactor); |
347 strokeData.setupPaint(&paint); | 336 strokeData.setupPaint(&paint); |
348 } | 337 } |
| 338 return true; |
| 339 } |
| 340 |
| 341 void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, TextRun& tex
tRun, const SVGTextFragment& fragment, int startPosition, int endPosition, const
SkPaint& paint) |
| 342 { |
| 343 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai
ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); |
| 344 const Font& scaledFont = textLayoutObject.scaledFont(); |
| 345 |
| 346 float scalingFactor = textLayoutObject.scalingFactor(); |
| 347 ASSERT(scalingFactor); |
| 348 |
| 349 FloatPoint textOrigin(fragment.x, fragment.y); |
| 350 FloatSize textSize(fragment.width, fragment.height); |
| 351 |
| 352 GraphicsContext& context = paintInfo.context; |
| 353 GraphicsContextStateSaver stateSaver(context, false); |
| 354 if (scalingFactor != 1) { |
| 355 textOrigin.scale(scalingFactor, scalingFactor); |
| 356 textSize.scale(scalingFactor); |
| 357 stateSaver.save(); |
| 358 context.scale(1 / scalingFactor, 1 / scalingFactor); |
| 359 } |
349 | 360 |
350 TextRunPaintInfo textRunPaintInfo(textRun); | 361 TextRunPaintInfo textRunPaintInfo(textRun); |
351 textRunPaintInfo.from = startPosition; | 362 textRunPaintInfo.from = startPosition; |
352 textRunPaintInfo.to = endPosition; | 363 textRunPaintInfo.to = endPosition; |
353 | 364 |
354 float baseline = scaledFont.fontMetrics().floatAscent(); | 365 float baseline = scaledFont.fontMetrics().floatAscent(); |
355 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baselin
e, | 366 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - baselin
e, |
356 textSize.width(), textSize.height()); | 367 textSize.width(), textSize.height()); |
357 | 368 |
358 context.drawText(scaledFont, textRunPaintInfo, textOrigin, paint); | 369 context.drawText(scaledFont, textRunPaintInfo, textOrigin, paint); |
359 } | 370 } |
360 | 371 |
361 void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, const Comput
edStyle& style, | 372 void SVGInlineTextBoxPainter::paintText(const PaintInfo& paintInfo, const Comput
edStyle& style, |
362 const ComputedStyle& selectionStyle, const SVGTextFragment& fragment, | 373 const ComputedStyle& selectionStyle, const SVGTextFragment& fragment, |
363 LayoutSVGResourceMode resourceMode, bool shouldPaintSelection) | 374 LayoutSVGResourceMode resourceMode, bool shouldPaintSelection) |
364 { | 375 { |
365 int startPosition = 0; | 376 int startPosition = 0; |
366 int endPosition = 0; | 377 int endPosition = 0; |
367 if (shouldPaintSelection) { | 378 if (shouldPaintSelection) { |
368 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); | 379 m_svgInlineTextBox.selectionStartEnd(startPosition, endPosition); |
369 shouldPaintSelection = m_svgInlineTextBox.mapStartEndPositionsIntoFragme
ntCoordinates(fragment, startPosition, endPosition); | 380 shouldPaintSelection = m_svgInlineTextBox.mapStartEndPositionsIntoFragme
ntCoordinates(fragment, startPosition, endPosition); |
370 } | 381 } |
371 | 382 |
372 // Fast path if there is no selection, just draw the whole chunk part using
the regular style | 383 // Fast path if there is no selection, just draw the whole chunk part using
the regular style |
373 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); | 384 TextRun textRun = m_svgInlineTextBox.constructTextRun(style, fragment); |
374 if (!shouldPaintSelection || startPosition >= endPosition) { | 385 if (!shouldPaintSelection || startPosition >= endPosition) { |
375 paintTextWithShadows(paintInfo, style, textRun, fragment, 0, fragment.le
ngth, resourceMode); | 386 SkPaint paint; |
| 387 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 388 paintText(paintInfo, textRun, fragment, 0, fragment.length, paint); |
376 return; | 389 return; |
377 } | 390 } |
378 | 391 |
379 // Eventually draw text using regular style until the start position of the
selection | 392 // Eventually draw text using regular style until the start position of the
selection |
380 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; | 393 bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection; |
381 if (startPosition > 0 && !paintSelectedTextOnly) | 394 if (startPosition > 0 && !paintSelectedTextOnly) { |
382 paintTextWithShadows(paintInfo, style, textRun, fragment, 0, startPositi
on, resourceMode); | 395 SkPaint paint; |
| 396 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 397 paintText(paintInfo, textRun, fragment, 0, startPosition, paint); |
| 398 } |
383 | 399 |
384 // Draw text using selection style from the start to the end position of the
selection | 400 // Draw text using selection style from the start to the end position of the
selection |
385 if (style != selectionStyle) { | 401 if (style != selectionStyle) { |
386 StyleDifference diff; | 402 StyleDifference diff; |
387 diff.setNeedsPaintInvalidationObject(); | 403 diff.setNeedsPaintInvalidationObject(); |
388 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF
rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, selectionStyle); | 404 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF
rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, selectionStyle); |
389 } | 405 } |
390 | 406 |
391 paintTextWithShadows(paintInfo, selectionStyle, textRun, fragment, startPosi
tion, endPosition, resourceMode); | 407 SkPaint paint; |
| 408 if (setupTextPaint(paintInfo, selectionStyle, resourceMode, paint)) |
| 409 paintText(paintInfo, textRun, fragment, startPosition, endPosition, pain
t); |
392 | 410 |
393 if (style != selectionStyle) { | 411 if (style != selectionStyle) { |
394 StyleDifference diff; | 412 StyleDifference diff; |
395 diff.setNeedsPaintInvalidationObject(); | 413 diff.setNeedsPaintInvalidationObject(); |
396 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF
rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, style); | 414 SVGResourcesCache::clientStyleChanged(LineLayoutPaintShim::layoutObjectF
rom(m_svgInlineTextBox.parent()->lineLayoutItem()), diff, style); |
397 } | 415 } |
398 | 416 |
399 // Eventually draw text using regular style from the end position of the sel
ection to the end of the current chunk part | 417 // Eventually draw text using regular style from the end position of the sel
ection to the end of the current chunk part |
400 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl
y) | 418 if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnl
y) { |
401 paintTextWithShadows(paintInfo, style, textRun, fragment, endPosition, f
ragment.length, resourceMode); | 419 SkPaint paint; |
| 420 if (setupTextPaint(paintInfo, style, resourceMode, paint)) |
| 421 paintText(paintInfo, textRun, fragment, endPosition, fragment.length
, paint); |
| 422 } |
402 } | 423 } |
403 | 424 |
404 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, con
st LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font&
font) | 425 void SVGInlineTextBoxPainter::paintTextMatchMarker(GraphicsContext& context, con
st LayoutPoint&, DocumentMarker* marker, const ComputedStyle& style, const Font&
font) |
405 { | 426 { |
406 // SVG is only interested in the TextMatch markers. | 427 // SVG is only interested in the TextMatch markers. |
407 if (marker->type() != DocumentMarker::TextMatch) | 428 if (marker->type() != DocumentMarker::TextMatch) |
408 return; | 429 return; |
409 | 430 |
410 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai
ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); | 431 LayoutSVGInlineText& textLayoutObject = toLayoutSVGInlineText(*LineLayoutPai
ntShim::layoutObjectFrom(m_svgInlineTextBox.lineLayoutItem())); |
411 | 432 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 if (!fragmentTransform.isIdentity()) | 465 if (!fragmentTransform.isIdentity()) |
445 context.concatCTM(fragmentTransform); | 466 context.concatCTM(fragmentTransform); |
446 context.setFillColor(color); | 467 context.setFillColor(color); |
447 context.fillRect(fragmentRect, color); | 468 context.fillRect(fragmentRect, color); |
448 } | 469 } |
449 } | 470 } |
450 } | 471 } |
451 } | 472 } |
452 | 473 |
453 } // namespace blink | 474 } // namespace blink |
OLD | NEW |