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 |