| OLD | NEW |
| 1 /** | 1 /** |
| 2 * Copyright (C) 2007 Rob Buis <buis@kde.org> | 2 * Copyright (C) 2007 Rob Buis <buis@kde.org> |
| 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> | 3 * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> |
| 4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 4 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
| 5 * | 5 * |
| 6 * This library is free software; you can redistribute it and/or | 6 * This library is free software; you can redistribute it and/or |
| 7 * modify it under the terms of the GNU Library General Public | 7 * modify it under the terms of the GNU Library General Public |
| 8 * License as published by the Free Software Foundation; either | 8 * License as published by the Free Software Foundation; either |
| 9 * version 2 of the License, or (at your option) any later version. | 9 * version 2 of the License, or (at your option) any later version. |
| 10 * | 10 * |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 | 346 |
| 347 class PaintingResourceScope { | 347 class PaintingResourceScope { |
| 348 public: | 348 public: |
| 349 PaintingResourceScope(RenderObject& renderer) | 349 PaintingResourceScope(RenderObject& renderer) |
| 350 : m_renderer(renderer) | 350 : m_renderer(renderer) |
| 351 , m_paintingResource(0) | 351 , m_paintingResource(0) |
| 352 { | 352 { |
| 353 } | 353 } |
| 354 ~PaintingResourceScope() { ASSERT(!m_paintingResource); } | 354 ~PaintingResourceScope() { ASSERT(!m_paintingResource); } |
| 355 | 355 |
| 356 bool acquirePaintingResource(GraphicsContext*&, float scalingFactor, RenderS
tyle*, RenderSVGResourceModeFlags); | 356 bool acquirePaintingResource(GraphicsContext*&, RenderStyle*, RenderSVGResou
rceModeFlags); |
| 357 void releasePaintingResource(GraphicsContext*&); | 357 void releasePaintingResource(GraphicsContext*&); |
| 358 | 358 |
| 359 private: | 359 private: |
| 360 RenderObject& m_renderer; | 360 RenderObject& m_renderer; |
| 361 RenderSVGResource* m_paintingResource; | 361 RenderSVGResource* m_paintingResource; |
| 362 }; | 362 }; |
| 363 | 363 |
| 364 bool PaintingResourceScope::acquirePaintingResource(GraphicsContext*& context, f
loat scalingFactor, | 364 bool PaintingResourceScope::acquirePaintingResource(GraphicsContext*& context, R
enderStyle* style, RenderSVGResourceModeFlags resourceModeFlags) |
| 365 RenderStyle* style, RenderSVGResourceModeFlags resourceModeFlags) | |
| 366 { | 365 { |
| 367 // Callers must save the context state before calling when scalingFactor is
not 1. | |
| 368 ASSERT(scalingFactor); | |
| 369 ASSERT(style); | 366 ASSERT(style); |
| 370 ASSERT(resourceModeFlags != ApplyToDefaultMode); | 367 ASSERT(resourceModeFlags != ApplyToDefaultMode); |
| 371 RenderSVGResourceMode resourceMode = static_cast<RenderSVGResourceMode>(reso
urceModeFlags & (ApplyToFillMode | ApplyToStrokeMode)); | 368 RenderSVGResourceMode resourceMode = static_cast<RenderSVGResourceMode>(reso
urceModeFlags & (ApplyToFillMode | ApplyToStrokeMode)); |
| 372 ASSERT(resourceMode == ApplyToFillMode || resourceMode == ApplyToStrokeMode)
; | 369 ASSERT(resourceMode == ApplyToFillMode || resourceMode == ApplyToStrokeMode)
; |
| 373 | 370 |
| 374 bool hasFallback = false; | 371 bool hasFallback = false; |
| 375 m_paintingResource = RenderSVGResource::requestPaintingResource(resourceMode
, &m_renderer, style, hasFallback); | 372 m_paintingResource = RenderSVGResource::requestPaintingResource(resourceMode
, &m_renderer, style, hasFallback); |
| 376 if (!m_paintingResource) | 373 if (!m_paintingResource) |
| 377 return false; | 374 return false; |
| 378 | 375 |
| 379 if (!m_paintingResource->applyResource(&m_renderer, style, context, resource
ModeFlags)) { | 376 if (!m_paintingResource->applyResource(&m_renderer, style, context, resource
ModeFlags)) { |
| 380 if (hasFallback) { | 377 if (hasFallback) { |
| 381 m_paintingResource = RenderSVGResource::sharedSolidPaintingResource(
); | 378 m_paintingResource = RenderSVGResource::sharedSolidPaintingResource(
); |
| 382 m_paintingResource->applyResource(&m_renderer, style, context, resou
rceModeFlags); | 379 m_paintingResource->applyResource(&m_renderer, style, context, resou
rceModeFlags); |
| 383 } | 380 } |
| 384 } | 381 } |
| 385 | |
| 386 if (scalingFactor != 1 && resourceModeFlags & ApplyToStrokeMode) | |
| 387 context->setStrokeThickness(context->strokeThickness() * scalingFactor); | |
| 388 | |
| 389 return true; | 382 return true; |
| 390 } | 383 } |
| 391 | 384 |
| 392 void PaintingResourceScope::releasePaintingResource(GraphicsContext*& context) | 385 void PaintingResourceScope::releasePaintingResource(GraphicsContext*& context) |
| 393 { | 386 { |
| 394 ASSERT(m_paintingResource); | 387 ASSERT(m_paintingResource); |
| 395 | 388 |
| 396 m_paintingResource->postApplyResource(&m_renderer, context); | 389 m_paintingResource->postApplyResource(&m_renderer, context); |
| 397 m_paintingResource = 0; | 390 m_paintingResource = 0; |
| 398 } | 391 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 endPosition = length; | 447 endPosition = length; |
| 455 else { | 448 else { |
| 456 ASSERT(endPosition >= offset); | 449 ASSERT(endPosition >= offset); |
| 457 endPosition -= offset; | 450 endPosition -= offset; |
| 458 } | 451 } |
| 459 | 452 |
| 460 ASSERT(startPosition < endPosition); | 453 ASSERT(startPosition < endPosition); |
| 461 return true; | 454 return true; |
| 462 } | 455 } |
| 463 | 456 |
| 464 static inline float positionOffsetForDecoration(TextDecoration decoration, const
FontMetrics& fontMetrics, float thickness) | 457 // Offset from the baseline for |decoration|. Positive offsets are above the bas
eline. |
| 458 static inline float baselineOffsetForDecoration(TextDecoration decoration, const
FontMetrics& fontMetrics, float thickness) |
| 465 { | 459 { |
| 466 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
ace> if specified. | 460 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
ace> if specified. |
| 467 // Compatible with Batik/Opera. | 461 // Compatible with Batik/Presto. |
| 468 if (decoration == TextDecorationUnderline) | 462 if (decoration == TextDecorationUnderline) |
| 469 return fontMetrics.floatAscent() + thickness * 1.5f; | 463 return -thickness * 1.5f; |
| 470 if (decoration == TextDecorationOverline) | 464 if (decoration == TextDecorationOverline) |
| 471 return thickness; | 465 return fontMetrics.floatAscent() - thickness; |
| 472 if (decoration == TextDecorationLineThrough) | 466 if (decoration == TextDecorationLineThrough) |
| 473 return fontMetrics.floatAscent() * 5 / 8.0f; | 467 return fontMetrics.floatAscent() * 3 / 8.0f; |
| 474 | 468 |
| 475 ASSERT_NOT_REACHED(); | 469 ASSERT_NOT_REACHED(); |
| 476 return 0.0f; | 470 return 0.0f; |
| 477 } | 471 } |
| 478 | 472 |
| 479 static inline float thicknessForDecoration(TextDecoration, const Font& font) | 473 static inline float thicknessForDecoration(TextDecoration, const Font& font) |
| 480 { | 474 { |
| 481 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
ace> if specified. | 475 // FIXME: For SVG Fonts we need to use the attributes defined in the <font-f
ace> if specified. |
| 482 // Compatible with Batik/Opera | 476 // Compatible with Batik/Presto |
| 483 return font.fontDescription().computedSize() / 20.0f; | 477 return font.fontDescription().computedSize() / 20.0f; |
| 484 } | 478 } |
| 485 | 479 |
| 486 static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
ox* parentBox) | 480 static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
ox* parentBox) |
| 487 { | 481 { |
| 488 // Lookup first render object in parent hierarchy which has text-decoration
set. | 482 // Lookup first render object in parent hierarchy which has text-decoration
set. |
| 489 RenderObject* renderer = 0; | 483 RenderObject* renderer = 0; |
| 490 while (parentBox) { | 484 while (parentBox) { |
| 491 renderer = &parentBox->renderer(); | 485 renderer = &parentBox->renderer(); |
| 492 | 486 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 ASSERT(resourceMode != ApplyToDefaultMode); | 533 ASSERT(resourceMode != ApplyToDefaultMode); |
| 540 | 534 |
| 541 RenderStyle* decorationStyle = decorationRenderer->style(); | 535 RenderStyle* decorationStyle = decorationRenderer->style(); |
| 542 ASSERT(decorationStyle); | 536 ASSERT(decorationStyle); |
| 543 | 537 |
| 544 float scalingFactor = 1; | 538 float scalingFactor = 1; |
| 545 Font scaledFont; | 539 Font scaledFont; |
| 546 RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decora
tionStyle, scalingFactor, scaledFont); | 540 RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decora
tionStyle, scalingFactor, scaledFont); |
| 547 ASSERT(scalingFactor); | 541 ASSERT(scalingFactor); |
| 548 | 542 |
| 549 // The initial y value refers to overline position. | |
| 550 float thickness = thicknessForDecoration(decoration, scaledFont); | 543 float thickness = thicknessForDecoration(decoration, scaledFont); |
| 551 | 544 |
| 552 if (fragment.width <= 0 && thickness <= 0) | 545 if (fragment.width <= 0 && thickness <= 0) |
| 553 return; | 546 return; |
| 554 | 547 |
| 555 FloatPoint decorationOrigin(fragment.x, fragment.y); | 548 float decorationOffset = baselineOffsetForDecoration(decoration, scaledFont.
fontMetrics(), thickness); |
| 556 float width = fragment.width; | 549 FloatPoint decorationOrigin(fragment.x, fragment.y - decorationOffset / scal
ingFactor); |
| 557 const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics(); | |
| 558 | |
| 559 GraphicsContextStateSaver stateSaver(*context, false); | |
| 560 if (scalingFactor != 1) { | |
| 561 stateSaver.save(); | |
| 562 width *= scalingFactor; | |
| 563 decorationOrigin.scale(scalingFactor, scalingFactor); | |
| 564 context->scale(1 / scalingFactor, 1 / scalingFactor); | |
| 565 } | |
| 566 | |
| 567 decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetFo
rDecoration(decoration, scaledFontMetrics, thickness)); | |
| 568 | 550 |
| 569 Path path; | 551 Path path; |
| 570 path.addRect(FloatRect(decorationOrigin, FloatSize(width, thickness))); | 552 path.addRect(FloatRect(decorationOrigin, FloatSize(fragment.width, thickness
/ scalingFactor))); |
| 571 | 553 |
| 572 // acquirePaintingResource also modifies state if the scalingFactor is non-i
dentity. | |
| 573 // Above we have saved the state for this case. | |
| 574 PaintingResourceScope resourceScope(*decorationRenderer); | 554 PaintingResourceScope resourceScope(*decorationRenderer); |
| 575 if (resourceScope.acquirePaintingResource(context, scalingFactor, decoration
Style, resourceMode)) { | 555 if (resourceScope.acquirePaintingResource(context, decorationStyle, resource
Mode)) { |
| 576 SVGRenderSupport::fillOrStrokePath(context, resourceMode, path); | 556 SVGRenderSupport::fillOrStrokePath(context, resourceMode, path); |
| 577 resourceScope.releasePaintingResource(context); | 557 resourceScope.releasePaintingResource(context); |
| 578 } | 558 } |
| 579 } | 559 } |
| 580 | 560 |
| 581 void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
e* style, | 561 void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
e* style, |
| 582 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, | 562 TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int en
dPosition, |
| 583 RenderSVGResourceModeFlags resourceMode) | 563 RenderSVGResourceModeFlags resourceMode) |
| 584 { | 564 { |
| 585 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); | 565 RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->renderer()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 600 textOrigin.scale(scalingFactor, scalingFactor); | 580 textOrigin.scale(scalingFactor, scalingFactor); |
| 601 textSize.scale(scalingFactor); | 581 textSize.scale(scalingFactor); |
| 602 context->save(); | 582 context->save(); |
| 603 context->scale(1 / scalingFactor, 1 / scalingFactor); | 583 context->scale(1 / scalingFactor, 1 / scalingFactor); |
| 604 } | 584 } |
| 605 | 585 |
| 606 if (hasShadow) | 586 if (hasShadow) |
| 607 context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::S
hadowRespectsAlpha)); | 587 context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::S
hadowRespectsAlpha)); |
| 608 | 588 |
| 609 PaintingResourceScope resourceScope(parent()->renderer()); | 589 PaintingResourceScope resourceScope(parent()->renderer()); |
| 610 if (resourceScope.acquirePaintingResource(context, scalingFactor, style, res
ourceMode)) { | 590 if (resourceScope.acquirePaintingResource(context, style, resourceMode)) { |
| 591 if (scalingFactor != 1 && resourceMode & ApplyToStrokeMode) |
| 592 context->setStrokeThickness(context->strokeThickness() * scalingFact
or); |
| 593 |
| 611 TextRunPaintInfo textRunPaintInfo(textRun); | 594 TextRunPaintInfo textRunPaintInfo(textRun); |
| 612 textRunPaintInfo.from = startPosition; | 595 textRunPaintInfo.from = startPosition; |
| 613 textRunPaintInfo.to = endPosition; | 596 textRunPaintInfo.to = endPosition; |
| 614 | 597 |
| 615 float baseline = scaledFont.fontMetrics().floatAscent(); | 598 float baseline = scaledFont.fontMetrics().floatAscent(); |
| 616 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - bas
eline, | 599 textRunPaintInfo.bounds = FloatRect(textOrigin.x(), textOrigin.y() - bas
eline, |
| 617 textSize.width(), textSize.height()); | 600 textSize.width(), textSize.height()); |
| 618 | 601 |
| 619 scaledFont.drawText(context, textRunPaintInfo, textOrigin); | 602 scaledFont.drawText(context, textRunPaintInfo, textOrigin); |
| 620 resourceScope.releasePaintingResource(context); | 603 resourceScope.releasePaintingResource(context); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 renderer().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); | 757 renderer().updateHitTestResult(result, locationInContainer.point
() - toLayoutSize(accumulatedOffset)); |
| 775 if (!result.addNodeToRectBasedTestResult(renderer().node(), requ
est, locationInContainer, rect)) | 758 if (!result.addNodeToRectBasedTestResult(renderer().node(), requ
est, locationInContainer, rect)) |
| 776 return true; | 759 return true; |
| 777 } | 760 } |
| 778 } | 761 } |
| 779 } | 762 } |
| 780 return false; | 763 return false; |
| 781 } | 764 } |
| 782 | 765 |
| 783 } // namespace blink | 766 } // namespace blink |
| OLD | NEW |