tdf#150622 use high contrast selection fg/bg colors for text selection
with SettingsForSelection
SettingsText -> HighlightTextColor
SettingsFill -> HighlightColor
SettingsLine -> HighlightColor
Change-Id: Iaac5834ce0f8b3f1b89376711b564773cfd0bfe3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141287
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/include/svx/sdr/overlay/overlayobject.hxx b/include/svx/sdr/overlay/overlayobject.hxx
index 294ceb3..643007c 100644
--- a/include/svx/sdr/overlay/overlayobject.hxx
+++ b/include/svx/sdr/overlay/overlayobject.hxx
@@ -109,10 +109,11 @@ namespace sdr::overlay
// it is switched to false
bool mbAllowsAntiAliase : 1;
// Flag to control if this OverlayObject is allowed to ignore the
// DrawMode settings which force use of colors to High Contrast fg/bg
// In High Contrast mode all fg and bg and forced to the a pair of normal
// high contrast colors. If this flag is set, then in High Contrast mode
// the colors are instead forced to the high contrast selection fg/bg pair.
// Default is false.
bool mbOverruleDrawModeSettings : 1;
bool mbHighContrastSelection : 1;
// set changed flag. Call after change, since the old range is invalidated
// and then the new one is calculated and invalidated, too. This will only
@@ -148,7 +149,7 @@ namespace sdr::overlay
bool allowsAntiAliase() const { return mbAllowsAntiAliase; }
// read access to DrawModeSettings flag
bool overrulesDrawModeSettings() const { return mbOverruleDrawModeSettings; }
bool isHighContrastSelection() const { return mbHighContrastSelection; }
// read access to baseRange. This may trigger createBaseRange() if
// object is changed.
diff --git a/include/vcl/rendercontext/DrawModeFlags.hxx b/include/vcl/rendercontext/DrawModeFlags.hxx
index edfa276..b51b179 100644
--- a/include/vcl/rendercontext/DrawModeFlags.hxx
+++ b/include/vcl/rendercontext/DrawModeFlags.hxx
@@ -45,11 +45,12 @@ enum class DrawModeFlags : sal_uInt32
SettingsFill = 0x00020000,
SettingsText = 0x00040000,
SettingsGradient = 0x00080000,
NoTransparency = 0x00100000,
SettingsForSelection = 0x00100000,
NoTransparency = 0x00200000,
};
namespace o3tl
{
template <> struct typed_flags<DrawModeFlags> : is_typed_flags<DrawModeFlags, 0x1fffff>
template <> struct typed_flags<DrawModeFlags> : is_typed_flags<DrawModeFlags, 0x3fffff>
{
};
}
diff --git a/svx/source/sdr/overlay/overlaymanager.cxx b/svx/source/sdr/overlay/overlaymanager.cxx
index 3d501b81..c29138d 100644
--- a/svx/source/sdr/overlay/overlaymanager.cxx
+++ b/svx/source/sdr/overlay/overlaymanager.cxx
@@ -51,8 +51,6 @@ namespace sdr::overlay
// but it seems reasonable to allow overlays to use the selection color
// taken from the system High Contrast settings
const DrawModeFlags nOriginalDrawMode(rDestinationDevice.GetDrawMode());
const DrawModeFlags nForceSettings = DrawModeFlags::SettingsLine | DrawModeFlags::SettingsFill |
DrawModeFlags::SettingsText | DrawModeFlags::SettingsGradient;
// create processor
std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(drawinglayer::processor2d::createProcessor2DFromOutputDevice(
@@ -81,16 +79,16 @@ namespace sdr::overlay
rDestinationDevice.SetAntialiasing(nOriginalAA & ~AntialiasingFlags::Enable);
}
const bool bOverrulesDrawModeSettings = rCandidate.overrulesDrawModeSettings();
if (bOverrulesDrawModeSettings)
const bool bIsHighContrastSelection = rCandidate.isHighContrastSelection();
if (bIsHighContrastSelection)
{
// overrule DrawMode settings
rDestinationDevice.SetDrawMode(nOriginalDrawMode & ~nForceSettings);
rDestinationDevice.SetDrawMode(nOriginalDrawMode | DrawModeFlags::SettingsForSelection);
}
pProcessor->process(rSequence);
if (bOverrulesDrawModeSettings)
if (bIsHighContrastSelection)
{
// restore DrawMode settings
rDestinationDevice.SetDrawMode(nOriginalDrawMode);
diff --git a/svx/source/sdr/overlay/overlayobject.cxx b/svx/source/sdr/overlay/overlayobject.cxx
index 6aab4f8..5c1de46 100644
--- a/svx/source/sdr/overlay/overlayobject.cxx
+++ b/svx/source/sdr/overlay/overlayobject.cxx
@@ -91,7 +91,7 @@ namespace sdr::overlay
mbIsHittable(true),
mbAllowsAnimation(false),
mbAllowsAntiAliase(true),
mbOverruleDrawModeSettings(false)
mbHighContrastSelection(false)
{
}
diff --git a/svx/source/sdr/overlay/overlayrectangle.cxx b/svx/source/sdr/overlay/overlayrectangle.cxx
index ce9c11b..3bf04f4 100644
--- a/svx/source/sdr/overlay/overlayrectangle.cxx
+++ b/svx/source/sdr/overlay/overlayrectangle.cxx
@@ -81,8 +81,8 @@ namespace sdr::overlay
// set AllowsAnimation flag to mark this object as animation capable
mbAllowsAnimation = bAnimate;
// allow use of selection color even in HighContrast mode
mbOverruleDrawModeSettings = true;
// use selection colors in HighContrast mode
mbHighContrastSelection = true;
}
void OverlayRectangle::Trigger(sal_uInt32 nTime)
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 9f3552f..76c629a 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -45,8 +45,11 @@
#include <vcl/weld.hxx>
#include <vcl/window.hxx>
#include <comphelper/lok.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <drawinglayer/processor2d/baseprocessor2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <drawinglayer/processor2d/processor2dtools.hxx>
#include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
#include <editeng/outliner.hxx>
#include <sal/log.hxx>
#include <sdr/overlay/overlaytools.hxx>
@@ -389,6 +392,7 @@ void SdrObjEditView::ModelHasChanged()
namespace
{
class TextEditFrameOverlayObject;
class TextEditHighContrastOverlaySelection;
/**
Helper class to visualize the content of an active EditView as an
@@ -407,7 +411,8 @@ class TextEditOverlayObject : public sdr::overlay::OverlayObject
{
protected:
/// local access to associated sdr::overlay::OverlaySelection
std::unique_ptr<sdr::overlay::OverlaySelection> mxOverlaySelection;
std::unique_ptr<sdr::overlay::OverlaySelection> mxOverlayTransparentSelection;
std::unique_ptr<TextEditHighContrastOverlaySelection> mxOverlayHighContrastSelection;
std::unique_ptr<TextEditFrameOverlayObject> mxOverlayFrame;
/// local definition depends on active OutlinerView
@@ -429,15 +434,11 @@ public:
TextEditOverlayObject(const Color& rColor, OutlinerView& rOutlinerView);
virtual ~TextEditOverlayObject() override;
// data read access
const sdr::overlay::OverlaySelection* getOverlaySelection() const
{
return mxOverlaySelection.get();
}
const OutlinerView& getOutlinerView() const { return mrOutlinerView; }
sdr::overlay::OverlayObject* getOverlaySelection();
sdr::overlay::OverlayObject* getOverlayFrame();
const OutlinerView& getOutlinerView() const { return mrOutlinerView; }
/// override to check conditions for last createOverlayObjectPrimitive2DSequence
virtual drawinglayer::primitive2d::Primitive2DContainer
getOverlayObjectPrimitive2DSequence() const override;
@@ -448,6 +449,10 @@ public:
void checkSelectionChange();
const basegfx::B2DRange& getRange() const { return maRange; }
const drawinglayer::primitive2d::Primitive2DContainer& getTextPrimitives() const
{
return maTextPrimitives;
}
};
class TextEditFrameOverlayObject : public sdr::overlay::OverlayObject
@@ -465,6 +470,88 @@ public:
virtual ~TextEditFrameOverlayObject() override;
};
class TextEditHighContrastOverlaySelection : public sdr::overlay::OverlayObject
{
private:
const TextEditOverlayObject& mrTextEditOverlayObject;
std::vector<basegfx::B2DRange> maRanges;
// geometry creation for OverlayObject, can use local *Last* values
virtual drawinglayer::primitive2d::Primitive2DContainer
createOverlayObjectPrimitive2DSequence() override;
public:
TextEditHighContrastOverlaySelection(const TextEditOverlayObject& rTextEditOverlayObject);
void setRanges(std::vector<basegfx::B2DRange>&& rNew);
virtual ~TextEditHighContrastOverlaySelection() override;
};
TextEditHighContrastOverlaySelection::TextEditHighContrastOverlaySelection(
const TextEditOverlayObject& rTextEditOverlayObject)
: OverlayObject(rTextEditOverlayObject.getBaseColor())
, mrTextEditOverlayObject(rTextEditOverlayObject)
{
allowAntiAliase(rTextEditOverlayObject.allowsAntiAliase());
// use selection colors in HighContrast mode
mbHighContrastSelection = true;
}
void TextEditHighContrastOverlaySelection::setRanges(std::vector<basegfx::B2DRange>&& rNew)
{
if (rNew != maRanges)
{
maRanges = std::move(rNew);
objectChange();
}
}
drawinglayer::primitive2d::Primitive2DContainer
TextEditHighContrastOverlaySelection::createOverlayObjectPrimitive2DSequence()
{
drawinglayer::primitive2d::Primitive2DContainer aRetval;
size_t nCount = maRanges.size();
if (nCount)
{
basegfx::B2DPolyPolygon aClipPolyPolygon;
basegfx::BColor aRGBColor(getBaseColor().getBColor());
for (size_t a = 0; a < nCount; ++a)
aClipPolyPolygon.append(basegfx::utils::createPolygonFromRect(maRanges[a]));
// This is used in high contrast mode, we will render the selection
// with the bg forced to the selection Highlight color and the fg color
// forced to the HighlightText color
aRetval.append(drawinglayer::primitive2d::Primitive2DReference(
new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
basegfx::B2DPolyPolygon(
basegfx::utils::createPolygonFromRect(aClipPolyPolygon.getB2DRange())),
aRGBColor)));
aRetval.append(mrTextEditOverlayObject.getTextPrimitives());
aRetval.append(drawinglayer::primitive2d::Primitive2DReference(
new drawinglayer::primitive2d::MaskPrimitive2D(aClipPolyPolygon, std::move(aRetval))));
}
return aRetval;
}
TextEditHighContrastOverlaySelection::~TextEditHighContrastOverlaySelection()
{
if (getOverlayManager())
{
getOverlayManager()->remove(*this);
}
}
sdr::overlay::OverlayObject* TextEditOverlayObject::getOverlaySelection()
{
if (mxOverlayTransparentSelection)
return mxOverlayTransparentSelection.get();
return mxOverlayHighContrastSelection.get();
}
sdr::overlay::OverlayObject* TextEditOverlayObject::getOverlayFrame()
{
if (!mxOverlayFrame)
@@ -510,14 +597,22 @@ TextEditOverlayObject::TextEditOverlayObject(const Color& rColor, OutlinerView&
// create local OverlaySelection - this is an integral part of EditText
// visualization
std::vector<basegfx::B2DRange> aEmptySelection{};
mxOverlaySelection.reset(new sdr::overlay::OverlaySelection(
sdr::overlay::OverlayType::Transparent, rColor, std::move(aEmptySelection), true));
if (Application::GetSettings().GetStyleSettings().GetHighContrastMode())
{
mxOverlayHighContrastSelection.reset(new TextEditHighContrastOverlaySelection(*this));
}
else
{
std::vector<basegfx::B2DRange> aEmptySelection{};
mxOverlayTransparentSelection.reset(new sdr::overlay::OverlaySelection(
sdr::overlay::OverlayType::Transparent, rColor, std::move(aEmptySelection), true));
}
}
TextEditOverlayObject::~TextEditOverlayObject()
{
mxOverlaySelection.reset();
mxOverlayTransparentSelection.reset();
mxOverlayHighContrastSelection.reset();
if (getOverlayManager())
{
@@ -531,8 +626,8 @@ TextEditFrameOverlayObject::TextEditFrameOverlayObject(
, mrTextEditOverlayObject(rTextEditOverlayObject)
{
allowAntiAliase(rTextEditOverlayObject.allowsAntiAliase());
// allow use of selection color even in HighContrast mode
mbOverruleDrawModeSettings = true;
// use selection colors in HighContrast mode
mbHighContrastSelection = true;
}
TextEditFrameOverlayObject::~TextEditFrameOverlayObject()
@@ -658,7 +753,10 @@ void TextEditOverlayObject::checkSelectionChange()
aRect.Right() + aLogicPixel.Width(), aRect.Bottom() + aLogicPixel.Height());
}
mxOverlaySelection->setRanges(std::move(aLogicRanges));
if (mxOverlayTransparentSelection)
mxOverlayTransparentSelection->setRanges(std::move(aLogicRanges));
else
mxOverlayHighContrastSelection->setRanges(std::move(aLogicRanges));
}
} // end of anonymous namespace
@@ -1309,8 +1407,7 @@ bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::W
xManager->add(*pNewTextEditOverlayObject);
if (bVisualizeSurroundingFrame)
xManager->add(*pNewTextEditOverlayObject->getOverlayFrame());
xManager->add(const_cast<sdr::overlay::OverlaySelection&>(
*pNewTextEditOverlayObject->getOverlaySelection()));
xManager->add(*pNewTextEditOverlayObject->getOverlaySelection());
maTEOverlayGroup.append(std::move(pNewTextEditOverlayObject));
}
diff --git a/vcl/source/outdev/gradient.cxx b/vcl/source/outdev/gradient.cxx
index bd19cd5..707ca47 100644
--- a/vcl/source/outdev/gradient.cxx
+++ b/vcl/source/outdev/gradient.cxx
@@ -617,7 +617,12 @@ Color OutputDevice::GetSingleColorGradientFill()
else if ( mnDrawMode & DrawModeFlags::WhiteGradient )
aColor = COL_WHITE;
else if ( mnDrawMode & DrawModeFlags::SettingsGradient )
aColor = GetSettings().GetStyleSettings().GetWindowColor();
{
if (mnDrawMode & DrawModeFlags::SettingsForSelection)
aColor = GetSettings().GetStyleSettings().GetHighlightColor();
else
aColor = GetSettings().GetStyleSettings().GetWindowColor();
}
return aColor;
}
diff --git a/vcl/source/rendercontext/drawmode.cxx b/vcl/source/rendercontext/drawmode.cxx
index fe0a1660..9819be3 100644
--- a/vcl/source/rendercontext/drawmode.cxx
+++ b/vcl/source/rendercontext/drawmode.cxx
@@ -53,7 +53,10 @@ Color GetLineColor(Color const& rColor, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsLine)
{
aColor = rStyleSettings.GetWindowTextColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aColor = rStyleSettings.GetHighlightColor();
else
aColor = rStyleSettings.GetWindowTextColor();
}
}
}
@@ -91,7 +94,10 @@ Color GetFillColor(Color const& rColor, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsFill)
{
aColor = rStyleSettings.GetWindowColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aColor = rStyleSettings.GetHighlightColor();
else
aColor = rStyleSettings.GetWindowColor();
}
}
}
@@ -119,7 +125,10 @@ Color GetHatchColor(Color const& rColor, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsLine)
{
aColor = rStyleSettings.GetWindowTextColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aColor = rStyleSettings.GetHighlightColor();
else
aColor = rStyleSettings.GetWindowTextColor();
}
return aColor;
@@ -149,7 +158,10 @@ Color GetTextColor(Color const& rColor, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsText)
{
aColor = rStyleSettings.GetWindowTextColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aColor = rStyleSettings.GetHighlightTextColor();
else
aColor = rStyleSettings.GetWindowTextColor();
}
}
@@ -183,7 +195,10 @@ vcl::Font GetFont(vcl::Font const& rFont, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsText)
{
aTextColor = rStyleSettings.GetWindowTextColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aTextColor = rStyleSettings.GetHighlightTextColor();
else
aTextColor = rStyleSettings.GetWindowTextColor();
}
aFont.SetColor(aTextColor);
@@ -207,7 +222,10 @@ vcl::Font GetFont(vcl::Font const& rFont, DrawModeFlags nDrawMode,
}
else if (nDrawMode & DrawModeFlags::SettingsFill)
{
aTextFillColor = rStyleSettings.GetWindowColor();
if (nDrawMode & DrawModeFlags::SettingsForSelection)
aTextFillColor = rStyleSettings.GetHighlightColor();
else
aTextFillColor = rStyleSettings.GetWindowColor();
}
else if (nDrawMode & DrawModeFlags::NoFill)
{