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) { 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 RenderProgress& renderProgress = downcast<RenderProgress>(object); 204 205 extParams.grow(sizeof(jint) + 3*sizeof(jfloat)); 206 jbyte *data = extParams.data(); 207 auto isDeterminate = jint(renderProgress.isDeterminate() ? 1 : 0); 208 memcpy(data, &isDeterminate, sizeof(isDeterminate)); 209 data += sizeof(jint); 210 211 auto position = jfloat(renderProgress.position()); 212 memcpy(data, &position, sizeof(position)); 213 data += sizeof(jfloat); 214 215 auto animationProgress = jfloat(renderProgress.animationProgress()); 216 memcpy(data, &animationProgress, sizeof(animationProgress)); 217 data += sizeof(jfloat); 218 219 auto animationStartTime = jfloat(renderProgress.animationStartTime()); 220 memcpy(data, &animationStartTime, sizeof(animationStartTime)); 221 #endif 222 #if ENABLE(METER_ELEMENT) 223 } else if (JNI_EXPAND(METER) == widgetIndex) { 224 jfloat value = 0; 225 jint region = 0; 226 if (object.isMeter()) { 227 HTMLMeterElement* meter = static_cast<HTMLMeterElement*>(object.node()); 228 value = meter->valueRatio(); 229 region = meter->gaugeRegion(); 230 #if ENABLE(PROGRESS_ELEMENT) 231 } else if (object.isProgress()) { 232 RenderProgress& renderProgress = downcast<RenderProgress>(object); 233 value = jfloat(renderProgress.position()); 234 #endif 235 } 236 237 extParams.grow(sizeof(jfloat) + sizeof(jint)); 238 jbyte *data = extParams.data(); 239 memcpy(data, &value, sizeof(value)); 240 data += sizeof(jfloat); 241 242 memcpy(data, ®ion, sizeof(region)); 243 #endif 244 } 245 246 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "createWidget", 247 "(JIIIIILjava/nio/ByteBuffer;)Lcom/sun/webkit/graphics/Ref;"); 248 ASSERT(mid); 249 250 RefPtr<RQRef> widgetRef = RQRef::create( 251 env->CallObjectMethod(jobject(*jRenderTheme), mid, 252 ptr_to_jlong(&object), 253 (jint)widgetIndex, 254 (jint)state, 255 (jint)rect.width(), (jint)rect.height(), 256 (jint)bgColor, 257 (jobject)JLObject(extParams.isEmpty() 258 ? nullptr 259 : env->NewDirectByteBuffer( 260 extParams.data(), 261 extParams.size()))) 262 ); 263 if (!widgetRef.get()) { 264 //switch to WebKit default render 265 return true; 266 } 267 CheckAndClearException(env); 268 269 // widgetRef will go into rq's inner refs vector. 270 paintInfo.context().platformContext()->rq().freeSpace(20) 271 << (jint)com_sun_webkit_graphics_GraphicsDecoder_DRAWWIDGET 272 << (jint)*jRenderTheme 273 << widgetRef 274 << (jint)rect.x() << (jint)rect.y(); 275 276 return false; 277 } 278 279 #if ENABLE(PROGRESS_ELEMENT) 280 void RenderThemeJava::adjustProgressBarStyle(StyleResolver&, RenderStyle& style, const Element*) const 281 { 282 style.setBoxShadow(nullptr); 283 } 284 285 //utatodo: ask Java theme 286 // These values have been copied from RenderThemeChromiumSkia.cpp 287 static const int progressActivityBlocks = 5; 288 static const int progressAnimationFrames = 10; 289 static const double progressAnimationInterval = 0.125; 290 double RenderThemeJava::animationRepeatIntervalForProgressBar(RenderProgress&) const 291 { 292 return progressAnimationInterval; 293 } 294 295 double RenderThemeJava::animationDurationForProgressBar(RenderProgress&) const 296 { 297 return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth; 298 } 299 300 bool RenderThemeJava::paintProgressBar(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 301 { 302 return paintWidget(JNI_EXPAND(PROGRESS_BAR), o, i, rect); 303 } 304 #endif 305 306 #if ENABLE(METER_ELEMENT) 307 bool RenderThemeJava::supportsMeter(ControlPart part) const 308 { 309 #if ENABLE(PROGRESS_ELEMENT) 310 if (part == ProgressBarPart) { 311 return true; 312 } 313 #endif 314 return (part == MeterPart); 315 } 316 317 bool RenderThemeJava::paintMeter(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 318 { 319 return paintWidget(JNI_EXPAND(METER), o, i, rect); 320 } 321 #endif 322 323 void RenderThemeJava::setCheckboxSize(RenderStyle& style) const 324 { 325 setRadioSize(style); 326 } 327 328 bool RenderThemeJava::paintCheckbox(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 329 { 330 return paintWidget(JNI_EXPAND(CHECK_BOX), o, i, rect); 331 } 332 333 void RenderThemeJava::setRadioSize(RenderStyle& style) const 334 { 335 // If the width and height are both specified, then we have nothing to do. 336 if ((!style.width().isIntrinsicOrAuto() && !style.height().isAuto())) { 337 return; 338 } 339 340 JNIEnv* env = WebCore_GetJavaEnv(); 341 342 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "getRadioButtonSize", "()I"); 343 ASSERT(mid); 344 345 // Get from default theme object. 346 int radioRadius = env->CallIntMethod((jobject)getJRenderTheme(nullptr), mid); 347 CheckAndClearException(env); 348 349 if (style.width().isIntrinsicOrAuto()) { 350 style.setWidth(Length(radioRadius, Fixed)); 351 } 352 353 if (style.height().isAuto()) { 354 style.setHeight(Length(radioRadius, Fixed)); 355 } 356 } 357 358 bool RenderThemeJava::paintRadio(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 359 { 360 return paintWidget(JNI_EXPAND(RADIO_BUTTON), o, i, rect); 361 } 362 363 bool RenderThemeJava::paintButton(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 364 { 365 return paintWidget(JNI_EXPAND(BUTTON), o, i, rect); 366 } 367 368 void RenderThemeJava::adjustTextFieldStyle(StyleResolver&, RenderStyle&, const Element*) const 369 { 370 notImplemented(); 371 } 372 373 bool RenderThemeJava::paintTextField(const RenderObject&o, const PaintInfo& i, const FloatRect& rect) 374 { 375 return paintWidget(JNI_EXPAND(TEXT_FIELD), o, i, rect); 376 } 377 378 void RenderThemeJava::adjustSearchFieldStyle(StyleResolver&, RenderStyle&, const Element*) const 379 { 380 notImplemented(); 381 } 382 383 bool RenderThemeJava::paintSearchField(const RenderObject&o, const PaintInfo& i, const IntRect& rect) 384 { 385 return paintWidget(JNI_EXPAND(TEXT_FIELD), o, i, rect); 386 } 387 388 void RenderThemeJava::adjustTextAreaStyle(StyleResolver&, RenderStyle& style, const Element*) const 389 { 390 if (style.paddingTop().isIntrinsicOrAuto()) 391 style.setPaddingTop(Length(1, Fixed)); 392 if (style.paddingBottom().isIntrinsicOrAuto()) 393 style.setPaddingBottom(Length(1, Fixed)); 394 } 395 396 bool RenderThemeJava::paintTextArea(const RenderObject&o, const PaintInfo& i, const FloatRect& r) 397 { 398 return paintTextField(o, i, r); 399 } 400 401 void RenderThemeJava::adjustButtonStyle(StyleResolver&, RenderStyle& style, const Element*) const 402 { 403 if (style.appearance() == PushButtonPart) { 404 // Ignore line-height. 405 style.setLineHeight(RenderStyle::initialLineHeight()); 406 } 407 } 408 409 enum JavaControlSize { 410 JavaRegularControlSize, // The control is sized as regular. 411 JavaSmallControlSize, // The control has a smaller size. 412 JavaMiniControlSize // The control has a smaller size than JavaSmallControlSize. 413 }; 414 415 static float systemFontSizeForControlSize(JavaControlSize controlSize) 416 { 417 static float sizes[] = { 16.0f, 13.0f, 10.0f }; 418 419 return sizes[controlSize]; 420 } 421 422 void RenderThemeJava::updateCachedSystemFontDescription(CSSValueID propId, FontCascadeDescription& fontDescription) const 423 { 424 // This logic owes much to RenderThemeSafari.cpp. 425 static FontCascadeDescription systemFont; 426 static FontCascadeDescription smallSystemFont; 427 static FontCascadeDescription menuFont; 428 static FontCascadeDescription labelFont; 429 static FontCascadeDescription miniControlFont; 430 static FontCascadeDescription smallControlFont; 431 static FontCascadeDescription controlFont; 432 433 FontCascadeDescription* cachedDesc; 434 float fontSize = 0; 435 switch (propId) { 436 case CSSValueSmallCaption: 437 cachedDesc = &smallSystemFont; 438 if (!smallSystemFont.isAbsoluteSize()) 439 fontSize = systemFontSizeForControlSize(JavaSmallControlSize); 440 break; 441 case CSSValueMenu: 442 cachedDesc = &menuFont; 443 if (!menuFont.isAbsoluteSize()) 444 fontSize = systemFontSizeForControlSize(JavaRegularControlSize); 445 break; 446 case CSSValueStatusBar: 447 cachedDesc = &labelFont; 448 if (!labelFont.isAbsoluteSize()) 449 fontSize = 10.0f; 450 break; 451 case CSSValueWebkitMiniControl: 452 cachedDesc = &miniControlFont; 453 if (!miniControlFont.isAbsoluteSize()) 454 fontSize = systemFontSizeForControlSize(JavaMiniControlSize); 455 break; 456 case CSSValueWebkitSmallControl: 457 cachedDesc = &smallControlFont; 458 if (!smallControlFont.isAbsoluteSize()) 459 fontSize = systemFontSizeForControlSize(JavaSmallControlSize); 460 break; 461 case CSSValueWebkitControl: 462 cachedDesc = &controlFont; 463 if (!controlFont.isAbsoluteSize()) 464 fontSize = systemFontSizeForControlSize(JavaRegularControlSize); 465 break; 466 default: 467 cachedDesc = &systemFont; 468 if (!systemFont.isAbsoluteSize()) 469 fontSize = 13.0f; 470 } 471 472 if (fontSize) { 473 cachedDesc->setIsAbsoluteSize(true); 474 // cachedDesc->setGenericFamily(FontCascadeDescription::NoFamily); 475 //cachedDesc->setOneFamily("Lucida Grande"); 476 cachedDesc->setOneFamily("Tahoma"); 477 cachedDesc->setSpecifiedSize(fontSize); 478 cachedDesc->setWeight(normalWeightValue()); 479 cachedDesc->setItalic(normalItalicValue()); 480 } 481 fontDescription = *cachedDesc; 482 } 483 484 void RenderThemeJava::adjustSliderTrackStyle(StyleResolver& selector, RenderStyle& style, const Element* element) const 485 { 486 //utatodo: we need to measure the control in Java theme. 487 RenderTheme::adjustSliderTrackStyle(selector, style, element); 488 } 489 490 bool RenderThemeJava::paintSliderTrack(const RenderObject&object, const PaintInfo& info, const IntRect& rect) 491 { 492 return paintWidget(JNI_EXPAND(SLIDER), object, info, rect); 493 } 494 495 void getSliderThumbSize(jint sliderType, int *width, int *height) 496 { 497 JNIEnv* env = WebCore_GetJavaEnv(); 498 JGClass cls = JLClass(env->FindClass(RENDER_MEDIA_CONTROLS_CLASS_NAME)); 499 ASSERT(cls); 500 501 jmethodID mid = env->GetStaticMethodID(cls, "fwkGetSliderThumbSize", "(I)I"); 502 ASSERT(mid); 503 504 jint size = env->CallStaticIntMethod(cls, mid, sliderType); 505 CheckAndClearException(env); 506 *width = (size >> 16) & 0xFFFF; 507 *height = size & 0xFFFF; 508 } 509 510 //utatodo: we need to measure the control in Java theme, do not make it const 511 const int sliderThumbWidth = 17; 512 const int sliderThumbHeight = 17; 513 514 void RenderThemeJava::adjustSliderThumbSize(RenderStyle& style, const Element*) const 515 { 516 ControlPart part = style.appearance(); 517 #if ENABLE(VIDEO) 518 if (part == SliderThumbVerticalPart || part == SliderThumbHorizontalPart) 519 #endif 520 { 521 style.setWidth(Length(sliderThumbHeight, Fixed)); 522 style.setHeight(Length(sliderThumbWidth, Fixed)); 523 } 524 #if ENABLE(VIDEO) 525 else if (part == MediaSliderThumbPart) { 526 static int timeWidth = 0; 527 static int timeHeight; 528 if (timeWidth == 0) { 529 getSliderThumbSize(JNI_EXPAND_MEDIA(SLIDER_TYPE_TIME), &timeWidth, &timeHeight); 530 } 531 style.setWidth(Length(timeWidth, Fixed)); 532 style.setHeight(Length(timeHeight, Fixed)); 533 } else if (part == MediaVolumeSliderThumbPart) { 534 static int volumeWidth = 0; 535 static int volumeHeight; 536 if (volumeWidth == 0) { 537 getSliderThumbSize(JNI_EXPAND_MEDIA(SLIDER_TYPE_VOLUME), &volumeWidth, &volumeHeight); 538 } 539 style.setWidth(Length(volumeWidth, Fixed)); 540 style.setHeight(Length(volumeHeight, Fixed)); 541 } 542 #endif 543 } 544 545 bool RenderThemeJava::paintSliderThumb(const RenderObject&, const PaintInfo&, const IntRect&) 546 { 547 // We've already painted it in paintSliderTrack(), no need to do anything here. 548 return false; 549 } 550 551 void RenderThemeJava::adjustMenuListStyle(StyleResolver&, RenderStyle& style, const Element*) const 552 { 553 // Add in the padding that we'd like to use. 554 style.setPaddingRight(Length(20.0f + style.paddingRight().value(), Fixed)); 555 style.setPaddingLeft(Length(2.0f + style.paddingLeft().value(), Fixed)); 556 } 557 558 bool RenderThemeJava::paintMenuList(const RenderObject& o, const PaintInfo& i, const FloatRect& rect) 559 { 560 return paintWidget(JNI_EXPAND(MENU_LIST), o, i, rect); 561 } 562 563 void RenderThemeJava::adjustMenuListButtonStyle(StyleResolver& selector, RenderStyle& style, const Element* e) const 564 { 565 style.resetBorderRadius(); 566 adjustMenuListStyle(selector, style, e); 567 } 568 569 bool RenderThemeJava::paintMenuListButtonDecorations(const RenderBox& o, const PaintInfo& i, const FloatRect& r) 570 { 571 IntRect rect(r.x() + r.width(), r.y(), r.height(), r.height()); 572 573 return paintWidget(JNI_EXPAND(MENU_LIST_BUTTON), o, i, rect); 574 } 575 576 bool RenderThemeJava::supportsFocusRing(const RenderStyle& style) const 577 { 578 if (!style.hasAppearance()) 579 return false; 580 581 switch (style.appearance()) { 582 case TextFieldPart: 583 case TextAreaPart: 584 case ButtonPart: 585 case CheckboxPart: 586 case RadioPart: 587 case MenulistPart: 588 return true; 589 default: 590 return RenderTheme::supportsFocusRing(style); 591 } 592 } 593 594 Color RenderThemeJava::getSelectionColor(int index) const 595 { 596 JNIEnv* env = WebCore_GetJavaEnv(); 597 ASSERT(env); 598 599 static jmethodID mid = env->GetMethodID(getJRenderThemeClass(), "getSelectionColor", "(I)I"); 600 ASSERT(mid); 601 602 // Get from default theme object. 603 jint c = env->CallIntMethod((jobject)getJRenderTheme(nullptr), mid, index); 604 CheckAndClearException(env); 605 606 return Color(c); 607 } 608 609 Color RenderThemeJava::platformActiveSelectionBackgroundColor() const 610 { 611 return getSelectionColor(JNI_EXPAND(BACKGROUND)); 612 } 613 614 Color RenderThemeJava::platformInactiveSelectionBackgroundColor() const 615 { 616 return platformActiveSelectionBackgroundColor(); 617 } 618 619 Color RenderThemeJava::platformActiveSelectionForegroundColor() const 620 { 621 return getSelectionColor(JNI_EXPAND(FOREGROUND)); 622 } 623 624 Color RenderThemeJava::platformInactiveSelectionForegroundColor() const 625 { 626 return platformActiveSelectionForegroundColor(); 627 } 628 629 #if ENABLE(VIDEO) 630 String RenderThemeJava::mediaControlsScript() 631 { 632 StringBuilder scriptBuilder; 633 scriptBuilder.append(mediaControlsLocalizedStringsJavaScript, sizeof(mediaControlsLocalizedStringsJavaScript)); 634 scriptBuilder.append(mediaControlsBaseJavaScript, sizeof(mediaControlsBaseJavaScript)); 635 scriptBuilder.append(mediaControlsGtkJavaScript, sizeof(mediaControlsGtkJavaScript)); 636 return scriptBuilder.toString(); 637 } 638 639 String RenderThemeJava::extraMediaControlsStyleSheet() 640 { 641 return String(mediaControlsGtkUserAgentStyleSheet, sizeof(mediaControlsGtkUserAgentStyleSheet)); 642 } 643 644 String RenderThemeJava::formatMediaControlsCurrentTime(float, float) const 645 { 646 return ""; 647 } 648 649 String RenderThemeJava::formatMediaControlsRemainingTime(float currentTime, float duration) const 650 { 651 return formatMediaControlsTime(currentTime) + "/" + formatMediaControlsTime(duration); 652 } 653 654 /* 655 bool RenderThemeJava::paintMediaFullscreenButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 656 */ 657 658 bool RenderThemeJava::paintMediaPlayButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 659 { 660 auto mediaElement = parentMediaElement(o); 661 if (mediaElement == nullptr) 662 return false; 663 664 // readyState can be NETWORK_EMPTY if preload is NONE 665 jint type = mediaElement->readyState() == HTMLMediaElementEnums::ReadyState::HAVE_NOTHING 666 ? JNI_EXPAND_MEDIA(DISABLED_PLAY_BUTTON) 667 : mediaElement->paused() 668 ? JNI_EXPAND_MEDIA(PLAY_BUTTON) 669 : JNI_EXPAND_MEDIA(PAUSE_BUTTON); 670 return paintMediaControl(type, o, paintInfo, r); 671 } 672 673 bool RenderThemeJava::paintMediaMuteButton(const RenderObject&o, const PaintInfo& paintInfo, const IntRect& r) 674 { 675 auto mediaElement = parentMediaElement(o); 676 if (mediaElement == nullptr) 677 return false; 678 679 jint type = !mediaElement->hasAudio() 680 ? JNI_EXPAND_MEDIA(DISABLED_MUTE_BUTTON) 681 : mediaElement->muted() 682 ? JNI_EXPAND_MEDIA(UNMUTE_BUTTON) 683 : JNI_EXPAND_MEDIA(MUTE_BUTTON); 684 return paintMediaControl(type, o, paintInfo, r); 685 } 686 687 /* 688 bool RenderThemeJava::paintMediaSeekBackButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 689 bool RenderThemeJava::paintMediaSeekForwardButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 690 */ 691 692 bool RenderThemeJava::paintMediaSliderTrack(const RenderObject&o, const PaintInfo& paintInfo, const IntRect& r) 693 { 694 auto mediaElement = parentMediaElement(o); 695 if (mediaElement == nullptr) 696 return false; 697 698 Ref<TimeRanges> timeRanges = mediaElement->buffered(); 699 700 paintInfo.context().platformContext()->rq().freeSpace(4 701 + 4 // number of timeRange pairs 702 + timeRanges->length() * 4 *2 // timeRange pairs 703 + 4 + 4 // duration and currentTime 704 + 4 + 4 + 4 + 4 // x, y, w, h 705 ) 706 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIA_TIMETRACK 707 << (jint)timeRanges->length(); 708 709 //utatodo: need [double] support 710 for (unsigned i = 0; i < timeRanges->length(); i++) { 711 paintInfo.context().platformContext()->rq() 712 << (jfloat)timeRanges->start(i).releaseReturnValue() << (jfloat)timeRanges->end(i).releaseReturnValue(); 713 } 714 715 paintInfo.context().platformContext()->rq() 716 << (jfloat)mediaElement->duration() 717 << (jfloat)mediaElement->currentTime() 718 << (jint)r.x() << (jint)r.y() << (jint)r.width() << (jint)r.height(); 719 return true; 720 } 721 722 bool RenderThemeJava::paintMediaSliderThumb(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 723 { 724 return paintMediaControl(JNI_EXPAND_MEDIA(TIME_SLIDER_THUMB), o, paintInfo, r); 725 } 726 727 bool RenderThemeJava::paintMediaVolumeSliderContainer(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 728 { 729 return paintMediaControl(JNI_EXPAND_MEDIA(VOLUME_CONTAINER), o, paintInfo, r); 730 } 731 732 bool RenderThemeJava::paintMediaVolumeSliderTrack(const RenderObject& o, const PaintInfo& paintInfo, const IntRect& r) 733 { 734 auto mediaElement = parentMediaElement(o); 735 if (mediaElement == nullptr) 736 return false; 737 738 paintInfo.context().platformContext()->rq().freeSpace(28) 739 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIA_VOLUMETRACK 740 << (jfloat)mediaElement->volume() 741 << (jint)(mediaElement->hasAudio() && !mediaElement->muted() ? 0 : 1) // muted 742 << (jint)r.x() << (jint)r.y() << (jint)r.width() << (jint)r.height(); 743 return true; 744 745 } 746 747 bool RenderThemeJava::paintMediaVolumeSliderThumb(const RenderObject& object, const PaintInfo& paintInfo, const IntRect& rect) 748 { 749 return paintMediaControl(JNI_EXPAND_MEDIA(VOLUME_THUMB), object, paintInfo, rect); 750 } 751 752 /* 753 bool RenderThemeJava::paintMediaRewindButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 754 bool RenderThemeJava::paintMediaReturnToRealtimeButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 755 bool RenderThemeJava::paintMediaToggleClosedCaptionsButton(const RenderObject& o, const PaintInfo& paintInfo, const IntRect &r); 756 */ 757 758 bool RenderThemeJava::paintMediaControlsBackground(const RenderObject&, const PaintInfo&, const IntRect&) 759 { 760 // return paintMediaControl(JNI_EXPAND_MEDIA(BACKGROUND), o, paintInfo, r); 761 return true; 762 } 763 764 bool RenderThemeJava::paintMediaCurrentTime(const RenderObject&, const PaintInfo&, const IntRect&) 765 { 766 // return paintMediaControl(JNI_EXPAND_MEDIA(CURRENT_TIME), o, paintInfo, r); 767 return true; 768 } 769 770 bool RenderThemeJava::paintMediaTimeRemaining(const RenderObject&, const PaintInfo&, const IntRect&) 771 { 772 // return paintMediaControl(JNI_EXPAND_MEDIA(REMAINING_TIME), o, paintInfo, r); 773 return true; 774 } 775 776 bool RenderThemeJava::paintMediaControl(jint type, const RenderObject&, const PaintInfo& paintInfo, const IntRect& r) 777 { 778 paintInfo.context().platformContext()->rq().freeSpace(24) 779 << (jint)com_sun_webkit_graphics_GraphicsDecoder_RENDERMEDIACONTROL 780 << type << (jint)r.x() << (jint)r.y() 781 << (jint)r.width() << (jint)r.height(); 782 783 return true; 784 } 785 786 787 #undef JNI_EXPAND_MEDIA 788 789 #endif // ENABLE(VIDEO) 790 791 } 792 793 #undef JNI_EXPAND 794