1 /* 2 * Copyright (C) 2007, 2008, 2009 Apple Inc. 3 * Copyright (C) 2009 Kenneth Rohde Christiansen 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 * 20 */ 21 22 #include "config.h" 23 #include "RenderThemeSafari.h" 24 #include "RenderThemeWin.h" 25 #include "Settings.h" 26 27 #if USE(SAFARI_THEME) 28 29 #include "CSSValueKeywords.h" 30 #include "Document.h" 31 #include "Element.h" 32 #include "Frame.h" 33 #include "FrameView.h" 34 #include "GraphicsContext.h" 35 #include "HTMLInputElement.h" 36 #include "HTMLMediaElement.h" 37 #include "HTMLNames.h" 38 #include "RenderMediaControls.h" 39 #include "RenderSlider.h" 40 #include "RenderView.h" 41 #include "RetainPtr.h" 42 #include "SoftLinking.h" 43 #include "cssstyleselector.h" 44 #include <CoreGraphics/CoreGraphics.h> 45 46 using std::min; 47 48 // FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeMac. 49 50 namespace WebCore { 51 52 using namespace HTMLNames; 53 using namespace SafariTheme; 54 55 enum { 56 topMargin, 57 rightMargin, 58 bottomMargin, 59 leftMargin 60 }; 61 62 enum { 63 topPadding, 64 rightPadding, 65 bottomPadding, 66 leftPadding 67 }; 68 69 PassRefPtr<RenderTheme> RenderThemeSafari::create() 70 { 71 return adoptRef(new RenderThemeSafari); 72 } 73 74 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) 75 { 76 static RenderTheme* safariTheme = RenderThemeSafari::create().releaseRef(); 77 static RenderTheme* windowsTheme = RenderThemeWin::create().releaseRef(); 78 79 // FIXME: This is called before Settings has been initialized by WebKit, so will return a 80 // potentially wrong answer the very first time it's called (see 81 // <https://bugs.webkit.org/show_bug.cgi?id=26493>). 82 if (Settings::shouldPaintNativeControls()) { 83 RenderTheme::setCustomFocusRingColor(safariTheme->platformFocusRingColor()); 84 return windowsTheme; // keep the reference of one. 85 } 86 return safariTheme; // keep the reference of one. 87 } 88 89 #ifdef DEBUG_ALL 90 SOFT_LINK_DEBUG_LIBRARY(SafariTheme) 91 #else 92 SOFT_LINK_LIBRARY(SafariTheme) 93 #endif 94 95 SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state), (part, context, rect, size, state)) 96 #if defined(SAFARI_THEME_VERSION) && SAFARI_THEME_VERSION >= 2 97 SOFT_LINK(SafariTheme, STPaintProgressIndicator, void, APIENTRY, (ProgressIndicatorType type, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state, float value), (type, context, rect, size, state, value)) 98 #endif 99 SOFT_LINK_OPTIONAL(SafariTheme, STCopyThemeColor, CGColorRef, APIENTRY, (unsigned color, SafariTheme::ThemeControlState)); 100 101 static const unsigned stFocusRingColorID = 4; 102 103 static const unsigned aquaFocusRingColor = 0xFF7DADD9; 104 105 static RGBA32 makeRGBAFromCGColor(CGColorRef color) 106 { 107 const CGFloat* components = CGColorGetComponents(color); 108 return makeRGBA(255 * components[0], 255 * components[1], 255 * components[2], 255 * components[3]); 109 } 110 111 ThemeControlState RenderThemeSafari::determineState(RenderObject* o) const 112 { 113 ThemeControlState result = 0; 114 if (isActive(o)) 115 result |= SafariTheme::ActiveState; 116 if (isEnabled(o) && !isReadOnlyControl(o)) 117 result |= SafariTheme::EnabledState; 118 if (isPressed(o)) 119 result |= SafariTheme::PressedState; 120 if (isChecked(o)) 121 result |= SafariTheme::CheckedState; 122 if (isIndeterminate(o)) 123 result |= SafariTheme::IndeterminateCheckedState; 124 if (isFocused(o)) 125 result |= SafariTheme::FocusedState; 126 if (isDefault(o)) 127 result |= SafariTheme::DefaultState; 128 return result; 129 } 130 131 static NSControlSize controlSizeFromRect(const IntRect& rect, const IntSize sizes[]) 132 { 133 if (sizes[NSRegularControlSize].height() == rect.height()) 134 return NSRegularControlSize; 135 else if (sizes[NSMiniControlSize].height() == rect.height()) 136 return NSMiniControlSize; 137 138 return NSSmallControlSize; 139 } 140 141 RenderThemeSafari::RenderThemeSafari() 142 { 143 } 144 145 RenderThemeSafari::~RenderThemeSafari() 146 { 147 } 148 149 Color RenderThemeSafari::platformActiveSelectionBackgroundColor() const 150 { 151 return Color(181, 213, 255); 152 } 153 154 Color RenderThemeSafari::platformInactiveSelectionBackgroundColor() const 155 { 156 return Color(212, 212, 212); 157 } 158 159 Color RenderThemeSafari::activeListBoxSelectionBackgroundColor() const 160 { 161 // FIXME: This should probably just be a darker version of the platformActiveSelectionBackgroundColor 162 return Color(56, 117, 215); 163 } 164 165 Color RenderThemeSafari::platformFocusRingColor() const 166 { 167 static Color focusRingColor; 168 169 if (!focusRingColor.isValid()) { 170 if (STCopyThemeColorPtr()) { 171 RetainPtr<CGColorRef> color(AdoptCF, STCopyThemeColorPtr()(stFocusRingColorID, SafariTheme::ActiveState)); 172 focusRingColor = makeRGBAFromCGColor(color.get()); 173 } 174 if (!focusRingColor.isValid()) 175 focusRingColor = aquaFocusRingColor; 176 } 177 178 return focusRingColor; 179 } 180 181 static float systemFontSizeForControlSize(NSControlSize controlSize) 182 { 183 static float sizes[] = { 13.0f, 11.0f, 9.0f }; 184 185 return sizes[controlSize]; 186 } 187 188 void RenderThemeSafari::systemFont(int propId, FontDescription& fontDescription) const 189 { 190 static FontDescription systemFont; 191 static FontDescription smallSystemFont; 192 static FontDescription menuFont; 193 static FontDescription labelFont; 194 static FontDescription miniControlFont; 195 static FontDescription smallControlFont; 196 static FontDescription controlFont; 197 198 FontDescription* cachedDesc; 199 float fontSize = 0; 200 switch (propId) { 201 case CSSValueSmallCaption: 202 cachedDesc = &smallSystemFont; 203 if (!smallSystemFont.isAbsoluteSize()) 204 fontSize = systemFontSizeForControlSize(NSSmallControlSize); 205 break; 206 case CSSValueMenu: 207 cachedDesc = &menuFont; 208 if (!menuFont.isAbsoluteSize()) 209 fontSize = systemFontSizeForControlSize(NSRegularControlSize); 210 break; 211 case CSSValueStatusBar: 212 cachedDesc = &labelFont; 213 if (!labelFont.isAbsoluteSize()) 214 fontSize = 10.0f; 215 break; 216 case CSSValueWebkitMiniControl: 217 cachedDesc = &miniControlFont; 218 if (!miniControlFont.isAbsoluteSize()) 219 fontSize = systemFontSizeForControlSize(NSMiniControlSize); 220 break; 221 case CSSValueWebkitSmallControl: 222 cachedDesc = &smallControlFont; 223 if (!smallControlFont.isAbsoluteSize()) 224 fontSize = systemFontSizeForControlSize(NSSmallControlSize); 225 break; 226 case CSSValueWebkitControl: 227 cachedDesc = &controlFont; 228 if (!controlFont.isAbsoluteSize()) 229 fontSize = systemFontSizeForControlSize(NSRegularControlSize); 230 break; 231 default: 232 cachedDesc = &systemFont; 233 if (!systemFont.isAbsoluteSize()) 234 fontSize = 13.0f; 235 } 236 237 if (fontSize) { 238 cachedDesc->setIsAbsoluteSize(true); 239 cachedDesc->setGenericFamily(FontDescription::NoFamily); 240 cachedDesc->firstFamily().setFamily("Lucida Grande"); 241 cachedDesc->setSpecifiedSize(fontSize); 242 cachedDesc->setWeight(FontWeightNormal); 243 cachedDesc->setItalic(false); 244 } 245 fontDescription = *cachedDesc; 246 } 247 248 bool RenderThemeSafari::isControlStyled(const RenderStyle* style, const BorderData& border, 249 const FillLayer& background, const Color& backgroundColor) const 250 { 251 // If we didn't find SafariTheme.dll we won't be able to paint any themed controls. 252 if (!SafariThemeLibrary()) 253 return true; 254 255 if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart) 256 return style->border() != border; 257 return RenderTheme::isControlStyled(style, border, background, backgroundColor); 258 } 259 260 void RenderThemeSafari::adjustRepaintRect(const RenderObject* o, IntRect& r) 261 { 262 NSControlSize controlSize = controlSizeForFont(o->style()); 263 264 switch (o->style()->appearance()) { 265 case CheckboxPart: { 266 // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox 267 // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. 268 r = inflateRect(r, checkboxSizes()[controlSize], checkboxMargins(controlSize)); 269 break; 270 } 271 case RadioPart: { 272 // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox 273 // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. 274 r = inflateRect(r, radioSizes()[controlSize], radioMargins(controlSize)); 275 break; 276 } 277 case PushButtonPart: 278 case DefaultButtonPart: 279 case ButtonPart: { 280 // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox 281 // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. 282 if (r.height() <= buttonSizes()[NSRegularControlSize].height()) 283 r = inflateRect(r, buttonSizes()[controlSize], buttonMargins(controlSize)); 284 break; 285 } 286 case MenulistPart: { 287 r = inflateRect(r, popupButtonSizes()[controlSize], popupButtonMargins(controlSize)); 288 break; 289 } 290 default: 291 break; 292 } 293 } 294 295 IntRect RenderThemeSafari::inflateRect(const IntRect& r, const IntSize& size, const int* margins) const 296 { 297 // Only do the inflation if the available width/height are too small. Otherwise try to 298 // fit the glow/check space into the available box's width/height. 299 int widthDelta = r.width() - (size.width() + margins[leftMargin] + margins[rightMargin]); 300 int heightDelta = r.height() - (size.height() + margins[topMargin] + margins[bottomMargin]); 301 IntRect result(r); 302 if (widthDelta < 0) { 303 result.setX(result.x() - margins[leftMargin]); 304 result.setWidth(result.width() - widthDelta); 305 } 306 if (heightDelta < 0) { 307 result.setY(result.y() - margins[topMargin]); 308 result.setHeight(result.height() - heightDelta); 309 } 310 return result; 311 } 312 313 int RenderThemeSafari::baselinePosition(const RenderObject* o) const 314 { 315 if (!o->isBox()) 316 return 0; 317 318 if (o->style()->appearance() == CheckboxPart || o->style()->appearance() == RadioPart) { 319 const RenderBox* box = toRenderBox(o); 320 return box->marginTop() + box->height() - 2; // The baseline is 2px up from the bottom of the checkbox/radio in AppKit. 321 } 322 323 return RenderTheme::baselinePosition(o); 324 } 325 326 bool RenderThemeSafari::controlSupportsTints(const RenderObject* o) const 327 { 328 if (!isEnabled(o)) 329 return false; 330 331 // Checkboxes only have tint when checked. 332 if (o->style()->appearance() == CheckboxPart) 333 return isChecked(o); 334 335 // For now assume other controls have tint if enabled. 336 return true; 337 } 338 339 NSControlSize RenderThemeSafari::controlSizeForFont(RenderStyle* style) const 340 { 341 int fontSize = style->fontSize(); 342 if (fontSize >= 16) 343 return NSRegularControlSize; 344 if (fontSize >= 11) 345 return NSSmallControlSize; 346 return NSMiniControlSize; 347 } 348 /* 349 void RenderThemeSafari::setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minSize) 350 { 351 NSControlSize size; 352 if (minSize.width() >= sizes[NSRegularControlSize].width() && 353 minSize.height() >= sizes[NSRegularControlSize].height()) 354 size = NSRegularControlSize; 355 else if (minSize.width() >= sizes[NSSmallControlSize].width() && 356 minSize.height() >= sizes[NSSmallControlSize].height()) 357 size = NSSmallControlSize; 358 else 359 size = NSMiniControlSize; 360 if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same. 361 [cell setControlSize:size]; 362 } 363 */ 364 IntSize RenderThemeSafari::sizeForFont(RenderStyle* style, const IntSize* sizes) const 365 { 366 return sizes[controlSizeForFont(style)]; 367 } 368 369 IntSize RenderThemeSafari::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const 370 { 371 return sizes[controlSizeForSystemFont(style)]; 372 } 373 374 void RenderThemeSafari::setSizeFromFont(RenderStyle* style, const IntSize* sizes) const 375 { 376 // FIXME: Check is flawed, since it doesn't take min-width/max-width into account. 377 IntSize size = sizeForFont(style, sizes); 378 if (style->width().isIntrinsicOrAuto() && size.width() > 0) 379 style->setWidth(Length(size.width(), Fixed)); 380 if (style->height().isAuto() && size.height() > 0) 381 style->setHeight(Length(size.height(), Fixed)); 382 } 383 384 void RenderThemeSafari::setFontFromControlSize(CSSStyleSelector* selector, RenderStyle* style, NSControlSize controlSize) const 385 { 386 FontDescription fontDescription; 387 fontDescription.setIsAbsoluteSize(true); 388 fontDescription.setGenericFamily(FontDescription::SerifFamily); 389 390 float fontSize = systemFontSizeForControlSize(controlSize); 391 fontDescription.firstFamily().setFamily("Lucida Grande"); 392 fontDescription.setComputedSize(fontSize); 393 fontDescription.setSpecifiedSize(fontSize); 394 395 // Reset line height 396 style->setLineHeight(RenderStyle::initialLineHeight()); 397 398 if (style->setFontDescription(fontDescription)) 399 style->font().update(selector->fontSelector()); 400 } 401 402 NSControlSize RenderThemeSafari::controlSizeForSystemFont(RenderStyle* style) const 403 { 404 int fontSize = style->fontSize(); 405 if (fontSize >= 13) 406 return NSRegularControlSize; 407 if (fontSize >= 11) 408 return NSSmallControlSize; 409 return NSMiniControlSize; 410 } 411 412 bool RenderThemeSafari::paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 413 { 414 ASSERT(SafariThemeLibrary()); 415 416 NSControlSize controlSize = controlSizeForFont(o->style()); 417 418 IntRect inflatedRect = inflateRect(r, checkboxSizes()[controlSize], checkboxMargins(controlSize)); 419 paintThemePart(SafariTheme::CheckboxPart, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o)); 420 421 return false; 422 } 423 424 const IntSize* RenderThemeSafari::checkboxSizes() const 425 { 426 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; 427 return sizes; 428 } 429 430 const int* RenderThemeSafari::checkboxMargins(NSControlSize controlSize) const 431 { 432 static const int margins[3][4] = 433 { 434 { 2, 2, 2, 2 }, 435 { 2, 2, 2, 1 }, 436 { 1, 0, 0, 0 }, 437 }; 438 return margins[controlSize]; 439 } 440 441 void RenderThemeSafari::setCheckboxSize(RenderStyle* style) const 442 { 443 // If the width and height are both specified, then we have nothing to do. 444 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) 445 return; 446 447 // Use the font size to determine the intrinsic width of the control. 448 setSizeFromFont(style, checkboxSizes()); 449 } 450 451 bool RenderThemeSafari::paintRadio(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 452 { 453 ASSERT(SafariThemeLibrary()); 454 455 NSControlSize controlSize = controlSizeForFont(o->style()); 456 457 IntRect inflatedRect = inflateRect(r, radioSizes()[controlSize], radioMargins(controlSize)); 458 paintThemePart(RadioButtonPart, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o)); 459 460 return false; 461 } 462 463 const IntSize* RenderThemeSafari::radioSizes() const 464 { 465 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; 466 return sizes; 467 } 468 469 const int* RenderThemeSafari::radioMargins(NSControlSize controlSize) const 470 { 471 static const int margins[3][4] = 472 { 473 { 1, 2, 2, 2 }, 474 { 0, 1, 2, 1 }, 475 { 0, 0, 1, 0 }, 476 }; 477 return margins[controlSize]; 478 } 479 480 void RenderThemeSafari::setRadioSize(RenderStyle* style) const 481 { 482 // If the width and height are both specified, then we have nothing to do. 483 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) 484 return; 485 486 // Use the font size to determine the intrinsic width of the control. 487 setSizeFromFont(style, radioSizes()); 488 } 489 490 void RenderThemeSafari::setButtonPaddingFromControlSize(RenderStyle* style, NSControlSize size) const 491 { 492 // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large 493 // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is 494 // by definition constrained, since we select mini only for small cramped environments. 495 // This also guarantees the HTML4 <button> will match our rendering by default, since we're using a consistent 496 // padding. 497 const int padding = 8; 498 style->setPaddingLeft(Length(padding, Fixed)); 499 style->setPaddingRight(Length(padding, Fixed)); 500 style->setPaddingTop(Length(0, Fixed)); 501 style->setPaddingBottom(Length(0, Fixed)); 502 } 503 504 void RenderThemeSafari::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 505 { 506 // There are three appearance constants for buttons. 507 // (1) Push-button is the constant for the default Aqua system button. Push buttons will not scale vertically and will not allow 508 // custom fonts or colors. <input>s use this constant. This button will allow custom colors and font weights/variants but won't 509 // scale vertically. 510 // (2) square-button is the constant for the square button. This button will allow custom fonts and colors and will scale vertically. 511 // (3) Button is the constant that means "pick the best button as appropriate." <button>s use this constant. This button will 512 // also scale vertically and allow custom fonts and colors. It will attempt to use Aqua if possible and will make this determination 513 // solely on the rectangle of the control. 514 515 // Determine our control size based off our font. 516 NSControlSize controlSize = controlSizeForFont(style); 517 518 if (style->appearance() == PushButtonPart) { 519 // Ditch the border. 520 style->resetBorder(); 521 522 // Height is locked to auto. 523 style->setHeight(Length(Auto)); 524 525 // White-space is locked to pre 526 style->setWhiteSpace(PRE); 527 528 // Set the button's vertical size. 529 setButtonSize(style); 530 531 // Add in the padding that we'd like to use. 532 setButtonPaddingFromControlSize(style, controlSize); 533 534 // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out 535 // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate 536 // system font for the control size instead. 537 setFontFromControlSize(selector, style, controlSize); 538 } else { 539 // Set a min-height so that we can't get smaller than the mini button. 540 style->setMinHeight(Length(15, Fixed)); 541 542 // Reset the top and bottom borders. 543 style->resetBorderTop(); 544 style->resetBorderBottom(); 545 } 546 } 547 548 const IntSize* RenderThemeSafari::buttonSizes() const 549 { 550 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; 551 return sizes; 552 } 553 554 const int* RenderThemeSafari::buttonMargins(NSControlSize controlSize) const 555 { 556 static const int margins[3][4] = 557 { 558 { 4, 6, 7, 6 }, 559 { 4, 5, 6, 5 }, 560 { 0, 1, 1, 1 }, 561 }; 562 return margins[controlSize]; 563 } 564 565 void RenderThemeSafari::setButtonSize(RenderStyle* style) const 566 { 567 // If the width and height are both specified, then we have nothing to do. 568 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) 569 return; 570 571 // Use the font size to determine the intrinsic width of the control. 572 setSizeFromFont(style, buttonSizes()); 573 } 574 575 bool RenderThemeSafari::paintButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 576 { 577 ASSERT(SafariThemeLibrary()); 578 579 // We inflate the rect as needed to account for padding included in the cell to accommodate the button 580 // shadow. We don't consider this part of the bounds of the control in WebKit. 581 582 NSControlSize controlSize = controlSizeFromRect(r, buttonSizes()); 583 IntRect inflatedRect = r; 584 585 ThemePart part; 586 if (r.height() <= buttonSizes()[NSRegularControlSize].height()) { 587 // Push button 588 part = SafariTheme::PushButtonPart; 589 590 IntSize size = buttonSizes()[controlSize]; 591 size.setWidth(r.width()); 592 593 // Center the button within the available space. 594 if (inflatedRect.height() > size.height()) { 595 inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - size.height()) / 2); 596 inflatedRect.setHeight(size.height()); 597 } 598 599 // Now inflate it to account for the shadow. 600 inflatedRect = inflateRect(inflatedRect, size, buttonMargins(controlSize)); 601 } else 602 part = SafariTheme::SquareButtonPart; 603 604 paintThemePart(part, paintInfo.context->platformContext(), inflatedRect, controlSize, determineState(o)); 605 return false; 606 } 607 608 bool RenderThemeSafari::paintTextField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 609 { 610 ASSERT(SafariThemeLibrary()); 611 612 paintThemePart(SafariTheme::TextFieldPart, paintInfo.context->platformContext(), r, (NSControlSize)0, determineState(o) & ~FocusedState); 613 return false; 614 } 615 616 void RenderThemeSafari::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const 617 { 618 } 619 620 bool RenderThemeSafari::paintCapsLockIndicator(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 621 { 622 #if defined(SAFARI_THEME_VERSION) && SAFARI_THEME_VERSION >= 1 623 ASSERT(SafariThemeLibrary()); 624 625 if (paintInfo.context->paintingDisabled()) 626 return true; 627 628 paintThemePart(CapsLockPart, paintInfo.context->platformContext(), r, (NSControlSize)0, (ThemeControlState)0); 629 630 return false; 631 #else 632 return true; 633 #endif 634 } 635 636 bool RenderThemeSafari::paintTextArea(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 637 { 638 ASSERT(SafariThemeLibrary()); 639 640 paintThemePart(SafariTheme::TextAreaPart, paintInfo.context->platformContext(), r, (NSControlSize)0, determineState(o) & ~FocusedState); 641 return false; 642 } 643 644 void RenderThemeSafari::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const 645 { 646 } 647 648 const int* RenderThemeSafari::popupButtonMargins(NSControlSize size) const 649 { 650 static const int margins[3][4] = 651 { 652 { 2, 3, 3, 3 }, 653 { 1, 3, 3, 3 }, 654 { 0, 1, 0, 1 } 655 }; 656 return margins[size]; 657 } 658 659 const IntSize* RenderThemeSafari::popupButtonSizes() const 660 { 661 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; 662 return sizes; 663 } 664 665 const int* RenderThemeSafari::popupButtonPadding(NSControlSize size) const 666 { 667 static const int padding[3][4] = 668 { 669 { 2, 26, 3, 8 }, 670 { 2, 23, 3, 8 }, 671 { 2, 22, 3, 10 } 672 }; 673 return padding[size]; 674 } 675 676 bool RenderThemeSafari::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& info, const IntRect& r) 677 { 678 ASSERT(SafariThemeLibrary()); 679 680 NSControlSize controlSize = controlSizeFromRect(r, popupButtonSizes()); 681 IntRect inflatedRect = r; 682 IntSize size = popupButtonSizes()[controlSize]; 683 size.setWidth(r.width()); 684 685 // Now inflate it to account for the shadow. 686 if (r.width() >= minimumMenuListSize(o->style())) 687 inflatedRect = inflateRect(inflatedRect, size, popupButtonMargins(controlSize)); 688 689 paintThemePart(DropDownButtonPart, info.context->platformContext(), inflatedRect, controlSize, determineState(o)); 690 691 return false; 692 } 693 694 const float baseFontSize = 11.0f; 695 const float baseArrowHeight = 5.0f; 696 const float baseArrowWidth = 7.0f; 697 const int arrowPaddingLeft = 5; 698 const int arrowPaddingRight = 5; 699 const int paddingBeforeSeparator = 4; 700 const int baseBorderRadius = 5; 701 const int styledPopupPaddingLeft = 8; 702 const int styledPopupPaddingTop = 1; 703 const int styledPopupPaddingBottom = 2; 704 705 static void TopGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) 706 { 707 static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f }; 708 static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f }; 709 float a = inData[0]; 710 int i = 0; 711 for (i = 0; i < 4; i++) 712 outData[i] = (1.0f - a) * dark[i] + a * light[i]; 713 } 714 715 static void BottomGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) 716 { 717 static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f }; 718 static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f }; 719 float a = inData[0]; 720 int i = 0; 721 for (i = 0; i < 4; i++) 722 outData[i] = (1.0f - a) * dark[i] + a * light[i]; 723 } 724 725 static void MainGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) 726 { 727 static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f }; 728 static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; 729 float a = inData[0]; 730 int i = 0; 731 for (i = 0; i < 4; i++) 732 outData[i] = (1.0f - a) * dark[i] + a * light[i]; 733 } 734 735 static void TrackGradientInterpolate(void* info, const CGFloat* inData, CGFloat* outData) 736 { 737 static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.678f }; 738 static float light[4] = { 0.0f, 0.0f, 0.0f, 0.13f }; 739 float a = inData[0]; 740 int i = 0; 741 for (i = 0; i < 4; i++) 742 outData[i] = (1.0f - a) * dark[i] + a * light[i]; 743 } 744 745 void RenderThemeSafari::paintMenuListButtonGradients(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 746 { 747 if (r.isEmpty()) 748 return; 749 750 CGContextRef context = paintInfo.context->platformContext(); 751 752 paintInfo.context->save(); 753 754 IntSize topLeftRadius; 755 IntSize topRightRadius; 756 IntSize bottomLeftRadius; 757 IntSize bottomRightRadius; 758 759 o->style()->getBorderRadiiForRect(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 760 761 int radius = topLeftRadius.width(); 762 763 RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 764 765 FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f); 766 struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL }; 767 RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks)); 768 RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.bottom()), topFunction.get(), false, false)); 769 770 FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f); 771 struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL }; 772 RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks)); 773 RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.bottom()), bottomFunction.get(), false, false)); 774 775 struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL }; 776 RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks)); 777 RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.bottom()), mainFunction.get(), false, false)); 778 779 RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false)); 780 781 RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace.get(), CGPointMake(r.right(), r.y()), CGPointMake(r.right() - radius, r.y()), mainFunction.get(), false, false)); 782 paintInfo.context->save(); 783 CGContextClipToRect(context, r); 784 paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 785 CGContextDrawShading(context, mainShading.get()); 786 paintInfo.context->restore(); 787 788 paintInfo.context->save(); 789 CGContextClipToRect(context, topGradient); 790 paintInfo.context->addRoundedRectClip(enclosingIntRect(topGradient), topLeftRadius, topRightRadius, IntSize(), IntSize()); 791 CGContextDrawShading(context, topShading.get()); 792 paintInfo.context->restore(); 793 794 if (!bottomGradient.isEmpty()) { 795 paintInfo.context->save(); 796 CGContextClipToRect(context, bottomGradient); 797 paintInfo.context->addRoundedRectClip(enclosingIntRect(bottomGradient), IntSize(), IntSize(), bottomLeftRadius, bottomRightRadius); 798 CGContextDrawShading(context, bottomShading.get()); 799 paintInfo.context->restore(); 800 } 801 802 paintInfo.context->save(); 803 CGContextClipToRect(context, r); 804 paintInfo.context->addRoundedRectClip(r, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius); 805 CGContextDrawShading(context, leftShading.get()); 806 CGContextDrawShading(context, rightShading.get()); 807 paintInfo.context->restore(); 808 809 paintInfo.context->restore(); 810 } 811 812 bool RenderThemeSafari::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 813 { 814 IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(), 815 r.y() + o->style()->borderTopWidth(), 816 r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(), 817 r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth()); 818 // Draw the gradients to give the styled popup menu a button appearance 819 paintMenuListButtonGradients(o, paintInfo, bounds); 820 821 // Since we actually know the size of the control here, we restrict the font scale to make sure the arrow will fit vertically in the bounds 822 float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / baseArrowHeight); 823 float centerY = bounds.y() + bounds.height() / 2.0f; 824 float arrowHeight = baseArrowHeight * fontScale; 825 float arrowWidth = baseArrowWidth * fontScale; 826 float leftEdge = bounds.right() - arrowPaddingRight - arrowWidth; 827 828 if (bounds.width() < arrowWidth + arrowPaddingLeft) 829 return false; 830 831 paintInfo.context->save(); 832 833 paintInfo.context->setFillColor(o->style()->color(), DeviceColorSpace); 834 paintInfo.context->setStrokeColor(NoStroke, DeviceColorSpace); 835 836 FloatPoint arrow[3]; 837 arrow[0] = FloatPoint(leftEdge, centerY - arrowHeight / 2.0f); 838 arrow[1] = FloatPoint(leftEdge + arrowWidth, centerY - arrowHeight / 2.0f); 839 arrow[2] = FloatPoint(leftEdge + arrowWidth / 2.0f, centerY + arrowHeight / 2.0f); 840 841 // Draw the arrow 842 paintInfo.context->drawConvexPolygon(3, arrow, true); 843 844 Color leftSeparatorColor(0, 0, 0, 40); 845 Color rightSeparatorColor(255, 255, 255, 40); 846 847 // FIXME: Should the separator thickness and space be scaled up by fontScale? 848 int separatorSpace = 2; 849 int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft); // FIXME: Round? 850 851 // Draw the separator to the left of the arrows 852 paintInfo.context->setStrokeThickness(1.0f); 853 paintInfo.context->setStrokeStyle(SolidStroke); 854 paintInfo.context->setStrokeColor(leftSeparatorColor, DeviceColorSpace); 855 paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()), 856 IntPoint(leftEdgeOfSeparator, bounds.bottom())); 857 858 paintInfo.context->setStrokeColor(rightSeparatorColor, DeviceColorSpace); 859 paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()), 860 IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.bottom())); 861 862 paintInfo.context->restore(); 863 return false; 864 } 865 866 void RenderThemeSafari::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 867 { 868 NSControlSize controlSize = controlSizeForFont(style); 869 870 style->resetBorder(); 871 style->resetPadding(); 872 873 // Height is locked to auto. 874 style->setHeight(Length(Auto)); 875 876 // White-space is locked to pre 877 style->setWhiteSpace(PRE); 878 879 // Set the foreground color to black or gray when we have the aqua look. 880 // Cast to RGB32 is to work around a compiler bug. 881 style->setColor(e && e->isEnabledFormControl() ? static_cast<RGBA32>(Color::black) : Color::darkGray); 882 883 // Set the button's vertical size. 884 setButtonSize(style); 885 886 // Our font is locked to the appropriate system font size for the control. To clarify, we first use the CSS-specified font to figure out 887 // a reasonable control size, but once that control size is determined, we throw that font away and use the appropriate 888 // system font for the control size instead. 889 setFontFromControlSize(selector, style, controlSize); 890 } 891 892 int RenderThemeSafari::popupInternalPaddingLeft(RenderStyle* style) const 893 { 894 if (style->appearance() == MenulistPart) 895 return popupButtonPadding(controlSizeForFont(style))[leftPadding]; 896 if (style->appearance() == MenulistButtonPart) 897 return styledPopupPaddingLeft; 898 return 0; 899 } 900 901 int RenderThemeSafari::popupInternalPaddingRight(RenderStyle* style) const 902 { 903 if (style->appearance() == MenulistPart) 904 return popupButtonPadding(controlSizeForFont(style))[rightPadding]; 905 if (style->appearance() == MenulistButtonPart) { 906 float fontScale = style->fontSize() / baseFontSize; 907 float arrowWidth = baseArrowWidth * fontScale; 908 return static_cast<int>(ceilf(arrowWidth + arrowPaddingLeft + arrowPaddingRight + paddingBeforeSeparator)); 909 } 910 return 0; 911 } 912 913 int RenderThemeSafari::popupInternalPaddingTop(RenderStyle* style) const 914 { 915 if (style->appearance() == MenulistPart) 916 return popupButtonPadding(controlSizeForFont(style))[topPadding]; 917 if (style->appearance() == MenulistButtonPart) 918 return styledPopupPaddingTop; 919 return 0; 920 } 921 922 int RenderThemeSafari::popupInternalPaddingBottom(RenderStyle* style) const 923 { 924 if (style->appearance() == MenulistPart) 925 return popupButtonPadding(controlSizeForFont(style))[bottomPadding]; 926 if (style->appearance() == MenulistButtonPart) 927 return styledPopupPaddingBottom; 928 return 0; 929 } 930 931 void RenderThemeSafari::adjustMenuListButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 932 { 933 float fontScale = style->fontSize() / baseFontSize; 934 935 style->resetPadding(); 936 style->setBorderRadius(IntSize(int(baseBorderRadius + fontScale - 1), int(baseBorderRadius + fontScale - 1))); // FIXME: Round up? 937 938 const int minHeight = 15; 939 style->setMinHeight(Length(minHeight, Fixed)); 940 941 style->setLineHeight(RenderStyle::initialLineHeight()); 942 } 943 944 const IntSize* RenderThemeSafari::menuListSizes() const 945 { 946 static const IntSize sizes[3] = { IntSize(9, 0), IntSize(5, 0), IntSize(0, 0) }; 947 return sizes; 948 } 949 950 int RenderThemeSafari::minimumMenuListSize(RenderStyle* style) const 951 { 952 return sizeForSystemFont(style, menuListSizes()).width(); 953 } 954 955 const int trackWidth = 5; 956 const int trackRadius = 2; 957 958 bool RenderThemeSafari::paintSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 959 { 960 IntRect bounds = r; 961 962 if (o->style()->appearance() == SliderHorizontalPart) { 963 bounds.setHeight(trackWidth); 964 bounds.setY(r.y() + r.height() / 2 - trackWidth / 2); 965 } else if (o->style()->appearance() == SliderVerticalPart) { 966 bounds.setWidth(trackWidth); 967 bounds.setX(r.x() + r.width() / 2 - trackWidth / 2); 968 } 969 970 CGContextRef context = paintInfo.context->platformContext(); 971 RetainPtr<CGColorSpaceRef> cspace(AdoptCF, CGColorSpaceCreateDeviceRGB()); 972 973 paintInfo.context->save(); 974 CGContextClipToRect(context, bounds); 975 976 struct CGFunctionCallbacks mainCallbacks = { 0, TrackGradientInterpolate, NULL }; 977 RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks)); 978 RetainPtr<CGShadingRef> mainShading; 979 if (o->style()->appearance() == SliderVerticalPart) 980 mainShading.adoptCF(CGShadingCreateAxial(cspace.get(), CGPointMake(bounds.x(), bounds.bottom()), CGPointMake(bounds.right(), bounds.bottom()), mainFunction.get(), false, false)); 981 else 982 mainShading.adoptCF(CGShadingCreateAxial(cspace.get(), CGPointMake(bounds.x(), bounds.y()), CGPointMake(bounds.x(), bounds.bottom()), mainFunction.get(), false, false)); 983 984 IntSize radius(trackRadius, trackRadius); 985 paintInfo.context->addRoundedRectClip(bounds, 986 radius, radius, 987 radius, radius); 988 CGContextDrawShading(context, mainShading.get()); 989 paintInfo.context->restore(); 990 991 return false; 992 } 993 994 void RenderThemeSafari::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 995 { 996 style->setBoxShadow(0); 997 } 998 999 const float verticalSliderHeightPadding = 0.1f; 1000 1001 bool RenderThemeSafari::paintSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1002 { 1003 ASSERT(SafariThemeLibrary()); 1004 1005 ASSERT(o->parent()->isSlider()); 1006 1007 bool pressed = toRenderSlider(o->parent())->inDragMode(); 1008 ThemeControlState state = determineState(o->parent()); 1009 state &= ~SafariTheme::PressedState; 1010 if (pressed) 1011 state |= SafariTheme::PressedState; 1012 1013 paintThemePart(SliderThumbPart, paintInfo.context->platformContext(), r, NSSmallControlSize, state); 1014 return false; 1015 } 1016 1017 const int sliderThumbWidth = 15; 1018 const int sliderThumbHeight = 15; 1019 1020 void RenderThemeSafari::adjustSliderThumbSize(RenderObject* o) const 1021 { 1022 if (o->style()->appearance() == SliderThumbHorizontalPart || o->style()->appearance() == SliderThumbVerticalPart) { 1023 o->style()->setWidth(Length(sliderThumbWidth, Fixed)); 1024 o->style()->setHeight(Length(sliderThumbHeight, Fixed)); 1025 } 1026 #if ENABLE(VIDEO) 1027 else if (o->style()->appearance() == MediaSliderThumbPart) 1028 RenderMediaControls::adjustMediaSliderThumbSize(o); 1029 #endif 1030 } 1031 1032 bool RenderThemeSafari::paintSearchField(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1033 { 1034 ASSERT(SafariThemeLibrary()); 1035 1036 paintThemePart(SafariTheme::SearchFieldPart, paintInfo.context->platformContext(), r, controlSizeFromRect(r, searchFieldSizes()), determineState(o)); 1037 return false; 1038 } 1039 1040 const IntSize* RenderThemeSafari::searchFieldSizes() const 1041 { 1042 static const IntSize sizes[3] = { IntSize(0, 22), IntSize(0, 19), IntSize(0, 15) }; 1043 return sizes; 1044 } 1045 1046 void RenderThemeSafari::setSearchFieldSize(RenderStyle* style) const 1047 { 1048 // If the width and height are both specified, then we have nothing to do. 1049 if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) 1050 return; 1051 1052 // Use the font size to determine the intrinsic width of the control. 1053 setSizeFromFont(style, searchFieldSizes()); 1054 } 1055 1056 void RenderThemeSafari::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 1057 { 1058 // Override border. 1059 style->resetBorder(); 1060 const short borderWidth = 2; 1061 style->setBorderLeftWidth(borderWidth); 1062 style->setBorderLeftStyle(INSET); 1063 style->setBorderRightWidth(borderWidth); 1064 style->setBorderRightStyle(INSET); 1065 style->setBorderBottomWidth(borderWidth); 1066 style->setBorderBottomStyle(INSET); 1067 style->setBorderTopWidth(borderWidth); 1068 style->setBorderTopStyle(INSET); 1069 1070 // Override height. 1071 style->setHeight(Length(Auto)); 1072 setSearchFieldSize(style); 1073 1074 // Override padding size to match AppKit text positioning. 1075 const int padding = 1; 1076 style->setPaddingLeft(Length(padding, Fixed)); 1077 style->setPaddingRight(Length(padding, Fixed)); 1078 style->setPaddingTop(Length(padding, Fixed)); 1079 style->setPaddingBottom(Length(padding, Fixed)); 1080 1081 NSControlSize controlSize = controlSizeForFont(style); 1082 setFontFromControlSize(selector, style, controlSize); 1083 } 1084 1085 bool RenderThemeSafari::paintSearchFieldCancelButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect&) 1086 { 1087 ASSERT(SafariThemeLibrary()); 1088 1089 Node* input = o->node()->shadowAncestorNode(); 1090 ASSERT(input); 1091 RenderObject* renderer = input->renderer(); 1092 ASSERT(renderer); 1093 1094 IntRect searchRect = renderer->absoluteBoundingBoxRect(); 1095 1096 paintThemePart(SafariTheme::SearchFieldCancelButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o)); 1097 return false; 1098 } 1099 1100 const IntSize* RenderThemeSafari::cancelButtonSizes() const 1101 { 1102 static const IntSize sizes[3] = { IntSize(16, 13), IntSize(13, 11), IntSize(13, 9) }; 1103 return sizes; 1104 } 1105 1106 void RenderThemeSafari::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 1107 { 1108 IntSize size = sizeForSystemFont(style, cancelButtonSizes()); 1109 style->setWidth(Length(size.width(), Fixed)); 1110 style->setHeight(Length(size.height(), Fixed)); 1111 } 1112 1113 const IntSize* RenderThemeSafari::resultsButtonSizes() const 1114 { 1115 static const IntSize sizes[3] = { IntSize(19, 13), IntSize(17, 11), IntSize(17, 9) }; 1116 return sizes; 1117 } 1118 1119 const int emptyResultsOffset = 9; 1120 void RenderThemeSafari::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 1121 { 1122 IntSize size = sizeForSystemFont(style, resultsButtonSizes()); 1123 style->setWidth(Length(size.width() - emptyResultsOffset, Fixed)); 1124 style->setHeight(Length(size.height(), Fixed)); 1125 } 1126 1127 bool RenderThemeSafari::paintSearchFieldDecoration(RenderObject*, const RenderObject::PaintInfo&, const IntRect&) 1128 { 1129 return false; 1130 } 1131 1132 void RenderThemeSafari::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 1133 { 1134 IntSize size = sizeForSystemFont(style, resultsButtonSizes()); 1135 style->setWidth(Length(size.width(), Fixed)); 1136 style->setHeight(Length(size.height(), Fixed)); 1137 } 1138 1139 bool RenderThemeSafari::paintSearchFieldResultsDecoration(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect&) 1140 { 1141 ASSERT(SafariThemeLibrary()); 1142 1143 Node* input = o->node()->shadowAncestorNode(); 1144 ASSERT(input); 1145 RenderObject* renderer = input->renderer(); 1146 ASSERT(renderer); 1147 1148 IntRect searchRect = renderer->absoluteBoundingBoxRect(); 1149 1150 paintThemePart(SafariTheme::SearchFieldResultsDecorationPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o)); 1151 return false; 1152 } 1153 1154 const int resultsArrowWidth = 5; 1155 void RenderThemeSafari::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 1156 { 1157 IntSize size = sizeForSystemFont(style, resultsButtonSizes()); 1158 style->setWidth(Length(size.width() + resultsArrowWidth, Fixed)); 1159 style->setHeight(Length(size.height(), Fixed)); 1160 } 1161 1162 bool RenderThemeSafari::paintSearchFieldResultsButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect&) 1163 { 1164 ASSERT(SafariThemeLibrary()); 1165 1166 Node* input = o->node()->shadowAncestorNode(); 1167 ASSERT(input); 1168 RenderObject* renderer = input->renderer(); 1169 ASSERT(renderer); 1170 1171 IntRect searchRect = renderer->absoluteBoundingBoxRect(); 1172 1173 paintThemePart(SafariTheme::SearchFieldResultsButtonPart, paintInfo.context->platformContext(), searchRect, controlSizeFromRect(searchRect, searchFieldSizes()), determineState(o)); 1174 return false; 1175 } 1176 #if ENABLE(VIDEO) 1177 bool RenderThemeSafari::paintMediaFullscreenButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1178 { 1179 return RenderMediaControls::paintMediaControlsPart(MediaFullscreenButton, o, paintInfo, r); 1180 } 1181 1182 bool RenderThemeSafari::paintMediaMuteButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1183 { 1184 return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, o, paintInfo, r); 1185 } 1186 1187 bool RenderThemeSafari::paintMediaPlayButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1188 { 1189 return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, o, paintInfo, r); 1190 } 1191 1192 bool RenderThemeSafari::paintMediaSeekBackButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1193 { 1194 return RenderMediaControls::paintMediaControlsPart(MediaSeekBackButton, o, paintInfo, r); 1195 } 1196 1197 bool RenderThemeSafari::paintMediaSeekForwardButton(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1198 { 1199 return RenderMediaControls::paintMediaControlsPart(MediaSeekForwardButton, o, paintInfo, r); 1200 } 1201 1202 bool RenderThemeSafari::paintMediaSliderTrack(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1203 { 1204 return RenderMediaControls::paintMediaControlsPart(MediaSlider, o, paintInfo, r); 1205 } 1206 1207 bool RenderThemeSafari::paintMediaSliderThumb(RenderObject* o, const RenderObject::PaintInfo& paintInfo, const IntRect& r) 1208 { 1209 return RenderMediaControls::paintMediaControlsPart(MediaSliderThumb, o, paintInfo, r); 1210 } 1211 #endif 1212 1213 } // namespace WebCore 1214 1215 #endif // #if USE(SAFARI_THEME) 1216