<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <config_features.h>

#include <vcl/window.hxx>
#include <vcl/dialog.hxx>
#include <vcl/virdev.hxx>
#include <vcl/cursor.hxx>
#include <vcl/settings.hxx>

#include <officecfg/Office/Common.hxx>
#include <sal/types.h>

#include <window.h>
#include <salgdi.hxx>
#include <salframe.hxx>
#include <svdata.hxx>

#define IMPL_PAINT_PAINT            ((sal_uInt16)0x0001)
#define IMPL_PAINT_PAINTALL         ((sal_uInt16)0x0002)
#define IMPL_PAINT_PAINTALLCHILDREN   ((sal_uInt16)0x0004)
#define IMPL_PAINT_PAINTCHILDREN      ((sal_uInt16)0x0008)
#define IMPL_PAINT_ERASE            ((sal_uInt16)0x0010)
#define IMPL_PAINT_CHECKRTL         ((sal_uInt16)0x0020)

class PaintHelper
{
private:
    VclPtr<vcl::Window> m_pWindow;
    vcl::Region* m_pChildRegion;
    Rectangle m_aSelectionRect;
    Rectangle m_aPaintRect;
    vcl::Region m_aPaintRegion;
    sal_uInt16 m_nPaintFlags;
    bool m_bPop;
    bool m_bRestoreCursor;
public:
    PaintHelper(vcl::Window* pWindow, sal_uInt16 nPaintFlags);
    void SetPop()
    {
        m_bPop = true;
    }
    void SetPaintRect(const Rectangle& rRect)
    {
        m_aPaintRect = rRect;
    }
    void SetSelectionRect(const Rectangle& rRect)
    {
        m_aSelectionRect = rRect;
    }
    void SetRestoreCursor(bool bRestoreCursor)
    {
        m_bRestoreCursor = bRestoreCursor;
    }
    bool GetRestoreCursor() const
    {
        return m_bRestoreCursor;
    }
    sal_uInt16 GetPaintFlags() const
    {
        return m_nPaintFlags;
    }
    vcl::Region& GetPaintRegion()
    {
        return m_aPaintRegion;
    }
    void DoPaint(const vcl::Region* pRegion);
    ~PaintHelper();
};

PaintHelper::PaintHelper(vcl::Window *pWindow, sal_uInt16 nPaintFlags)
    : m_pWindow(pWindow)
    , m_pChildRegion(NULL)
    , m_nPaintFlags(nPaintFlags)
    , m_bPop(false)
    , m_bRestoreCursor(false)
{
}

