1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "config.h" 27 28 #include <cstdio> 29 #include <wtf/Vector.h> 30 #include <wtf/text/StringBuilder.h> 31 32 #include "Chrome.h" 33 #include "ChromeClientJava.h" 34 #include "CSSPropertyNames.h" 35 #include "CSSFontSelector.h" 36 #include "CSSValueKeywords.h" 37 #include <wtf/java/JavaEnv.h> 38 #include "HTMLMediaElement.h" 39 #include "NotImplemented.h" 40 #include "PaintInfo.h" 41 #include "PlatformContextJava.h" 42 #include "RenderObject.h" 43 #if ENABLE(PROGRESS_ELEMENT) 44 #include "RenderProgress.h" 45 #endif 46 #if ENABLE(METER_ELEMENT) 47 #include "HTMLMeterElement.h" 48 #endif 49 #include "RenderSlider.h" 50 #include "RenderThemeJava.h" 51 #include "ThemeTypes.h" 52 #include "TimeRanges.h" 53 #include "UserAgentScripts.h" 54 #include "UserAgentStyleSheets.h" 55 #include "MediaControlElementTypes.h" 56 #include "Page.h" 57 58 #include "com_sun_webkit_graphics_RenderTheme.h" 59 #include "com_sun_webkit_graphics_GraphicsDecoder.h" 60 #include "com_sun_webkit_graphics_RenderMediaControls.h" 61 62 63 #define RENDER_MEDIA_CONTROLS_CLASS_NAME "com/sun/webkit/graphics/RenderMediaControls" 64 65 #define JNI_EXPAND(n) com_sun_webkit_graphics_RenderTheme_##n 66 #define JNI_EXPAND_MEDIA(n) com_sun_webkit_graphics_RenderMediaControls_##n 67 68 namespace WebCore { 69 70 RenderTheme& RenderTheme::singleton() 71 { 72 static RenderTheme& sm_defaultInstance = *new RenderThemeJava(); 73 return sm_defaultInstance; 74 } 75 76 jclass getJRenderThemeClass() 77 { 78 static JGClass jRenderThemeCls( 79 WebCore_GetJavaEnv()->FindClass("com/sun/webkit/graphics/RenderTheme")); 80 ASSERT(jRenderThemeCls); 81 82 return jRenderThemeCls; 83 } 84 85 static JLObject getJRenderTheme(JLObject page) 86 { 87 JNIEnv* env = WebCore_GetJavaEnv(); 88 89 if (!page) { 90 static jmethodID mid = env->GetStaticMethodID( 91 PG_GetWebPageClass(env), 92 "fwkGetDefaultRenderTheme", 93 "()Lcom/sun/webkit/graphics/RenderTheme;"); 94 ASSERT(mid); 95 96 JLObject jRenderTheme(env->CallStaticObjectMethod(PG_GetWebPageClass(env), mid)); 97 CheckAndClearException(env); 98 99 return jRenderTheme; 100 } 101 102 static jmethodID mid = env->GetMethodID( 103 PG_GetWebPageClass(env), 104 "getRenderTheme", 105 "()Lcom/sun/webkit/graphics/RenderTheme;"); 106 ASSERT(mid); 107 108 JLObject jRenderTheme(env->CallObjectMethod( 109 page, 110 mid)); 111 CheckAndClearException(env); 112 113 return jRenderTheme; 114 } 115 116 RefPtr<RQRef> RenderThemeJava::themeForPage(JLObject page) 117 { 118 return RQRef::create(getJRenderTheme(page)); 119 } 120 121 RenderThemeJava::RenderThemeJava() 122 { 123 } 124 125 int RenderThemeJava::createWidgetState(const RenderObject& o) 126 { 127 int state = 0; 128 if (isChecked(o)) 129 state |= JNI_EXPAND(CHECKED); 130 if (isIndeterminate(o)) 131 state |= JNI_EXPAND(INDETERMINATE); 132 if (isEnabled(o)) 133 state |= JNI_EXPAND(ENABLED); 134 if (isFocused(o)) 135 state |= JNI_EXPAND(FOCUSED); 136 if (isPressed(o)) 137 state |= JNI_EXPAND(PRESSED); 138 if (isHovered(o)) 139 state |= JNI_EXPAND(HOVERED); 140 if (isReadOnlyControl(o)) 141 state |= JNI_EXPAND(READ_ONLY); 142 return state; 143 } 144 145 bool RenderThemeJava::paintWidget( 146 int widgetIndex, 147 const RenderObject& object, 148 const PaintInfo &paintInfo, 149 const FloatRect &rect) { 150 151 return paintWidget(widgetIndex, object, paintInfo, enclosingIntRect(rect)); 152 } 153 154 bool RenderThemeJava::paintWidget( 155 int widgetIndex, 156 const RenderObject& object, 157 const PaintInfo &paintInfo, 158 const IntRect &rect) 159 { 160 // platformContext() returns 0 when printing 161 if (paintInfo.context().paintingDisabled() || !paintInfo.context().platformContext()) { 162 return false; 163 } 164 165 auto jRenderTheme = paintInfo.context().platformContext()->jRenderTheme(); 166 if (!jRenderTheme) { 167 return false; 168 } 169 170 int state = createWidgetState(object); 171 RGBA32 bgColor = object.style().visitedDependentColor( 172 widgetIndex == JNI_EXPAND(MENU_LIST_BUTTON) 173 ? CSSPropertyColor 174 : CSSPropertyBackgroundColor 175 ).rgb(); 176 177 JNIEnv* env = WebCore_GetJavaEnv(); 178 179 WTF::Vector<jbyte> extParams; 180 if (JNI_EXPAND(SLIDER) == widgetIndex && is<RenderSlider>(object)) { 181 HTMLInputElement& input = downcast<RenderSlider>(object).element(); 182 183 extParams.grow(sizeof(jint) + 3 * sizeof(jfloat)); 184 jbyte *data = extParams.data(); 185 auto isVertical = jint((object.style().appearance() == SliderHorizontalPart) 186 ? 0 187 : 1); 188 memcpy(data, &isVertical, sizeof(isVertical)); 189 data += sizeof(jint); 190 191 auto maximum = jfloat(input.maximum()); 192 memcpy(data, &maximum, sizeof(maximum)); 193 data += sizeof(jfloat); 194 195 auto minimum = jfloat(input.minimum()); 196 memcpy(data, &minimum, sizeof(minimum)); 197 data += sizeof(jfloat); 198 199 auto valueAsNumber = jfloat(input.valueAsNumber()); 200 memcpy(data, &valueAsNumber, sizeof(valueAsNumber)); 201 } else if (JNI_EXPAND(PROGRESS_BAR) == widgetIndex) { 202 #if ENABLE(PROGRESS_ELEMENT) 203 if (is<RenderProgress>(object)) { 204 RenderProgress& renderProgress = downcast<RenderProgress>(object); 205 206 extParams.grow(sizeof(jint) + 3*sizeof(jfloat)); 207 jbyte *data = extParams.data(); 208 auto isDeterminate = jint(renderProgress.isDeterminate() ? 1 : 0); 209 memcpy(data, &isDeterminate, sizeof(isDeterminate)); 210 data += sizeof(jint); 211 212 auto position = jfloat(renderProgress.position()); 213 memcpy(data, &position, sizeof(position)); 214 data += sizeof(jfloat); 215 216 auto animationProgress = jfloat(renderProgress.animationProgress()); 217 memcpy(data, &animationProgress, sizeof(animationProgress)); 218 data += sizeof(jfloat); 219 220 auto animationStartTime = jfloat(renderProgress.animationStartTime()); 221 memcpy(data, &animationStartTime, sizeof(animationStartTime)); 222 } 223 #endif 224 #if ENABLE(METER_ELEMENT) 225 } else if (JNI_EXPAND(METER) == widgetIndex) { 226 jfloat value = 0; 227 jint region = 0; 228 if (object.isMeter()) { 229 HTMLMeterElement* meter = static_cast<HTMLMeterElement*>(object.node()); 230 value = meter->valueRatio(); 231 region = meter->gaugeRegion(); 232 #if ENABLE(PROGRESS_ELEMENT) 233 } else if (is<RenderProgress>(object>)) { 234 RenderProgress& renderProgress = downcast<RenderProgress>(object); 235 value = jfloat(renderProgress.position()); 236 #endif 237 } 238 239 extParams.grow(sizeof(jfloat) + sizeof(jint)); 240 jbyte *data = extParams.data(); 241 memcpy(data, &value, sizeof(value)); 242 data += sizeof(jfloat); 243 244 memcpy(data, ®ion, sizeof(region)); 245 #endif 246 } 247 248 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "createWidget", 249 "(JIIIIILjava/nio/ByteBuffer;)Lcom/sun/webkit/graphics/Ref;"); 250 ASSERT(mid); 251 252 RefPtr<RQRef> widgetRef = RQRef::create( 253 env->CallObjectMethod(jobject(*jRenderTheme), mid, 254 ptr_to_jlong(&object), 255 (jint)widgetIndex, 256 (jint)state, 257 (jint)rect.width(), (jint)rect.height(), 258 (jint)bgColor, 259 (jobject)JLObject(extParams.isEmpty() 260 ? nullptr 261 : env->NewDirectByteBuffer( 262 extParams.data(), 263 extParams.size()))) 264 ); 265 if (!widgetRef.get()) { 266 //switch to WebKit default render 267 return true; 268 } 269 CheckAndClearException(env); 270 271 // widgetRef will go into rq's inner refs vector. 272 paintInfo.context().platformContext()->rq().freeSpace(20) 273 << (jint)com_sun_webkit_graphics_GraphicsDecoder_DRAWWIDGET 274 << (jint)*jRenderTheme 275 << widgetRef 276 << (jint)rect.x() << (jint)rect.y(); 277 278 return false; 279 } 280 281 #if ENABLE(PROGRESS_ELEMENT) 282 void RenderThemeJava::adjustProgressBarStyle(StyleResolver&, RenderStyle& style, const Element*) const 283 { 284 style.setBoxShadow(nullptr); 285 } 286 287 //utatodo: ask Java theme 288 // These values have been copied from RenderThemeChromiumSkia.cpp 289 static const int progressActivityBlocks = 5; 290 static const int progressAnimationFrames = 10; 291 static const double progressAnimationInterval = 0.125; 292 double RenderThemeJava::animationRepeatIntervalForProgressBar(RenderProgress&) const 293 { 294 return progressAnimationInterval; 295 } 296 297 double RenderThemeJava::animationDurationForProgressBar(RenderProgress&) const 298 { 299 return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth; 300 } 301 302 bool RenderThemeJava::paintProgressBar(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 303 { 304 return paintWidget(JNI_EXPAND(PROGRESS_BAR), o, i, rect); 305 } 306 #endif 307 308 #if ENABLE(METER_ELEMENT) 309 bool RenderThemeJava::supportsMeter(ControlPart part) const 310 { 311 #if ENABLE(PROGRESS_ELEMENT) 312 if (part == ProgressBarPart) { 313 return true; 314 } 315 #endif 316 return (part == MeterPart); 317 } 318 319 bool RenderThemeJava::paintMeter(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 320 { 321 return paintWidget(JNI_EXPAND(METER), o, i, rect); 322 } 323 #endif 324 325 void RenderThemeJava::setCheckboxSize(RenderStyle& style) const 326 { 327 setRadioSize(style); 328 } 329 330 bool RenderThemeJava::paintCheckbox(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 331 { 332 return paintWidget(JNI_EXPAND(CHECK_BOX), o, i, rect); 333 } 334 335 void RenderThemeJava::setRadioSize(RenderStyle& style) const 336 { 337 // If the width and height are both specified, then we have nothing to do. 338 if ((!style.width().isIntrinsicOrAuto() && !style.height().isAuto())) { 339 return; 340 } 341 342 JNIEnv* env = WebCore_GetJavaEnv(); 343 344 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "getRadioButtonSize", "()I"); 345 ASSERT(mid); 346 347 // Get from default theme object. 348 int radioRadius = env->CallIntMethod((jobject)getJRenderTheme(nullptr), mid); 349 CheckAndClearException(env); 350 351 if (style.width().isIntrinsicOrAuto()) { 352 style.setWidth(Length(radioRadius, Fixed)); 353 } 354 355 if (style.height().isAuto()) { 356 style.setHeight(Length(radioRadius, Fixed)); 357 } 358 } 359 360 bool RenderThemeJava::paintRadio(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 361 { 362 return paintWidget(JNI_EXPAND(RADIO_BUTTON), o, i, rect); 363 } 364 365 bool RenderThemeJava::paintButton(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 366 { 367 return paintWidget(JNI_EXPAND(BUTTON), o, i, rect); 368 } 369 370 void RenderThemeJava::adjustTextFieldStyle(StyleResolver&, RenderStyle&, const Element*) const 371 { 372 notImplemented(); 373 } 374 375 bool RenderThemeJava::paintTextField(const RenderObject&o, const PaintInfo& i, const FloatRect& rect) 376 { 377 return paintWidget(JNI_EXPAND(TEXT_FIELD), o, i, rect); 378 } 379 380 void RenderThemeJava::adjustSearchFieldStyle(StyleResolver&, RenderStyle&, const Element*) const 381 { 382 notImplemented(); 383 } 384 385 bool RenderThemeJava::paintSearchField(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 386 { 387 return paintWidget(JNI_EXPAND(TEXT_FIELD), o, i, rect); 388 } 389 390 void RenderThemeJava::adjustTextAreaStyle(StyleResolver&, RenderStyle& style, const Element*) const 391 { 392 if (style.paddingTop().isIntrinsicOrAuto()) 393 style.setPaddingTop(Length(1, Fixed)); 394 if (style.paddingBottom().isIntrinsicOrAuto()) 395 style.setPaddingBottom(Length(1, Fixed)); 396 } 397 398 bool RenderThemeJava::paintTextArea(const RenderObject&o, const PaintInfo& i, const FloatRect& r) 399 { 400 return paintTextField(o, i, r); 401 } 402 403 void RenderThemeJava::adjustButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const 404 { 405 if (style.appearance() == PushButtonPart) { 406 // Ignore line-height. 407 style.setLineHeight(RenderStyle::initialLineHeight()); 408 } 409 } 410 411 enum JavaControlSize { 412 JavaRegularControlSize, // The control is sized as regular. 413 JavaSmallControlSize, // The control has a smaller size. 414 JavaMiniControlSize // The control has a smaller size than JavaSmallControlSize. 415 }; 416 417 static float systemFontSizeForControlSize(JavaControlSize controlSize) 418 { 419 static float sizes[] = { 16.0f, 13.0f, 10.0f }; 420 421 return sizes[controlSize]; 422 } 423 424 void RenderThemeJava::updateCachedSystemFontDescription(CSSValueID propId, FontCascadeDescription& fontDescription) const 425 { 426 // This logic owes much to RenderThemeSafari.cpp. 427 static FontCascadeDescription systemFont; 428 static FontCascadeDescription smallSystemFont; 429 static FontCascadeDescription menuFont; 430 static FontCascadeDescription labelFont; 431 static FontCascadeDescription miniControlFont; 432 static FontCascadeDescription smallControlFont; 433 static FontCascadeDescription controlFont; 434 435 FontCascadeDescription* cachedDesc; 436 float fontSize = 0; 437 switch (propId) { 438 case CSSValueSmallCaption: 439 cachedDesc = &smallSystemFont; 440 if (!smallSystemFont.isAbsoluteSize()) 441 fontSize = systemFontSizeForControlSize(JavaSmallControlSize); 442 break; 443 case CSSValueMenu: 444 cachedDesc = &menuFont; 445 if (!menuFont.isAbsoluteSize()) 446 fontSize = systemFontSizeForControlSize(JavaRegularControlSize); 447 break; 448 case CSSValueStatusBar: 449 cachedDesc = &labelFont; 450 if (!labelFont.isAbsoluteSize()) 451 fontSize = 10.0f; 452 break; 453 case CSSValueWebkitMiniControl: 454 cachedDesc = &miniControlFont; 455 if (!miniControlFont.isAbsoluteSize()) 456 fontSize = systemFontSizeForControlSize(JavaMiniControlSize); 457 break; 458 case CSSValueWebkitSmallControl: 459 cachedDesc = &smallControlFont; 460 if (!smallControlFont.isAbsoluteSize()) 461 fontSize = systemFontSizeForControlSize(JavaSmallControlSize); 462 break; 463 case CSSValueWebkitControl: 464 cachedDesc = &controlFont; 465 if (!controlFont.isAbsoluteSize()) 466 fontSize = systemFontSizeForControlSize(JavaRegularControlSize); 467 break; 468 default: 469 cachedDesc = &systemFont; 470 if (!systemFont.isAbsoluteSize()) 471 fontSize = 13.0f; 472 } 473 474 if (fontSize) { 475 cachedDesc->setIsAbsoluteSize(true); 476 // cachedDesc->setGenericFamily(FontCascadeDescription::NoFamily); 477 //cachedDesc->setOneFamily("Lucida Grande"); 478 cachedDesc->setOneFamily("Tahoma"); 479 cachedDesc->setSpecifiedSize(fontSize); 480 cachedDesc->setWeight(normalWeightValue()); 481 cachedDesc->setItalic(normalItalicValue()); 482 } 483 fontDescription = *cachedDesc; 484 } 485 486 void RenderThemeJava::adjustSliderTrackStyle(StyleResolver& selector, RenderStyle& style, const Element* element) const 487 { 488 //utatodo: we need to measure the control in Java theme. 489 RenderTheme::adjustSliderTrackStyle(selector, style, element); 490 } 491 492 bool RenderThemeJava::paintSliderTrack(const RenderObject&object, const PaintInfo& info, const IntRect& rect) 493 { 494 return paintWidget(JNI_EXPAND(SLIDER), object, info, rect); 495 } 496 497 void getSliderThumbSize(jint sliderType, int *width, int *height) 498 { 499 JNIEnv* env = WebCore_GetJavaEnv(); 500 JGClass cls = JLClass(env->FindClass(RENDER_MEDIA_CONTROLS_CLASS_NAME)); 501 ASSERT(cls); 502 503 jmethodID mid = env->GetStaticMethodID(cls, "fwkGetSliderThumbSize", "(I)I"); 504 ASSERT(mid); 505 506 jint size = env->CallStaticIntMethod(cls, mid, sliderType); 507 CheckAndClearException(env); 508 *width = (size >> 16) & 0xFFFF; 509 *height = size & 0xFFFF; 510 } 511 512 //utatodo: we need to measure the control in Java theme, do not make it const 513 const int sliderThumbWidth = 17; 514 const int sliderThumbHeight = 17; 515 516 void RenderThemeJava::adjustSliderThumbSize(RenderStyle& style, const Element*) const 517 { 518 ControlPart part = style.appearance(); 519 #if ENABLE(VIDEO) 520 if (part == SliderThumbVerticalPart || part == SliderThumbHorizontalPart) 521 #endif 522 { 523 style.setWidth(Length(sliderThumbHeight, Fixed)); 524 style.setHeight(Length(sliderThumbWidth, Fixed)); 525 } 526 #if ENABLE(VIDEO) 527 else if (part == MediaSliderThumbPart) { 528 static int timeWidth = 0; 529 static int timeHeight; 530 if (timeWidth == 0) { 531 getSliderThumbSize(JNI_EXPAND_MEDIA(SLIDER_TYPE_TIME), &timeWidth, &timeHeight); 532 } 533 style.setWidth(Length(timeWidth, Fixed)); 534 style.setHeight(Length(timeHeight, Fixed)); 535 } else if (part == MediaVolumeSliderThumbPart) { 536 static int volumeWidth = 0; 537 static int volumeHeight; 538 if (volumeWidth == 0) { 539 getSliderThumbSize(JNI_EXPAND_MEDIA(SLIDER_TYPE_VOLUME), &volumeWidth, &volumeHeight); 540 } 541 style.setWidth(Length(volumeWidth, Fixed)); 542 style.setHeight(Length(volumeHeight, Fixed)); 543 } 544 #endif 545 } 546 547 bool RenderThemeJava::paintSliderThumb(const RenderObject&, const PaintInfo&, const IntRect&) 548 { 549 // We've already painted it in paintSliderTrack(), no need to do anything here. 550 return false; 551 } 552 553 void RenderThemeJava::adjustMenuListStyle(StyleResolver&, RenderStyle& style, const Element*) const 554 { 555 // Add in the padding that we'd like to use. 556 style.setPaddingRight(Length(20.0f + style.paddingRight().value(), Fixed)); 557 style.setPaddingLeft(Length(2.0f + style.paddingLeft().value(), Fixed)); 558 } 559 560 bool RenderThemeJava::paintMenuList(const RenderObject& o, const PaintInfo& i, const FloatRect& rect) 561 { 562 return paintWidget(JNI_EXPAND(MENU_LIST), o, i, rect); 563 } 564 565 void RenderThemeJava::adjustMenuListButtonStyle(StyleResolver& selector, RenderStyle& style, const Element* e) const 566 { 567 style.resetBorderRadius(); 568 adjustMenuListStyle(selector, style, e); 569 } 570 571 bool RenderThemeJava::paintMenuListButtonDecorations(const RenderBox& o, const PaintInfo& i, const FloatRect& r) 572 { 573 IntRect rect(r.x() + r.width(), r.y(), r.height(), r.height()); 574 575 return paintWidget(JNI_EXPAND(MENU_LIST_BUTTON), o, i, rect); 576 } 577 578 bool RenderThemeJava::supportsFocusRing(const RenderStyle& style) const 579 { 580 if (!style.hasAppearance()) 581 return false; 582 583 switch (style.appearance()) { 584 case TextFieldPart: 585 case TextAreaPart: 586 case ButtonPart: 587 case CheckboxPart: 588 case RadioPart: 589 case MenulistPart: 590 return true; 591 default: 592 return RenderTheme::supportsFocusRing(style); 593 } 594 } 595 596 Color RenderThemeJava::getSelectionColor(int index) const 597 { 598 JNIEnv* env = WebCore_GetJavaEnv(); 599 ASSERT(env); 600 601 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "getSelectionColor", "(I)I"); 602 ASSERT(mid); 603 604 // Get from default theme object. 605 jint c = env->CallIntMethod((jobject)getJRenderTheme(nullptr), mid, index); 606 CheckAndClearException(env); 607 608 return Color(c); 609 } 610 611 Color RenderThemeJava::platformActiveSelectionBackgroundColor() const 612 { 613 return getSelectionColor(JNI_EXPAND(BACKGROUND)); 614 } 615 616 Color RenderThemeJava::platformInactiveSelectionBackgroundColor() const 617 { 618 return platformActiveSelectionBackgroundColor(); 619 } 620 621 Color RenderThemeJava::platformActiveSelectionForegroundColor() const 622 { 623 return getSelectionColor(JNI_EXPAND(FOREGROUND)); 624 } 625 626 Color RenderThemeJava::platformInactiveSelectionForegroundColor() const 627 { 628 return platformActiveSelectionForegroundColor(); 629 } 630 631 #if ENABLE(VIDEO) 632 String RenderThemeJava::mediaControlsScript() 633 { 634 StringBuilder scriptBuilder; 635 scriptBuilder.append(mediaControlsLocalizedStringsJavaScript, sizeof(mediaControlsLocalizedStringsJavaScript)); 636 scriptBuilder.append(mediaControlsBaseJavaScript, sizeof(mediaControlsBaseJavaScript)); 637 scriptBuilder.append(mediaControlsGtkJavaScript, sizeof(mediaControlsGtkJavaScript)); 638 return scriptBuilder.toString(); 639 } 640 641 String RenderThemeJava::extraMediaControlsStyleSheet() 642 { 643 return String(mediaControlsGtkUserAgentStyleSheet, sizeof(mediaControlsGtkUserAgentStyleSheet)); 644 } 645 646 String RenderThemeJava::formatMediaControlsCurrentTime(float, float) const 647 { 648 return ""; 649 } 650 651 String RenderThemeJava::formatMediaControlsRemainingTime(float currentTime, float duration) const 652 { 653 return formatMediaControlsTime(currentTime) + "/" + formatMediaControlsTime(duration); 654 } 655 656 /* 657 bool RenderThemeJava::paintMediaFullscreenButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 658 */ 659 660 bool RenderThemeJava::paintMediaPlayButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 661 { 662 auto mediaElement = parentMediaElement(o); 663 if (mediaElement == nullptr) 664 return false; 665 666 // readyState can be NETWORK_EMPTY if preload is NONE 667 jint type = mediaElement->readyState() == HTMLMediaElementEnums::ReadyState::HAVE_NOTHING 668 ? JNI_EXPAND_MEDIA(DISABLED_PLAY_BUTTON) 669 : mediaElement->paused() 670 ? JNI_EXPAND_MEDIA(PLAY_BUTTON) 671 : JNI_EXPAND_MEDIA(PAUSE_BUTTON); 672 return paintMediaControl(type, o, paintInfo, r); 673 } 674 675 bool RenderThemeJava::paintMediaMuteButton(const RenderObject&o, const PaintInfo& paintInfo, const IntRect& r) 676 { 677 auto mediaElement = parentMediaElement(o); 678 if (mediaElement == nullptr) 679 return false; 680 681 jint type = !mediaElement->hasAudio() 682 ? JNI_EXPAND_MEDIA(DISABLED_MUTE_BUTTON) 683 : mediaElement->muted() 684 ? JNI_EXPAND_MEDIA(UNMUTE_BUTTON) 685 : JNI_EXPAND_MEDIA(MUTE_BUTTON); 686 return paintMediaControl(type, o, paintInfo, r); 687 } 688 689 /* 690 bool RenderThemeJava::paintMediaSeekBackButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 691 bool RenderThemeJava::paintMediaSeekForwardButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 692 */ 693 694 bool RenderThemeJava::paintMediaSliderTrack(const RenderObject&o, const PaintInfo& paintInfo, const IntRect& r) 695 { 696 auto mediaElement = parentMediaElement(o); 697 if (mediaElement == nullptr) 698 return false; 699 700 Ref<TimeRanges> timeRanges = mediaElement->buffered(); 701 702 paintInfo.context().platformContext()->rq().freeSpace(4 703 + 4 // number of timeRange pairs 704 + timeRanges->length() * 4 *2 // timeRange pairs 705 + 4 + 4 // duration and currentTime 706 + 4 + 4 + 4 + 4 // x, y, w, h 707 ) 708 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIA_TIMETRACK 709 << (jint)timeRanges->length(); 710 711 //utatodo: need [double] support 712 for (unsigned i = 0; i < timeRanges->length(); i++) { 713 paintInfo.context().platformContext()->rq() 714 << (jfloat)timeRanges->start(i).releaseReturnValue() << (jfloat)timeRanges->end(i).releaseReturnValue(); 715 } 716 717 paintInfo.context().platformContext()->rq() 718 << (jfloat)mediaElement->duration() 719 << (jfloat)mediaElement->currentTime() 720 << (jint)r.x() << (jint)r.y() << (jint)r.width() << (jint)r.height(); 721 return true; 722 } 723 724 bool RenderThemeJava::paintMediaSliderThumb(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 725 { 726 return paintMediaControl(JNI_EXPAND_MEDIA(TIME_SLIDER_THUMB), o, paintInfo, r); 727 } 728 729 bool RenderThemeJava::paintMediaVolumeSliderContainer(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 730 { 731 return paintMediaControl(JNI_EXPAND_MEDIA(VOLUME_CONTAINER), o, paintInfo, r); 732 } 733 734 bool RenderThemeJava::paintMediaVolumeSliderTrack(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 735 { 736 auto mediaElement = parentMediaElement(o); 737 if (mediaElement == nullptr) 738 return false; 739 740 paintInfo.context().platformContext()->rq().freeSpace(28) 741 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIA_VOLUMETRACK 742 << (jfloat)mediaElement->volume() 743 << (jint)(mediaElement->hasAudio() && !mediaElement->muted() ? 0 : 1) // muted 744 << (jint)r.x() << (jint)r.y() << (jint)r.width() << (jint)r.height(); 745 return true; 746 747 } 748 749 bool RenderThemeJava::paintMediaVolumeSliderThumb(const RenderObject& object, const PaintInfo& paintInfo, const IntRect& rect) 750 { 751 return paintMediaControl(JNI_EXPAND_MEDIA(VOLUME_THUMB), object, paintInfo, rect); 752 } 753 754 /* 755 bool RenderThemeJava::paintMediaRewindButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 756 bool RenderThemeJava::paintMediaReturnToRealtimeButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 757 bool RenderThemeJava::paintMediaToggleClosedCaptionsButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 758 */ 759 760 bool RenderThemeJava::paintMediaControlsBackground(const RenderObject&, const PaintInfo&, const IntRect&) 761 { 762 // return paintMediaControl(JNI_EXPAND_MEDIA(BACKGROUND), o, paintInfo, r); 763 return true; 764 } 765 766 bool RenderThemeJava::paintMediaCurrentTime(const RenderObject&, const PaintInfo&, const IntRect&) 767 { 768 // return paintMediaControl(JNI_EXPAND_MEDIA(CURRENT_TIME), o, paintInfo, r); 769 return true; 770 } 771 772 bool RenderThemeJava::paintMediaTimeRemaining(const RenderObject&, const PaintInfo&, const IntRect&) 773 { 774 // return paintMediaControl(JNI_EXPAND_MEDIA(REMAINING_TIME), o, paintInfo, r); 775 return true; 776 } 777 778 bool RenderThemeJava::paintMediaControl(jint type, const RenderObject&, const PaintInfo& paintInfo, const IntRect& r) 779 { 780 paintInfo.context().platformContext()->rq().freeSpace(24) 781 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIACONTROL 782 << type << (jint)r.x() << (jint)r.y() 783 << (jint)r.width() << (jint)r.height(); 784 785 return true; 786 } 787 788 789 #undef JNI_EXPAND_MEDIA 790 791 #endif // ENABLE(VIDEO) 792 793 } 794 795 #undef JNI_EXPAND 796