tdf#164247 sw a11y check: Adhere to WCAG contrast threshold for large text
Quoting WCAG 2.2 "Success Criterion 1.4.3 Contrast (Minimum)" [1]: > The visual presentation of text and images of text has a contrast > ratio of at least 4.5:1, except for the following: > > Large Text > > Large-scale text and images of large-scale text have a contrast > ratio of at least 3:1; Regarding large text, the corresponding "Understanding SC 1.4.3" [2] clarifies: > Text that is larger and has wider character strokes is easier to read at > lower contrast. The contrast requirement for larger text is therefore > lower. This allows authors to use a wider range of color choices for > large text, which is helpful for design of pages, particularly titles. > 18 point text or 14 point bold text is judged to be large enough to > require a lower contrast ratio. Therefore, lower the text contrast requirement in Writer's accessibility check from 4.5 to 3.0 for text that is considered large according to that specification. Add a unit test with 2 test documents: * one that adheres to the requirements and would have triggered false positives without this change in place (sw/qa/core/accessibilitycheck/data/ContrastTestOK.odt) * one that doesn't adhere to the requirements and still fails the check, as it should (sw/qa/core/accessibilitycheck/data/ContrastTestFail.odt) [1] https://www.w3.org/TR/WCAG22/#contrast-minimum [2] https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html Change-Id: I398f72aa5bdcd77c42834632575d6465a5ecd586 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178127 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
This commit is contained in:
parent
5ba8f4f453
commit
a4b03fce93
4 changed files with 59 additions and 1 deletions
|
@ -318,6 +318,37 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testStylesWithHeader)
|
||||||
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DIRECT_FORMATTING, aIssues[4]->m_eIssueID);
|
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DIRECT_FORMATTING, aIssues[4]->m_eIssueID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Text contrast tests
|
||||||
|
// see https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
|
||||||
|
CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testCheckTextContrast)
|
||||||
|
{
|
||||||
|
// first test doc has these issues:
|
||||||
|
// * normal text with contrast < 4.5
|
||||||
|
// * large text with contrast < 3.0
|
||||||
|
// * bold text with font size 13 (i.e. not considered large) with contrast < 4.5
|
||||||
|
createSwDoc("ContrastTestFail.odt");
|
||||||
|
SwDoc* pDoc = getSwDoc();
|
||||||
|
sw::AccessibilityCheck aCheck(pDoc);
|
||||||
|
aCheck.check();
|
||||||
|
auto& aIssues = aCheck.getIssueCollection().getIssues();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(size_t(3), aIssues.size());
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_CONTRAST, aIssues[0]->m_eIssueID);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_CONTRAST, aIssues[1]->m_eIssueID);
|
||||||
|
CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_CONTRAST, aIssues[2]->m_eIssueID);
|
||||||
|
|
||||||
|
// second test doc has large text with contrast between 3.0 and 4.5,
|
||||||
|
// which is sufficient for large text
|
||||||
|
// both of these are considered large text according to the spec:
|
||||||
|
// * non-bold text font with size 18
|
||||||
|
// * bold text with font size 14
|
||||||
|
createSwDoc("ContrastTestOK.odt");
|
||||||
|
SwDoc* pDocOK = getSwDoc();
|
||||||
|
sw::AccessibilityCheck aCheckOK(pDocOK);
|
||||||
|
aCheckOK.check();
|
||||||
|
auto& aIssuesOK = aCheckOK.getIssueCollection().getIssues();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(size_t(0), aIssuesOK.size());
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<sfx::AccessibilityIssue>>
|
std::vector<std::shared_ptr<sfx::AccessibilityIssue>>
|
||||||
|
|
BIN
sw/qa/core/accessibilitycheck/data/ContrastTestFail.odt
Normal file
BIN
sw/qa/core/accessibilitycheck/data/ContrastTestFail.odt
Normal file
Binary file not shown.
BIN
sw/qa/core/accessibilitycheck/data/ContrastTestOK.odt
Normal file
BIN
sw/qa/core/accessibilitycheck/data/ContrastTestOK.odt
Normal file
Binary file not shown.
|
@ -21,6 +21,7 @@
|
||||||
#include <svx/svdpage.hxx>
|
#include <svx/svdpage.hxx>
|
||||||
#include <sortedobjs.hxx>
|
#include <sortedobjs.hxx>
|
||||||
#include <swtable.hxx>
|
#include <swtable.hxx>
|
||||||
|
#include <com/sun/star/awt/FontWeight.hpp>
|
||||||
#include <com/sun/star/frame/XModel.hpp>
|
#include <com/sun/star/frame/XModel.hpp>
|
||||||
#include <com/sun/star/text/XTextContent.hpp>
|
#include <com/sun/star/text/XTextContent.hpp>
|
||||||
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
|
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
|
||||||
|
@ -716,6 +717,32 @@ double calculateContrastRatio(Color const& rColor1, Color const& rColor2)
|
||||||
return (aMinMax.second + 0.05) / (aMinMax.first + 0.05);
|
return (aMinMax.second + 0.05) / (aMinMax.first + 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine required minimum contrast ratio for text with the given properties
|
||||||
|
// according to https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
|
||||||
|
// * 3.0 for large text (font size >= 18 or bold and font size >= 14)
|
||||||
|
// * 4.5 otherwise
|
||||||
|
double minimumContrastRatio(const uno::Reference<beans::XPropertySet>& xProperties)
|
||||||
|
{
|
||||||
|
double fMinimumContrastRatio = 4.5;
|
||||||
|
double fFontSize = 0;
|
||||||
|
if (xProperties->getPropertyValue(u"CharHeight"_ustr) >>= fFontSize)
|
||||||
|
{
|
||||||
|
if (fFontSize >= 18)
|
||||||
|
fMinimumContrastRatio = 3.0;
|
||||||
|
else if (fFontSize >= 14)
|
||||||
|
{
|
||||||
|
double fCharWeight = 0;
|
||||||
|
if (xProperties->getPropertyValue(u"CharWeight"_ustr) >>= fCharWeight)
|
||||||
|
{
|
||||||
|
if (fCharWeight == css::awt::FontWeight::BOLD
|
||||||
|
|| fCharWeight == css::awt::FontWeight::ULTRABOLD)
|
||||||
|
fMinimumContrastRatio = 3.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fMinimumContrastRatio;
|
||||||
|
}
|
||||||
|
|
||||||
class TextContrastCheck : public NodeCheck
|
class TextContrastCheck : public NodeCheck
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -836,7 +863,7 @@ private:
|
||||||
aBackgroundColor = COL_WHITE;
|
aBackgroundColor = COL_WHITE;
|
||||||
|
|
||||||
double fContrastRatio = calculateContrastRatio(aForegroundColor, aBackgroundColor);
|
double fContrastRatio = calculateContrastRatio(aForegroundColor, aBackgroundColor);
|
||||||
if (fContrastRatio < 4.5)
|
if (fContrastRatio < minimumContrastRatio(xProperties))
|
||||||
{
|
{
|
||||||
auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_CONTRAST),
|
auto pIssue = lclAddIssue(m_rIssueCollection, SwResId(STR_TEXT_CONTRAST),
|
||||||
sfx::AccessibilityIssueID::TEXT_CONTRAST,
|
sfx::AccessibilityIssueID::TEXT_CONTRAST,
|
||||||
|
|
Loading…
Reference in a new issue