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 47 using std::min; 48 49 // FIXME: The platform-independent code in this class should be factored out and merged with RenderThemeMac. 50 51 namespace WebCore { 52 53 using namespace HTMLNames; 54 using namespace SafariTheme; 55 56 enum { 57 topMargin, 58 rightMargin, 59 bottomMargin, 60 leftMargin 61 }; 62 63 enum { 64 topPadding, 65 rightPadding, 66 bottomPadding, 67 leftPadding 68 }; 69 70 PassRefPtr<RenderTheme> RenderThemeSafari::create() 71 { 72 return adoptRef(new RenderThemeSafari); 73 } 74 75 PassRefPtr<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 91 SOFT_LINK_DEBUG_LIBRARY(SafariTheme) 92 #else 93 SOFT_LINK_LIBRARY(SafariTheme) 94 #endif 95 96 SOFT_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 98 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)) 99 #endif 100 SOFT_LINK_OPTIONAL(SafariTheme, STCopyThemeColor, CGColorRef, APIENTRY, (unsigned color, SafariTheme::ThemeControlState)); 101 102 static const unsigned stFocusRingColorID = 4; 103 104 static const unsigned aquaFocusRingColor = 0xFF7DADD9; 105 106 static 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 112 ThemeControlState 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 132 static 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 142 RenderThemeSafari::RenderThemeSafari() 143 { 144 } 145 146 RenderThemeSafari::~RenderThemeSafari() 147 { 148 } 149 150 Color RenderThemeSafari::platformActiveSelectionBackgroundColor() const 151 { 152 return Color(181, 213, 255); 153 } 154 155 Color RenderThemeSafari::platformInactiveSelectionBackgroundColor() const 156 { 157 return Color(212, 212, 212); 158 } 159 160 Color 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 166 Color 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 182 static float systemFontSizeForControlSize(NSControlSize controlSize) 183 { 184 static float sizes[] = { 13.0f, 11.0f, 9.0f }; 185 186 return sizes[controlSize]; 187 } 188 189 void 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 249 bool 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 261 void 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 296 IntRect 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 314 int 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 327 bool 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 340 NSControlSize 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 /* 350 void 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 */ 365 IntSize RenderThemeSafari::sizeForFont(RenderStyle* style, const IntSize* sizes) const 366 { 367 return sizes[controlSizeForFont(style)]; 368 } 369 370 IntSize RenderThemeSafari::sizeForSystemFont(RenderStyle* style, const IntSize* sizes) const 371 { 372 return sizes[controlSizeForSystemFont(style)]; 373 } 374 375 void 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 385 void 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 403 NSControlSize 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 413 bool 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 425 const 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 431 const 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 442 void 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 452 bool 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 464 const 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 470 const 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 481 void 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 491 void 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 505 void 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 549 const 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 555 const 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 566 void 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 576 bool 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 609 bool 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 617 void RenderThemeSafari::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const 618 { 619 } 620 621 bool 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 637 bool 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 645 void RenderThemeSafari::adjustTextAreaStyle(CSSStyleSelector*, RenderStyle*, Element*) const 646 { 647 } 648 649 const 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 660 const 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 666 const 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 677 bool 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 695 const float baseFontSize = 11.0f; 696 const float baseArrowHeight = 5.0f; 697 const float baseArrowWidth = 7.0f; 698 const int arrowPaddingLeft = 5; 699 const int arrowPaddingRight = 5; 700 const int paddingBeforeSeparator = 4; 701 const int baseBorderRadius = 5; 702 const int styledPopupPaddingLeft = 8; 703 const int styledPopupPaddingTop = 1; 704 const int styledPopupPaddingBottom = 2; 705 706 static 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 716 static 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 726 static 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 736 static 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 746 void 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 807 bool 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 861 void 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 887 int 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 896 int 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 908 int 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 917 int 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 926 void 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 939 const 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 945 int RenderThemeSafari::minimumMenuListSize(RenderStyle* style) const 946 { 947 return sizeForSystemFont(style, menuListSizes()).width(); 948 } 949 950 const int trackWidth = 5; 951 const int trackRadius = 2; 952 953 bool 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 990 void RenderThemeSafari::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const 991 { 992 style->setBoxShadow(0); 993 } 994 995 const float verticalSliderHeightPadding = 0.1f; 996 997 bool 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 1013 const int sliderThumbWidth = 15; 1014 const int sliderThumbHeight = 15; 1015 1016 void 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 1028 bool 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 1036 const 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 1042 void 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 1052 void 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 1081 bool 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 1096 const 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 1102 void 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 1109 const 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 1115 const int emptyResultsOffset = 9; 1116 void 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 1123 bool RenderThemeSafari::paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&) 1124 { 1125 return false; 1126 } 1127 1128 void 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 1135 bool 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 1150 const int resultsArrowWidth = 5; 1151 void 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 1158 bool 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) 1173 bool RenderThemeSafari::paintMediaFullscreenButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1174 { 1175 return RenderMediaControls::paintMediaControlsPart(MediaFullscreenButton, o, paintInfo, r); 1176 } 1177 1178 bool RenderThemeSafari::paintMediaMuteButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1179 { 1180 return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, o, paintInfo, r); 1181 } 1182 1183 bool RenderThemeSafari::paintMediaPlayButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1184 { 1185 return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, o, paintInfo, r); 1186 } 1187 1188 bool RenderThemeSafari::paintMediaSeekBackButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1189 { 1190 return RenderMediaControls::paintMediaControlsPart(MediaSeekBackButton, o, paintInfo, r); 1191 } 1192 1193 bool RenderThemeSafari::paintMediaSeekForwardButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1194 { 1195 return RenderMediaControls::paintMediaControlsPart(MediaSeekForwardButton, o, paintInfo, r); 1196 } 1197 1198 bool RenderThemeSafari::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) 1199 { 1200 return RenderMediaControls::paintMediaControlsPart(MediaSlider, o, paintInfo, r); 1201 } 1202 1203 bool 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