182 lines
5.2 KiB
C++
182 lines
5.2 KiB
C++
// Copyright 2018 The Chromium Embedded Framework Authors. All rights
|
|
// reserved. Use of this source code is governed by a BSD-style license that
|
|
// can be found in the LICENSE file.
|
|
|
|
#include "CEF/OsrRenderHandlerWinNative.h"
|
|
|
|
#include "include/base/cef_callback.h"
|
|
#include "include/wrapper/cef_closure_task.h"
|
|
#include "include/wrapper/cef_helpers.h"
|
|
#include "CEF/UtilWin.h"
|
|
|
|
OsrRenderHandlerWinNative::OsrRenderHandlerWinNative(
|
|
const OsrRendererSettings& settings,
|
|
HWND hwnd)
|
|
: OsrRenderHandlerWin(settings, hwnd),
|
|
hdc_(nullptr),
|
|
hrc_(nullptr),
|
|
painting_popup_(false),
|
|
view_width_(0),
|
|
view_height_(0),
|
|
spin_x_(0),
|
|
spin_y_(0) {}
|
|
|
|
void OsrRenderHandlerWinNative::Initialize(CefRefPtr<CefBrowser> browser) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
SetBrowser(browser);
|
|
}
|
|
|
|
OsrRenderHandlerWinNative::~OsrRenderHandlerWinNative() {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::SetSpin(float spinX, float spinY) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
spin_x_ = spinX;
|
|
spin_y_ = spinY;
|
|
Invalidate();
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::IncrementSpin(float spinDX, float spinDY) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
spin_x_ -= spinDX;
|
|
spin_y_ -= spinDY;
|
|
Invalidate();
|
|
}
|
|
|
|
bool OsrRenderHandlerWinNative::IsOverPopupWidget(int x, int y) const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
const CefRect& rc = popup_rect_;
|
|
int popup_right = rc.x + rc.width;
|
|
int popup_bottom = rc.y + rc.height;
|
|
return (x >= rc.x) && (x < popup_right) && (y >= rc.y) && (y < popup_bottom);
|
|
}
|
|
|
|
int OsrRenderHandlerWinNative::GetPopupXOffset() const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
return original_popup_rect_.x - popup_rect_.x;
|
|
}
|
|
|
|
int OsrRenderHandlerWinNative::GetPopupYOffset() const {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
return original_popup_rect_.y - popup_rect_.y;
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::OnPopupShow(CefRefPtr<CefBrowser> browser,
|
|
bool show) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
|
|
if (!show) {
|
|
popup_rect_.Set(0, 0, 0, 0);
|
|
original_popup_rect_.Set(0, 0, 0, 0);
|
|
browser->GetHost()->Invalidate(PET_VIEW);
|
|
}
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
|
const CefRect& rect) {
|
|
CEF_REQUIRE_UI_THREAD();
|
|
if (rect.width <= 0 || rect.height <= 0)
|
|
return;
|
|
original_popup_rect_ = rect;
|
|
popup_rect_ = GetPopupRectInWebView(original_popup_rect_);
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::OnPaint(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRenderHandler::PaintElementType type,
|
|
const CefRenderHandler::RectList& dirtyRects,
|
|
const void* buffer,
|
|
int width,
|
|
int height) {
|
|
CEF_REQUIRE_UI_THREAD()
|
|
// stbi_write_png("d:/3.png", width, height, 4, buffer, width * 4);
|
|
|
|
HDC hDc = GetDC(hwnd());
|
|
HDC hMemDC = CreateCompatibleDC(hDc);
|
|
RECT rct;
|
|
GetClientRect(hwnd(), &rct);
|
|
BITMAPINFO bmi = { 0 };
|
|
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
|
bmi.bmiHeader.biWidth = width;
|
|
bmi.bmiHeader.biHeight = height;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biSizeImage = 0;
|
|
|
|
DWORD *pvBits = nullptr;
|
|
HBITMAP hBitmap = CreateDIBSection(hDc, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&pvBits), NULL, 0);
|
|
const int iTotal = width * height * 4;
|
|
// for (int i = 0; i != height; ++i)
|
|
// {
|
|
// for (int j = 0; j != width; ++j)
|
|
// {
|
|
// pvBits[i * width + j] = reinterpret_cast<const DWORD*>(buffer)[(height - i - 1) * width + j];
|
|
// byte *pByte = (byte*)&pvBits[i * width + j];
|
|
// pByte[0] = pByte[0] * pByte[3] / 255;
|
|
// pByte[1] = pByte[1] * pByte[3] / 255;
|
|
// pByte[2] = pByte[2] * pByte[3] / 255;
|
|
// }
|
|
// }
|
|
memcpy(pvBits, buffer, iTotal);
|
|
|
|
GdiFlush();
|
|
SelectObject(hMemDC, hBitmap);
|
|
|
|
POINT ptSrc;
|
|
ptSrc.x = 0;
|
|
ptSrc.y = 0;
|
|
POINT ptDst = ptSrc;
|
|
// ClientToScreen(hwnd(), &ptDst);
|
|
SIZE szSrc;
|
|
szSrc.cx = width;
|
|
szSrc.cy = height;
|
|
BLENDFUNCTION bf;
|
|
bf.BlendOp = AC_SRC_OVER;
|
|
bf.BlendFlags = 0;
|
|
bf.SourceConstantAlpha = 255;
|
|
bf.AlphaFormat = AC_SRC_ALPHA;
|
|
PAINTSTRUCT ps;
|
|
BeginPaint(hwnd(), &ps);
|
|
EndPaint(hwnd(), &ps);
|
|
UpdateLayeredWindow(hwnd(), hDc, &ptDst, &szSrc, hMemDC,
|
|
&ptSrc, 0, &bf, ULW_ALPHA);
|
|
DeleteDC(hMemDC);
|
|
DeleteObject(hBitmap);
|
|
ReleaseDC(hwnd(), hDc);
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::OnAcceleratedPaint(
|
|
CefRefPtr<CefBrowser> browser,
|
|
CefRenderHandler::PaintElementType type,
|
|
const CefRenderHandler::RectList& dirtyRects,
|
|
void* share_handle) {
|
|
// Not used with this implementation.
|
|
NOTREACHED();
|
|
}
|
|
|
|
void OsrRenderHandlerWinNative::Render() {
|
|
|
|
}
|
|
|
|
CefRect OsrRenderHandlerWinNative::GetPopupRectInWebView(const CefRect& original_rect) {
|
|
CefRect rc(original_rect);
|
|
// if x or y are negative, move them to 0.
|
|
if (rc.x < 0)
|
|
rc.x = 0;
|
|
if (rc.y < 0)
|
|
rc.y = 0;
|
|
// if popup goes outside the view, try to reposition origin
|
|
if (rc.x + rc.width > view_width_)
|
|
rc.x = view_width_ - rc.width;
|
|
if (rc.y + rc.height > view_height_)
|
|
rc.y = view_height_ - rc.height;
|
|
// if x or y became negative, move them to 0 again.
|
|
if (rc.x < 0)
|
|
rc.x = 0;
|
|
if (rc.y < 0)
|
|
rc.y = 0;
|
|
return rc;
|
|
}
|