mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-14 15:13:07 +00:00
Ladybird: Add Android View for WebView and paint into it from bindings
This allows our WebViewImplementationNative class to paint into an Android Bitmap class from the onDraw() view event. We also set the viewport geometry from the view since we're setting the Kotlin Bitmap at the same time.
This commit is contained in:
parent
8d05ff1fe7
commit
1d369cb722
Notes:
sideshowbarker
2024-07-16 22:54:10 +09:00
Author: https://github.com/ADKaster
Commit: 1d369cb722
Pull-request: https://github.com/SerenityOS/serenity/pull/20934
Reviewed-by: https://github.com/bugaevc
9 changed files with 162 additions and 31 deletions
|
@ -4,31 +4,78 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibGfx/Bitmap.h>
|
||||
#include <LibGfx/Painter.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
#include <android/bitmap.h>
|
||||
#include <android/log.h>
|
||||
#include <jni.h>
|
||||
|
||||
using namespace WebView;
|
||||
|
||||
namespace {
|
||||
|
||||
Gfx::BitmapFormat to_gfx_bitmap_format(i32 f)
|
||||
{
|
||||
switch (f) {
|
||||
case ANDROID_BITMAP_FORMAT_RGBA_8888:
|
||||
return Gfx::BitmapFormat::BGRA8888;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
class WebViewImplementationNative : public WebView::ViewImplementation {
|
||||
public:
|
||||
virtual Gfx::IntRect viewport_rect() const override { return {}; }
|
||||
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint) const override { return {}; }
|
||||
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint) const override { return {}; }
|
||||
virtual Gfx::IntRect viewport_rect() const override { return m_viewport_rect; }
|
||||
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint p) const override { return p; }
|
||||
virtual Gfx::IntPoint to_widget_position(Gfx::IntPoint p) const override { return p; }
|
||||
virtual void update_zoom() override { }
|
||||
|
||||
void paint_into_bitmap(void* android_bitmap_raw, AndroidBitmapInfo const& info)
|
||||
{
|
||||
// Software bitmaps only for now!
|
||||
VERIFY((info.flags & ANDROID_BITMAP_FLAGS_IS_HARDWARE) == 0);
|
||||
|
||||
auto android_bitmap = MUST(Gfx::Bitmap::create_wrapper(to_gfx_bitmap_format(info.format), { info.width, info.height }, 1, info.stride, android_bitmap_raw));
|
||||
Gfx::Painter painter(android_bitmap);
|
||||
if (auto* bitmap = m_client_state.has_usable_bitmap ? m_client_state.front_bitmap.bitmap.ptr() : m_backup_bitmap.ptr())
|
||||
painter.blit({ 0, 0 }, *bitmap, bitmap->rect());
|
||||
else
|
||||
painter.clear_rect(painter.clip_rect(), Gfx::Color::Magenta);
|
||||
|
||||
// Convert our internal BGRA into RGBA. This will be slowwwwwww
|
||||
// FIXME: Don't do a color format swap here.
|
||||
for (auto y = 0; y < android_bitmap->height(); ++y) {
|
||||
auto* scanline = android_bitmap->scanline(y);
|
||||
for (auto x = 0; x < android_bitmap->width(); ++x) {
|
||||
auto current_pixel = scanline[x];
|
||||
u32 alpha = (current_pixel & 0xFF000000U) >> 24;
|
||||
u32 red = (current_pixel & 0x00FF0000U) >> 16;
|
||||
u32 green = (current_pixel & 0x0000FF00U) >> 8;
|
||||
u32 blue = (current_pixel & 0x000000FFU);
|
||||
scanline[x] = (alpha << 24U) | (blue << 16U) | (green << 8U) | red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_viewport_geometry(int w, int h)
|
||||
{
|
||||
m_viewport_rect = { { 0, 0 }, { w, h } };
|
||||
}
|
||||
|
||||
static jclass global_class_reference;
|
||||
static jfieldID instance_pointer_field;
|
||||
|
||||
private:
|
||||
Gfx::IntRect m_viewport_rect;
|
||||
};
|
||||
jclass WebViewImplementationNative::global_class_reference;
|
||||
jfieldID WebViewImplementationNative::instance_pointer_field;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementationNative_00024Companion_nativeClassInit(JNIEnv* env, jobject /* thiz */)
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_00024Companion_nativeClassInit(JNIEnv* env, jobject /* thiz */)
|
||||
{
|
||||
auto local_class = env->FindClass("org/serenityos/ladybird/WebViewImplementationNative");
|
||||
auto local_class = env->FindClass("org/serenityos/ladybird/WebViewImplementation");
|
||||
if (!local_class)
|
||||
TODO();
|
||||
WebViewImplementationNative::global_class_reference = reinterpret_cast<jclass>(env->NewGlobalRef(local_class));
|
||||
|
@ -40,7 +87,7 @@ Java_org_serenityos_ladybird_WebViewImplementationNative_00024Companion_nativeCl
|
|||
}
|
||||
|
||||
extern "C" JNIEXPORT jlong JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementationNative_nativeObjectInit(JNIEnv*, jobject /* thiz */)
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectInit(JNIEnv*, jobject /* thiz */)
|
||||
{
|
||||
auto instance = reinterpret_cast<jlong>(new WebViewImplementationNative);
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "Ladybird", "New WebViewImplementationNative at %p", reinterpret_cast<void*>(instance));
|
||||
|
@ -48,8 +95,30 @@ Java_org_serenityos_ladybird_WebViewImplementationNative_nativeObjectInit(JNIEnv
|
|||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementationNative_nativeObjectDispose(JNIEnv*, jobject /* thiz */, jlong instance)
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeObjectDispose(JNIEnv*, jobject /* thiz */, jlong instance)
|
||||
{
|
||||
delete reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
__android_log_print(ANDROID_LOG_DEBUG, "Ladybird", "Destroyed WebViewImplementationNative at %p", reinterpret_cast<void*>(instance));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeDrawIntoBitmap(JNIEnv* env, jobject /* thiz */, jlong instance, jobject bitmap)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
|
||||
AndroidBitmapInfo bitmap_info = {};
|
||||
void* pixels = nullptr;
|
||||
AndroidBitmap_getInfo(env, bitmap, &bitmap_info);
|
||||
AndroidBitmap_lockPixels(env, bitmap, &pixels);
|
||||
if (pixels)
|
||||
impl->paint_into_bitmap(pixels, bitmap_info);
|
||||
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_org_serenityos_ladybird_WebViewImplementation_nativeSetViewportGeometry(JNIEnv*, jobject /* thiz */, jlong instance, jint w, jint h)
|
||||
{
|
||||
auto* impl = reinterpret_cast<WebViewImplementationNative*>(instance);
|
||||
impl->set_viewport_geometry(w, h);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue