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