1 /* 2 * Copyright (C) 2007 Apple Inc. 3 * Copyright (C) 2007 Alp Toker <alp (at) atoker.com> 4 * Copyright (C) 2008 Collabora Ltd. 5 * Copyright (C) 2008, 2009 Google Inc. 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 * 17 * You should have received a copy of the GNU Library General Public License 18 * along with this library; see the file COPYING.LIB. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 * 22 */ 23 24 #include "config.h" 25 #include "RenderThemeChromiumSkia.h" 26 27 #include "CSSValueKeywords.h" 28 #include "CurrentTime.h" 29 #include "GraphicsContext.h" 30 #include "HTMLMediaElement.h" 31 #include "HTMLNames.h" 32 #include "Image.h" 33 #include "MediaControlElements.h" 34 #include "PaintInfo.h" 35 #include "PlatformBridge.h" 36 #include "PlatformContextSkia.h" 37 #include "RenderBox.h" 38 #include "RenderMediaControlsChromium.h" 39 #include "RenderObject.h" 40 #include "RenderProgress.h" 41 #include "RenderSlider.h" 42 #include "ScrollbarTheme.h" 43 #include "TimeRanges.h" 44 #include "TransformationMatrix.h" 45 #include "UserAgentStyleSheets.h" 46 47 #include "SkShader.h" 48 #include "SkGradientShader.h" 49 50 namespace WebCore { 51 52 enum PaddingType { 53 TopPadding, 54 RightPadding, 55 BottomPadding, 56 LeftPadding 57 }; 58 59 static const int styledMenuListInternalPadding[4] = { 1, 4, 1, 4 }; 60 61 // These values all match Safari/Win. 62 static const float defaultControlFontPixelSize = 13; 63 static const float defaultCancelButtonSize = 9; 64 static const float minCancelButtonSize = 5; 65 static const float maxCancelButtonSize = 21; 66 static const float defaultSearchFieldResultsDecorationSize = 13; 67 static const float minSearchFieldResultsDecorationSize = 9; 68 static const float maxSearchFieldResultsDecorationSize = 30; 69 static const float defaultSearchFieldResultsButtonWidth = 18; 70 71 // We aim to match IE here. 72 // -IE uses a font based on the encoding as the default font for form controls. 73 // -Gecko uses MS Shell Dlg (actually calls GetStockObject(DEFAULT_GUI_FONT), 74 // which returns MS Shell Dlg) 75 // -Safari uses Lucida Grande. 76 // 77 // FIXME: The only case where we know we don't match IE is for ANSI encodings. 78 // IE uses MS Shell Dlg there, which we render incorrectly at certain pixel 79 // sizes (e.g. 15px). So, for now we just use Arial. 80 const String& RenderThemeChromiumSkia::defaultGUIFont() 81 { 82 DEFINE_STATIC_LOCAL(String, fontFace, ("Arial")); 83 return fontFace; 84 } 85 86 float RenderThemeChromiumSkia::defaultFontSize = 16.0; 87 88 RenderThemeChromiumSkia::RenderThemeChromiumSkia() 89 { 90 } 91 92 RenderThemeChromiumSkia::~RenderThemeChromiumSkia() 93 { 94 } 95 96 // Use the Windows style sheets to match their metrics. 97 String RenderThemeChromiumSkia::extraDefaultStyleSheet() 98 { 99 return String(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet)) + 100 String(themeChromiumSkiaUserAgentStyleSheet, sizeof(themeChromiumSkiaUserAgentStyleSheet)); 101 } 102 103 String RenderThemeChromiumSkia::extraQuirksStyleSheet() 104 { 105 return String(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet)); 106 } 107 108 #if ENABLE(VIDEO) 109 String RenderThemeChromiumSkia::extraMediaControlsStyleSheet() 110 { 111 return String(mediaControlsChromiumUserAgentStyleSheet, sizeof(mediaControlsChromiumUserAgentStyleSheet)); 112 } 113 #endif 114 115 bool RenderThemeChromiumSkia::supportsHover(const RenderStyle* style) const 116 { 117 return true; 118 } 119 120 bool RenderThemeChromiumSkia::supportsFocusRing(const RenderStyle* style) const 121 { 122 // This causes WebKit to draw the focus rings for us. 123 return false; 124 } 125 126 Color RenderThemeChromiumSkia::platformActiveSelectionBackgroundColor() const 127 { 128 return Color(0x1e, 0x90, 0xff); 129 } 130 131 Color RenderThemeChromiumSkia::platformInactiveSelectionBackgroundColor() const 132 { 133 return Color(0xc8, 0xc8, 0xc8); 134 } 135 136 Color RenderThemeChromiumSkia::platformActiveSelectionForegroundColor() const 137 { 138 return Color::black; 139 } 140 141 Color RenderThemeChromiumSkia::platformInactiveSelectionForegroundColor() const 142 { 143 return Color(0x32, 0x32, 0x32); 144 } 145 146 Color RenderThemeChromiumSkia::platformFocusRingColor() const 147 { 148 static Color focusRingColor(229, 151, 0, 255); 149 return focusRingColor; 150 } 151 152 double RenderThemeChromiumSkia::caretBlinkInterval() const 153 { 154 // Disable the blinking caret in layout test mode, as it introduces 155 // a race condition for the pixel tests. http://b/1198440 156 if (PlatformBridge::layoutTestMode()) 157 return 0; 158 159 return caretBlinkIntervalInternal(); 160 } 161 162 void RenderThemeChromiumSkia::systemFont(int propId, FontDescription& fontDescription) const 163 { 164 float fontSize = defaultFontSize; 165 166 switch (propId) { 167 case CSSValueWebkitMiniControl: 168 case CSSValueWebkitSmallControl: 169 case CSSValueWebkitControl: 170 // Why 2 points smaller? Because that's what Gecko does. Note that we 171 // are assuming a 96dpi screen, which is the default that we use on 172 // Windows. 173 static const float pointsPerInch = 72.0f; 174 static const float pixelsPerInch = 96.0f; 175 fontSize -= (2.0f / pointsPerInch) * pixelsPerInch; 176 break; 177 } 178 179 fontDescription.firstFamily().setFamily(defaultGUIFont()); 180 fontDescription.setSpecifiedSize(fontSize); 181 fontDescription.setIsAbsoluteSize(true); 182 fontDescription.setGenericFamily(FontDescription::NoFamily); 183 fontDescription.setWeight(FontWeightNormal); 184 fontDescription.setItalic(false); 185 } 186 187 int RenderThemeChromiumSkia::minimumMenuListSize(RenderStyle* style) const 188 { 189 return 0; 190 } 191 192 // These are the default dimensions of radio buttons and checkboxes. 193 static const int widgetStandardWidth = 13; 194 static const int widgetStandardHeight = 13; 195 196 // Return a rectangle that has the same center point as |original|, but with a 197 // size capped at |width| by |height|. 198 IntRect center(const IntRect& original, int width, int height) 199 { 200 width = std::min(original.width(), width); 201 height = std::min(original.height(), height); 202 int x = original.x() + (original.width() - width) / 2; 203 int y = original.y() + (original.height() - height) / 2; 204 205 return IntRect(x, y, width, height); 206 } 207 208 void RenderThemeChromiumSkia::setCheckboxSize(RenderStyle* style) const 209 { 210 // If the width and height are both specified, then we have nothing to do. 211 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) 212 return; 213 214 // FIXME: A hard-coded size of 13 is used. This is wrong but necessary 215 // for now. It matches Firefox. At different DPI settings on Windows, 216 // querying the theme gives you a larger size that accounts for the higher 217 // DPI. Until our entire engine honors a DPI setting other than 96, we 218 // can't rely on the theme's metrics. 219 const IntSize size(widgetStandardWidth, widgetStandardHeight); 220 setSizeIfAuto(style, size); 221 } 222 223 void RenderThemeChromiumSkia::setRadioSize(RenderStyle* style) const 224 { 225 // Use same sizing for radio box as checkbox. 226 setCheckboxSize(style); 227 } 228 229 void RenderThemeChromiumSkia::adjustButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 230 { 231 if (style->appearance() == PushButtonPart) { 232 // Ignore line-height. 233 style->setLineHeight(RenderStyle::initialLineHeight()); 234 } 235 } 236 237 bool RenderThemeChromiumSkia::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) 238 { 239 return paintTextField(o, i, r); 240 } 241 242 void RenderThemeChromiumSkia::adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 243 { 244 // Ignore line-height. 245 style->setLineHeight(RenderStyle::initialLineHeight()); 246 } 247 248 bool RenderThemeChromiumSkia::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& r) 249 { 250 return paintTextField(o, i, r); 251 } 252 253 void RenderThemeChromiumSkia::adjustSearchFieldCancelButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 254 { 255 // Scale the button size based on the font size 256 float fontScale = style->fontSize() / defaultControlFontPixelSize; 257 int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize)); 258 style->setWidth(Length(cancelButtonSize, Fixed)); 259 style->setHeight(Length(cancelButtonSize, Fixed)); 260 } 261 262 IntRect RenderThemeChromiumSkia::convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const 263 { 264 // Compute an offset between the part renderer and the input renderer. 265 IntSize offsetFromInputRenderer = -(partRenderer->offsetFromAncestorContainer(inputRenderer)); 266 // Move the rect into partRenderer's coords. 267 partRect.move(offsetFromInputRenderer); 268 // Account for the local drawing offset. 269 partRect.move(localOffset.x(), localOffset.y()); 270 271 return partRect; 272 } 273 274 bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const PaintInfo& paintInfo, const IntRect& r) 275 { 276 // Get the renderer of <input> element. 277 Node* input = cancelButtonObject->node()->shadowAncestorNode(); 278 if (!input->renderer()->isBox()) 279 return false; 280 RenderBox* inputRenderBox = toRenderBox(input->renderer()); 281 IntRect inputContentBox = inputRenderBox->contentBoxRect(); 282 283 // Make sure the scaled button stays square and will fit in its parent's box. 284 int cancelButtonSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height())); 285 // Calculate cancel button's coordinates relative to the input element. 286 // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will 287 // be one pixel closer to the bottom of the field. This tends to look better with the text. 288 IntRect cancelButtonRect(cancelButtonObject->offsetFromAncestorContainer(inputRenderBox).width(), 289 inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2, 290 cancelButtonSize, cancelButtonSize); 291 IntRect paintingRect = convertToPaintingRect(inputRenderBox, cancelButtonObject, cancelButtonRect, r); 292 293 static Image* cancelImage = Image::loadPlatformResource("searchCancel").releaseRef(); 294 static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").releaseRef(); 295 paintInfo.context->drawImage(isPressed(cancelButtonObject) ? cancelPressedImage : cancelImage, 296 cancelButtonObject->style()->colorSpace(), paintingRect); 297 return false; 298 } 299 300 void RenderThemeChromiumSkia::adjustSearchFieldDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 301 { 302 IntSize emptySize(1, 11); 303 style->setWidth(Length(emptySize.width(), Fixed)); 304 style->setHeight(Length(emptySize.height(), Fixed)); 305 } 306 307 void RenderThemeChromiumSkia::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 308 { 309 // Scale the decoration size based on the font size 310 float fontScale = style->fontSize() / defaultControlFontPixelSize; 311 int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 312 maxSearchFieldResultsDecorationSize)); 313 style->setWidth(Length(magnifierSize, Fixed)); 314 style->setHeight(Length(magnifierSize, Fixed)); 315 } 316 317 bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const PaintInfo& paintInfo, const IntRect& r) 318 { 319 // Get the renderer of <input> element. 320 Node* input = magnifierObject->node()->shadowAncestorNode(); 321 if (!input->renderer()->isBox()) 322 return false; 323 RenderBox* inputRenderBox = toRenderBox(input->renderer()); 324 IntRect inputContentBox = inputRenderBox->contentBoxRect(); 325 326 // Make sure the scaled decoration stays square and will fit in its parent's box. 327 int magnifierSize = std::min(inputContentBox.width(), std::min(inputContentBox.height(), r.height())); 328 // Calculate decoration's coordinates relative to the input element. 329 // Center the decoration vertically. Round up though, so if it has to be one pixel off-center, it will 330 // be one pixel closer to the bottom of the field. This tends to look better with the text. 331 IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(), 332 inputContentBox.y() + (inputContentBox.height() - magnifierSize + 1) / 2, 333 magnifierSize, magnifierSize); 334 IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r); 335 336 static Image* magnifierImage = Image::loadPlatformResource("searchMagnifier").releaseRef(); 337 paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect); 338 return false; 339 } 340 341 void RenderThemeChromiumSkia::adjustSearchFieldResultsButtonStyle(CSSStyleSelector*, RenderStyle* style, Element*) const 342 { 343 // Scale the button size based on the font size 344 float fontScale = style->fontSize() / defaultControlFontPixelSize; 345 int magnifierHeight = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 346 maxSearchFieldResultsDecorationSize)); 347 int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize); 348 style->setWidth(Length(magnifierWidth, Fixed)); 349 style->setHeight(Length(magnifierHeight, Fixed)); 350 } 351 352 bool RenderThemeChromiumSkia::paintSearchFieldResultsButton(RenderObject* magnifierObject, const PaintInfo& paintInfo, const IntRect& r) 353 { 354 // Get the renderer of <input> element. 355 Node* input = magnifierObject->node()->shadowAncestorNode(); 356 if (!input->renderer()->isBox()) 357 return false; 358 RenderBox* inputRenderBox = toRenderBox(input->renderer()); 359 IntRect inputContentBox = inputRenderBox->contentBoxRect(); 360 361 // Make sure the scaled decoration will fit in its parent's box. 362 int magnifierHeight = std::min(inputContentBox.height(), r.height()); 363 int magnifierWidth = std::min(inputContentBox.width(), static_cast<int>(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize)); 364 IntRect magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(), 365 inputContentBox.y() + (inputContentBox.height() - magnifierHeight + 1) / 2, 366 magnifierWidth, magnifierHeight); 367 IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r); 368 369 static Image* magnifierImage = Image::loadPlatformResource("searchMagnifierResults").releaseRef(); 370 paintInfo.context->drawImage(magnifierImage, magnifierObject->style()->colorSpace(), paintingRect); 371 return false; 372 } 373 374 bool RenderThemeChromiumSkia::paintMediaControlsBackground(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 375 { 376 #if ENABLE(VIDEO) 377 return RenderMediaControlsChromium::paintMediaControlsPart(MediaTimelineContainer, object, paintInfo, rect); 378 #else 379 UNUSED_PARAM(object); 380 UNUSED_PARAM(paintInfo); 381 UNUSED_PARAM(rect); 382 return false; 383 #endif 384 } 385 386 bool RenderThemeChromiumSkia::paintMediaSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 387 { 388 #if ENABLE(VIDEO) 389 return RenderMediaControlsChromium::paintMediaControlsPart(MediaSlider, object, paintInfo, rect); 390 #else 391 UNUSED_PARAM(object); 392 UNUSED_PARAM(paintInfo); 393 UNUSED_PARAM(rect); 394 return false; 395 #endif 396 } 397 398 bool RenderThemeChromiumSkia::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 399 { 400 #if ENABLE(VIDEO) 401 return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSlider, object, paintInfo, rect); 402 #else 403 UNUSED_PARAM(object); 404 UNUSED_PARAM(paintInfo); 405 UNUSED_PARAM(rect); 406 return false; 407 #endif 408 } 409 410 void RenderThemeChromiumSkia::adjustSliderThumbSize(RenderObject* object) const 411 { 412 #if ENABLE(VIDEO) 413 RenderMediaControlsChromium::adjustMediaSliderThumbSize(object); 414 #else 415 UNUSED_PARAM(object); 416 #endif 417 } 418 419 bool RenderThemeChromiumSkia::paintMediaSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 420 { 421 #if ENABLE(VIDEO) 422 return RenderMediaControlsChromium::paintMediaControlsPart(MediaSliderThumb, object, paintInfo, rect); 423 #else 424 UNUSED_PARAM(object); 425 UNUSED_PARAM(paintInfo); 426 UNUSED_PARAM(rect); 427 return false; 428 #endif 429 } 430 431 bool RenderThemeChromiumSkia::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 432 { 433 #if ENABLE(VIDEO) 434 return RenderMediaControlsChromium::paintMediaControlsPart(MediaVolumeSliderThumb, object, paintInfo, rect); 435 #else 436 UNUSED_PARAM(object); 437 UNUSED_PARAM(paintInfo); 438 UNUSED_PARAM(rect); 439 return false; 440 #endif 441 } 442 443 bool RenderThemeChromiumSkia::paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 444 { 445 #if ENABLE(VIDEO) 446 return RenderMediaControlsChromium::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect); 447 #else 448 UNUSED_PARAM(object); 449 UNUSED_PARAM(paintInfo); 450 UNUSED_PARAM(rect); 451 return false; 452 #endif 453 } 454 455 bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) 456 { 457 #if ENABLE(VIDEO) 458 return RenderMediaControlsChromium::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect); 459 #else 460 UNUSED_PARAM(object); 461 UNUSED_PARAM(paintInfo); 462 UNUSED_PARAM(rect); 463 return false; 464 #endif 465 } 466 467 void RenderThemeChromiumSkia::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const 468 { 469 // Height is locked to auto on all browsers. 470 style->setLineHeight(RenderStyle::initialLineHeight()); 471 } 472 473 void RenderThemeChromiumSkia::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 474 { 475 adjustMenuListStyle(selector, style, e); 476 } 477 478 // Used to paint styled menulists (i.e. with a non-default border) 479 bool RenderThemeChromiumSkia::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) 480 { 481 return paintMenuList(o, i, rect); 482 } 483 484 int RenderThemeChromiumSkia::popupInternalPaddingLeft(RenderStyle* style) const 485 { 486 return menuListInternalPadding(style, LeftPadding); 487 } 488 489 int RenderThemeChromiumSkia::popupInternalPaddingRight(RenderStyle* style) const 490 { 491 return menuListInternalPadding(style, RightPadding); 492 } 493 494 int RenderThemeChromiumSkia::popupInternalPaddingTop(RenderStyle* style) const 495 { 496 return menuListInternalPadding(style, TopPadding); 497 } 498 499 int RenderThemeChromiumSkia::popupInternalPaddingBottom(RenderStyle* style) const 500 { 501 return menuListInternalPadding(style, BottomPadding); 502 } 503 504 // static 505 void RenderThemeChromiumSkia::setDefaultFontSize(int fontSize) 506 { 507 defaultFontSize = static_cast<float>(fontSize); 508 } 509 510 double RenderThemeChromiumSkia::caretBlinkIntervalInternal() const 511 { 512 return RenderTheme::caretBlinkInterval(); 513 } 514 515 // static 516 void RenderThemeChromiumSkia::setSizeIfAuto(RenderStyle* style, const IntSize& size) 517 { 518 if (style->width().isIntrinsicOrAuto()) 519 style->setWidth(Length(size.width(), Fixed)); 520 if (style->height().isAuto()) 521 style->setHeight(Length(size.height(), Fixed)); 522 } 523 524 int RenderThemeChromiumSkia::menuListInternalPadding(RenderStyle* style, int paddingType) const 525 { 526 // This internal padding is in addition to the user-supplied padding. 527 // Matches the FF behavior. 528 int padding = styledMenuListInternalPadding[paddingType]; 529 530 // Reserve the space for right arrow here. The rest of the padding is 531 // set by adjustMenuListStyle, since PopMenuWin.cpp uses the padding from 532 // RenderMenuList to lay out the individual items in the popup. 533 // If the MenuList actually has appearance "NoAppearance", then that means 534 // we don't draw a button, so don't reserve space for it. 535 const int barType = style->direction() == LTR ? RightPadding : LeftPadding; 536 if (paddingType == barType && style->appearance() != NoControlPart) 537 padding += ScrollbarTheme::nativeTheme()->scrollbarThickness(); 538 539 return padding; 540 } 541 542 #if ENABLE(PROGRESS_TAG) 543 544 // 545 // Following values are come from default of GTK+ 546 // 547 static const int progressDeltaPixelsPerSecond = 100; 548 static const int progressActivityBlocks = 5; 549 static const int progressAnimationFrmaes = 10; 550 static const double progressAnimationInterval = 0.125; 551 552 IntRect RenderThemeChromiumSkia::determinateProgressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const 553 { 554 int dx = rect.width() * renderProgress->position(); 555 if (renderProgress->style()->direction() == RTL) 556 return IntRect(rect.x() + rect.width() - dx, rect.y(), dx, rect.height()); 557 return IntRect(rect.x(), rect.y(), dx, rect.height()); 558 } 559 560 IntRect RenderThemeChromiumSkia::indeterminateProgressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const 561 { 562 563 int valueWidth = rect.width() / progressActivityBlocks; 564 int movableWidth = rect.width() - valueWidth; 565 if (movableWidth <= 0) 566 return IntRect(); 567 568 double progress = renderProgress->animationProgress(); 569 if (progress < 0.5) 570 return IntRect(rect.x() + progress * 2 * movableWidth, rect.y(), valueWidth, rect.height()); 571 return IntRect(rect.x() + (1.0 - progress) * 2 * movableWidth, rect.y(), valueWidth, rect.height()); 572 } 573 574 double RenderThemeChromiumSkia::animationRepeatIntervalForProgressBar(RenderProgress*) const 575 { 576 return progressAnimationInterval; 577 } 578 579 double RenderThemeChromiumSkia::animationDurationForProgressBar(RenderProgress* renderProgress) const 580 { 581 return progressAnimationInterval * progressAnimationFrmaes * 2; // "2" for back and forth 582 } 583 584 IntRect RenderThemeChromiumSkia::progressValueRectFor(RenderProgress* renderProgress, const IntRect& rect) const 585 { 586 return renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, rect) : indeterminateProgressValueRectFor(renderProgress, rect); 587 } 588 589 #endif 590 591 } // namespace WebCore 592