void PaintHelper::DoPaint(const vcl::Region* pRegion)
{
    WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
    vcl::Region* pWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
    if ( pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL )
        pWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
    else
    {
        if ( pRegion )
            pWindowImpl->maInvalidateRegion.Union( *pRegion );

        if( pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible )
            /* #98602# need to repaint all children within the
           * tracking rectangle, so the following invert
           * operation takes places without traces of the previous
           * one.
           */
            pWindowImpl->maInvalidateRegion.Union( *pWindowImpl->mpWinData->mpTrackRect );

        if ( pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN )
            m_pChildRegion = new vcl::Region( pWindowImpl->maInvalidateRegion );
        pWindowImpl->maInvalidateRegion.Intersect( *pWinChildClipRegion );
    }
    pWindowImpl->mnPaintFlags = 0;
    if (!pWindowImpl->maInvalidateRegion.IsEmpty())
    {
        m_pWindow->BeginPaint();

        // double-buffering - so far an experimental feature
        if (officecfg::Office::Common::Misc::ExperimentalMode::get())
        {
            m_pWindow->PushPaintHelper(this, *m_pWindow);

            ScopedVclPtrInstance<VirtualDevice> pDevice;

            // transfer various settings
            // FIXME: this must disappear as we move to RenderContext only,
            // the painting must become state-less, so that no actual
            // vcl::Window setting affects this
            pDevice->SetBackground(m_pWindow->GetBackground());
            pDevice->SetClipRegion(m_pWindow->GetClipRegion());
            pDevice->SetFillColor(m_pWindow->GetFillColor());
            pDevice->SetFont(m_pWindow->GetFont());
            pDevice->SetLineColor(m_pWindow->GetLineColor());
            pDevice->SetMapMode(m_pWindow->GetMapMode());
            pDevice->SetRefPoint(m_pWindow->GetRefPoint());
            pDevice->SetSettings(m_pWindow->GetSettings());

            // update the output size now, after all the settings were copied
            pDevice->SetOutputSize(m_pWindow->GetOutputSize());

            // copy the underlying content to be able to handle trasparency
            pDevice->DrawOutDev(m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), *m_pWindow);

            m_pWindow->ApplySettings(*pDevice.get());

            // paint to the VirtualDevice first
            m_pWindow->Paint(*pDevice.get(), m_aPaintRect);

            // debugging of the areas - show where we are painting
            // export VCL_DOUBLEBUFFERING_REGIONS=1 to see where are we
            // painting
            if (getenv("VCL_DOUBLEBUFFERING_DEBUG"))
            {
                Rectangle aTestRect(m_aPaintRect);
                aTestRect.Right() -= 1;
                aTestRect.Bottom() -= 1;
                pDevice->SetLineColor(Color(COL_LIGHTRED));<commit_msg>cleanup Paint, copy more settings to virtual device<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include <config_features.h>

#include <vcl/window.hxx>
#include <vcl/dialog.hxx>
#include <vcl/virdev.hxx>
#include <vcl/cursor.hxx>
#include <vcl/settings.hxx>

#include <officecfg/Office/Common.hxx>
#include <sal/types.h>

#include <window.h>
#include <salgdi.hxx>
#include <salframe.hxx>
#include <svdata.hxx>

#define IMPL_PAINT_PAINT            ((sal_uInt16)0x0001)
#define IMPL_PAINT_PAINTALL         ((sal_uInt16)0x0002)
#define IMPL_PAINT_PAINTALLCHILDREN   ((sal_uInt16)0x0004)
#define IMPL_PAINT_PAINTCHILDREN      ((sal_uInt16)0x0008)
#define IMPL_PAINT_ERASE            ((sal_uInt16)0x0010)
#define IMPL_PAINT_CHECKRTL         ((sal_uInt16)0x0020)

class PaintHelper
{
private:
    VclPtr<vcl::Window> m_pWindow;
    vcl::Region* m_pChildRegion;
    Rectangle m_aSelectionRect;
    Rectangle m_aPaintRect;
    vcl::Region m_aPaintRegion;
    sal_uInt16 m_nPaintFlags;
    bool m_bPop;
    bool m_bRestoreCursor;
public:
    PaintHelper(vcl::Window* pWindow, sal_uInt16 nPaintFlags);
    void SetPop()
    {
        m_bPop = true;
    }
    void SetPaintRect(const Rectangle& rRect)
    {
        m_aPaintRect = rRect;
    }
    void SetSelectionRect(const Rectangle& rRect)
    {
        m_aSelectionRect = rRect;
    }
    void SetRestoreCursor(bool bRestoreCursor)
    {
        m_bRestoreCursor = bRestoreCursor;
    }
    bool GetRestoreCursor() const
    {
        return m_bRestoreCursor;
    }
    sal_uInt16 GetPaintFlags() const
    {
        return m_nPaintFlags;
    }
    vcl::Region& GetPaintRegion()
    {
        return m_aPaintRegion;
    }
    void DoPaint(const vcl::Region* pRegion);
    ~PaintHelper();
};

PaintHelper::PaintHelper(vcl::Window *pWindow, sal_uInt16 nPaintFlags)
    : m_pWindow(pWindow)
    , m_pChildRegion(NULL)
    , m_nPaintFlags(nPaintFlags)
    , m_bPop(false)
    , m_bRestoreCursor(false)
{
}

void PaintHelper::DoPaint(const vcl::Region* pRegion)
{
    WindowImpl* pWindowImpl = m_pWindow->ImplGetWindowImpl();
    vcl::Region* pWinChildClipRegion = m_pWindow->ImplGetWinChildClipRegion();
    if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALL)
    {
        pWindowImpl->maInvalidateRegion = *pWinChildClipRegion;
    }
    else
    {
        if (pRegion)
            pWindowImpl->maInvalidateRegion.Union( *pRegion );

        if (pWindowImpl->mpWinData && pWindowImpl->mbTrackVisible)
            /* #98602# need to repaint all children within the
           * tracking rectangle, so the following invert
           * operation takes places without traces of the previous
           * one.
           */
           pWindowImpl->maInvalidateRegion.Union(*pWindowImpl->mpWinData->mpTrackRect);

        if (pWindowImpl->mnPaintFlags & IMPL_PAINT_PAINTALLCHILDREN)
            m_pChildRegion = new vcl::Region(pWindowImpl->maInvalidateRegion);
        pWindowImpl->maInvalidateRegion.Intersect(*pWinChildClipRegion);
    }
    pWindowImpl->mnPaintFlags = 0;
    if (!pWindowImpl->maInvalidateRegion.IsEmpty())
    {
        m_pWindow->BeginPaint();

        // double-buffering - so far an experimental feature
        if (officecfg::Office::Common::Misc::ExperimentalMode::get())
        {
            m_pWindow->PushPaintHelper(this, *m_pWindow);

            ScopedVclPtrInstance<VirtualDevice> pDevice;

            // transfer various settings
            // FIXME: this must disappear as we move to RenderContext only,
            // the painting must become state-less, so that no actual
            // vcl::Window setting affects this
            pDevice->SetBackground(m_pWindow->GetBackground());
            pDevice->SetClipRegion(m_pWindow->GetClipRegion());
            pDevice->SetFillColor(m_pWindow->GetFillColor());
            pDevice->SetFont(m_pWindow->GetFont());
            pDevice->SetLineColor(m_pWindow->GetLineColor());
            pDevice->SetMapMode(m_pWindow->GetMapMode());
            pDevice->SetRefPoint(m_pWindow->GetRefPoint());
            pDevice->SetSettings(m_pWindow->GetSettings());
            pDevice->SetTextColor(m_pWindow->GetTextColor());
            pDevice->SetTextLineColor(m_pWindow->GetTextLineColor());
            pDevice->SetOverlineColor(m_pWindow->GetOverlineColor());
            pDevice->SetTextFillColor(m_pWindow->GetTextFillColor());
            pDevice->SetTextAlign(m_pWindow->GetTextAlign());
            pDevice->SetRasterOp(m_pWindow->GetRasterOp());
            pDevice->SetRefPoint(m_pWindow->GetRefPoint());
            pDevice->SetLayoutMode(m_pWindow->GetLayoutMode());
            pDevice->SetDigitLanguage(m_pWindow->GetDigitLanguage());

            // update the output size now, after all the settings were copied
            pDevice->SetOutputSize(m_pWindow->GetOutputSize());

            // copy the underlying content to be able to handle trasparency
            pDevice->DrawOutDev(m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), m_aPaintRect.TopLeft(), m_aPaintRect.GetSize(), *m_pWindow);

            m_pWindow->ApplySettings(*pDevice.get());

            // paint to the VirtualDevice first
            m_pWindow->Paint(*pDevice.get(), m_aPaintRect);

            // debugging of the areas - show where we are painting
            // export VCL_DOUBLEBUFFERING_DEBUG=1 to see where are we
            // painting
            if (getenv("VCL_DOUBLEBUFFERING_DEBUG"))
            {
                Rectangle aTestRect(m_aPaintRect);
                aTestRect.Right() -= 1;
                aTestRect.Bottom() -= 1;
                pDevice->SetLineColor(Color(COL_LIGHTRED));
{'fraction_non_alphanumeric': 0.10405186385737439, 'fraction_numerical': 0.011183144246353322, 'mean_word_length': 2.8942884190596403, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 127, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3488159', 'n_tokens_mistral': 3937, 'n_tokens_neox': 3813, 'n_words': 832}