⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 webview.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    HDC windowDC = ::GetDC(m_viewWindow);    HDC bitmapDC = ::CreateCompatibleDC(windowDC);    ::SelectObject(bitmapDC, m_backingStoreBitmap.get());        // Scroll the bitmap.    RECT scrollRectWin(scrollViewRect);    RECT clipRectWin(clipRect);    ::ScrollDC(bitmapDC, dx, dy, &scrollRectWin, &clipRectWin, updateRegion, 0);    RECT regionBox;    ::GetRgnBox(updateRegion, &regionBox);    // Flush.    GdiFlush();    // Add the dirty region to the backing store's dirty region.    addToDirtyRegion(updateRegion);    if (m_uiDelegatePrivate)        m_uiDelegatePrivate->webViewScrolled(this);    // Update the backing store.    updateBackingStore(frameView, bitmapDC, false);    // Clean up.    ::DeleteDC(bitmapDC);    ::ReleaseDC(m_viewWindow, windowDC);}// This emulates the Mac smarts for painting rects intelligently.  This is very// important for us, since we double buffer based off dirty rects.static void getUpdateRects(HRGN region, const IntRect& dirtyRect, Vector<IntRect>& rects){    ASSERT_ARG(region, region);    const int cRectThreshold = 10;    const float cWastedSpaceThreshold = 0.75f;    rects.clear();    DWORD regionDataSize = GetRegionData(region, sizeof(RGNDATA), NULL);    if (!regionDataSize) {        rects.append(dirtyRect);        return;    }    Vector<unsigned char> buffer(regionDataSize);    RGNDATA* regionData = reinterpret_cast<RGNDATA*>(buffer.data());    GetRegionData(region, regionDataSize, regionData);    if (regionData->rdh.nCount > cRectThreshold) {        rects.append(dirtyRect);        return;    }    double singlePixels = 0.0;    unsigned i;    RECT* rect;    for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)        singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);    double unionPixels = dirtyRect.width() * dirtyRect.height();    double wastedSpace = 1.0 - (singlePixels / unionPixels);    if (wastedSpace <= cWastedSpaceThreshold) {        rects.append(dirtyRect);        return;    }    for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)        rects.append(*rect);}void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty, WindowsToPaint windowsToPaint){    LOCAL_GDI_COUNTER(0, __FUNCTION__);    HDC windowDC = 0;    HDC bitmapDC = dc;    if (!dc) {        windowDC = ::GetDC(m_viewWindow);        bitmapDC = ::CreateCompatibleDC(windowDC);        ::SelectObject(bitmapDC, m_backingStoreBitmap.get());    }    if (m_backingStoreBitmap && (m_backingStoreDirtyRegion || backingStoreCompletelyDirty)) {        // Do a layout first so that everything we render to the backing store is always current.        if (Frame* coreFrame = core(m_mainFrame))            if (FrameView* view = coreFrame->view())                view->layoutIfNeededRecursive();        Vector<IntRect> paintRects;        if (!backingStoreCompletelyDirty) {            RECT regionBox;            ::GetRgnBox(m_backingStoreDirtyRegion.get(), &regionBox);            getUpdateRects(m_backingStoreDirtyRegion.get(), regionBox, paintRects);        } else {            RECT clientRect;            ::GetClientRect(m_viewWindow, &clientRect);            paintRects.append(clientRect);        }        for (unsigned i = 0; i < paintRects.size(); ++i)            paintIntoBackingStore(frameView, bitmapDC, paintRects[i], windowsToPaint);        if (m_uiDelegatePrivate) {            COMPtr<IWebUIDelegatePrivate2> uiDelegatePrivate2(Query, m_uiDelegatePrivate);            if (uiDelegatePrivate2)                uiDelegatePrivate2->webViewPainted(this);        }        m_backingStoreDirtyRegion.clear();    }    if (!dc) {        ::DeleteDC(bitmapDC);        ::ReleaseDC(m_viewWindow, windowDC);    }    GdiFlush();}void WebView::paint(HDC dc, LPARAM options){    LOCAL_GDI_COUNTER(0, __FUNCTION__);    Frame* coreFrame = core(m_mainFrame);    if (!coreFrame)        return;    FrameView* frameView = coreFrame->view();    m_paintCount++;    RECT rcPaint;    HDC hdc;    OwnPtr<HRGN> region;    int regionType = NULLREGION;    PAINTSTRUCT ps;    WindowsToPaint windowsToPaint;    if (!dc) {        region.set(CreateRectRgn(0,0,0,0));        regionType = GetUpdateRgn(m_viewWindow, region.get(), false);        hdc = BeginPaint(m_viewWindow, &ps);        rcPaint = ps.rcPaint;        // We're painting to the screen, and our child windows can handle        // painting themselves to the screen.        windowsToPaint = PaintWebViewOnly;    } else {        hdc = dc;        ::GetClientRect(m_viewWindow, &rcPaint);        if (options & PRF_ERASEBKGND)            ::FillRect(hdc, &rcPaint, (HBRUSH)GetStockObject(WHITE_BRUSH));        // Since we aren't painting to the screen, we want to paint all our        // children into the HDC.        windowsToPaint = PaintWebViewAndChildren;    }    HDC bitmapDC = ::CreateCompatibleDC(hdc);    bool backingStoreCompletelyDirty = ensureBackingStore();    ::SelectObject(bitmapDC, m_backingStoreBitmap.get());    // Update our backing store if needed.    updateBackingStore(frameView, bitmapDC, backingStoreCompletelyDirty, windowsToPaint);    // Now we blit the updated backing store    IntRect windowDirtyRect = rcPaint;        // Apply the same heuristic for this update region too.    Vector<IntRect> blitRects;    if (region && regionType == COMPLEXREGION)        getUpdateRects(region.get(), windowDirtyRect, blitRects);    else        blitRects.append(windowDirtyRect);    for (unsigned i = 0; i < blitRects.size(); ++i)        paintIntoWindow(bitmapDC, hdc, blitRects[i]);    ::DeleteDC(bitmapDC);    // Paint the gripper.    COMPtr<IWebUIDelegate> ui;    if (SUCCEEDED(uiDelegate(&ui))) {        COMPtr<IWebUIDelegatePrivate> uiPrivate;        if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&uiPrivate))) {            RECT r;            if (SUCCEEDED(uiPrivate->webViewResizerRect(this, &r))) {                LOCAL_GDI_COUNTER(2, __FUNCTION__" webViewDrawResizer delegate call");                uiPrivate->webViewDrawResizer(this, hdc, (frameView->containsScrollbarsAvoidingResizer() ? true : false), &r);            }        }    }    if (!dc)        EndPaint(m_viewWindow, &ps);    m_paintCount--;    if (active())        cancelDeleteBackingStoreSoon();    else        deleteBackingStoreSoon();}void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const IntRect& dirtyRect, WindowsToPaint windowsToPaint){    LOCAL_GDI_COUNTER(0, __FUNCTION__);    RECT rect = dirtyRect;#if FLASH_BACKING_STORE_REDRAW    HDC dc = ::GetDC(m_viewWindow);    OwnPtr<HBRUSH> yellowBrush = CreateSolidBrush(RGB(255, 255, 0));    FillRect(dc, &rect, yellowBrush.get());    GdiFlush();    Sleep(50);    paintIntoWindow(bitmapDC, dc, dirtyRect);    ::ReleaseDC(m_viewWindow, dc);#endif    GraphicsContext gc(bitmapDC, m_transparent);    gc.setShouldIncludeChildWindows(windowsToPaint == PaintWebViewAndChildren);    gc.save();    if (m_transparent)        gc.clearRect(dirtyRect);    else        FillRect(bitmapDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));    if (frameView && frameView->frame() && frameView->frame()->contentRenderer()) {        gc.clip(dirtyRect);        frameView->paint(&gc, dirtyRect);    }    gc.restore();}void WebView::paintIntoWindow(HDC bitmapDC, HDC windowDC, const IntRect& dirtyRect){    LOCAL_GDI_COUNTER(0, __FUNCTION__);#if FLASH_WINDOW_REDRAW    OwnPtr<HBRUSH> greenBrush = CreateSolidBrush(RGB(0, 255, 0));    RECT rect = dirtyRect;    FillRect(windowDC, &rect, greenBrush.get());    GdiFlush();    Sleep(50);#endif    // Blit the dirty rect from the backing store into the same position    // in the destination DC.    BitBlt(windowDC, dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), bitmapDC,           dirtyRect.x(), dirtyRect.y(), SRCCOPY);}void WebView::frameRect(RECT* rect){    ::GetWindowRect(m_viewWindow, rect);}void WebView::closeWindowSoon(){    m_closeWindowTimer.startOneShot(0);    AddRef();}void WebView::closeWindowTimerFired(WebCore::Timer<WebView>*){    closeWindow();    Release();}void WebView::closeWindow(){    if (m_hasSpellCheckerDocumentTag) {        if (m_editingDelegate)            m_editingDelegate->closeSpellDocument(this);        m_hasSpellCheckerDocumentTag = false;    }    COMPtr<IWebUIDelegate> ui;    if (SUCCEEDED(uiDelegate(&ui)))        ui->webViewClose(this);}bool WebView::canHandleRequest(const WebCore::ResourceRequest& request){    // On the mac there's an about url protocol implementation but CFNetwork doesn't have that.    if (equalIgnoringCase(String(request.url().protocol()), "about"))        return true;#if USE(CFNETWORK)    if (CFURLProtocolCanHandleRequest(request.cfURLRequest()))        return true;    // FIXME: Mac WebKit calls _representationExistsForURLScheme here    return false;#else    return true;#endif}String WebView::standardUserAgentWithApplicationName(const String& applicationName){    return String::format("Mozilla/5.0 (Windows; U; %s; %s) AppleWebKit/%s (KHTML, like Gecko)%s%s", osVersion().latin1().data(), defaultLanguage().latin1().data(), webKitVersion().latin1().data(), (applicationName.length() ? " " : ""), applicationName.latin1().data());}Page* WebView::page(){    return m_page;}bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam){    static const int contextMenuMargin = 1;    // Translate the screen coordinates into window coordinates    POINT coords = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };    if (coords.x == -1 || coords.y == -1) {        FrameView* view = m_page->mainFrame()->view();        if (!view)            return false;        int rightAligned = ::GetSystemMetrics(SM_MENUDROPALIGNMENT);        IntPoint location;        // The context menu event was generated from the keyboard, so show the context menu by the current selection.        Position start = m_page->mainFrame()->selection()->selection().start();        Position end = m_page->mainFrame()->selection()->selection().end();        if (!start.node() || !end.node())            location = IntPoint(rightAligned ? view->contentsWidth() - contextMenuMargin : contextMenuMargin, contextMenuMargin);        else {            RenderObject* renderer = start.node()->renderer();            if (!renderer)                return false;            // Calculate the rect of the first line of the selection (cribbed from -[WebCoreFrameBridge firstRectForDOMRange:],            // now Frame::firstRectForRange(), which perhaps this should call).            int extraWidthToEndOfLine = 0;            InlineBox* startInlineBox;            int startCaretOffset;            start.getInlineBoxAndOffset(DOWNSTREAM, startInlineBox, startCaretOffset);            IntRect startCaretRect = renderer->localCaretRect(startInlineBox, startCaretOffset, &extraWidthToEndOfLine);            if (startCaretRect != IntRect())                startCaretRect = renderer->localToAbsoluteQuad(FloatRect(startCaretRect)).enclosingBoundingBox();            InlineBox* endInlineBox;            int endCaretOffset;            end.getInlineBoxAndOffset(UPSTREAM, endInlineBox, endCaretOffset);            IntRect endCaretRect = renderer->localCaretRect(endInlineBox, endCaretOffset);            if (endCaretRect != IntRect())                endCaretRect = renderer->localToAbsoluteQuad(FloatRect(endCaretRect)).enclosingBoundingBox();            IntRect firstRect;            if (startCaretRect.y() == endCaretRect.y())                firstRect = IntRect(min(startCaretRect.x(), endCaretRect.x()), startCaretRect.y(), abs(endCaretRect.x() - startCaretRect.x()), max(startCaretRect.height(), endCaretRect.height()));            else                firstRect = IntRect(startCaretRect.x(), startCaretRect.y(), startCaretRect.width() + extraWidthToEndOfLine, startCaretRect.height());            location = IntPoint(rightAligned ? firstRect.right() : firstRect.x(), firstRect.bottom());        }        location = view->contentsToWindow(location);        // FIXME: The IntSize(0, -1) is a hack to get the hit-testing to result in the selected element.        // Ideally we'd have the position of a context menu event be separate from its target node.        coords = location + IntSize(0, -1);    } else {        if (!::ScreenToClient(m_viewWindow, &coords))            return false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -