Commit b366b75e authored by Matus Uzak's avatar Matus Uzak
Browse files

pptx: Workaround for text colors inheritance before proper color scheme support.

There's a lot of slides where the text is not visible because text color equals
the background color.

* Ignore text colors set by slideMaster/slideLayout in case the color scheme
  changed in slideLayout/slide respectively.  Always use the color scheme defined
  by slideLayout when dealing with defaults because there's a better chance the
  text is going to be visible.

FIXME: Update fo:color in styles prepared while processing the p:txStyles
(Slide Master Text Styles) element when a color scheme override is detected.

BUG:286101
parent 7a4c1909
......@@ -1588,6 +1588,26 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lnRef()
READ_EPILOGUE
}
#undef CURRENT_EL
#define CURRENT_EL masterClrMapping
//! masterClrMapping handler (Master Color Mapping)
/* This element is a part of a choice for which color mapping is used within
the document. If this element is specified, then we specifically use the
color mapping defined in the master.
Parent elements:
- [done] clrMapOvr (§19.3.1.7)
*/
KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_masterClrMapping()
{
READ_PROLOGUE
// TODO: Add filter specific stuff.
readNext();
READ_EPILOGUE
}
#undef CURRENT_EL
#define CURRENT_EL overrideClrMapping
//! overrideClrMapping handler (Override Color Mapping)
......@@ -1598,22 +1618,20 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_lnRef()
Parent elements:
- [done] clrMapOvr (§19.3.1.7)
Child elements:
- extLst (Extension List) §20.1.2.2.15
*/
KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_overrideClrMapping()
{
// FIXME: In case of presentations, this element is located after the
// p:cSld element. It basically applies theme colors to a slideLayout.
// But the corresponsing KoGenStyles from the slideMaster and slideLayout
// are already prepared so we inherit wrong colors in a presentation Slide.
READ_PROLOGUE
const QXmlStreamAttributes attrs(attributes());
#ifdef PPTXXMLSLIDEREADER_CPP
QMap<QString, QString> colorMapBkp;
if ((m_context->type == SlideLayout) || (m_context->type == Slide)) {
colorMapBkp = m_context->colorMap;
}
#endif
int index = 0;
while (index < attrs.size()) {
const QString handledAttr = attrs.at(index).name().toString();
......@@ -1624,6 +1642,29 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_overrideClrMapping()
++index;
}
// FIXME: PPTX: Update styles prepared while processing the p:txStyles
// element (Slide Master Text Styles).
//
// NOTE: Workaround! Inform the pptx filter that the color mapping
// changed compared to slideMaster. Theme specific default colors should
// be used until we get correct style:use-window-font-color support.
#ifdef PPTXXMLSLIDEREADER_CPP
if (m_context->type == SlideLayout) {
if (m_context->colorMap != colorMapBkp) {
m_context->slideLayoutProperties->overrideClrMapping = true;
m_context->slideLayoutProperties->colorMap = m_context->colorMap;
}
}
// NOTE: Workaround! Inform the pptx filter that the color mapping
// changed compared to slideMaster. Theme specific default colors should
// be used.
if (m_context->type == Slide) {
if (m_context->colorMap != colorMapBkp) {
m_context->overrideClrMapping = true;
}
}
#endif
while (!atEnd()) {
readNext();
kDebug() << *this;
......@@ -2126,6 +2167,17 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_DrawingML_r()
}
}
#ifdef PPTXXMLSLIDEREADER_CPP
// NOTE: Workaround! Themes support is not perfect at the moment so let
// the application set the text color automatically instead of using the
// wrong color from p:txStyles provided by the slideMaster. KDE BUG 286101
if (m_context->type == Slide) {
if (m_currentTextStyle.property("fo:color").isEmpty()) {
m_currentTextStyle.addProperty("style:use-window-font-color", "true");
}
}
#endif
const QString currentTextStyleName(mainStyles->insert(m_currentTextStyle));
body->startElement("text:span", false);
body->addAttribute("text:style-name", currentTextStyleName);
......@@ -4293,15 +4345,14 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_schemeClr()
READ_ATTR_WITHOUT_NS(val)
#ifdef PPTXXMLDOCUMENTREADER_CPP
// We skip reading this one properly as we do not know the correct theme in
// the time of reading.
if (m_colorState == PptxXmlDocumentReader::rprState) {
// Skip the rest of the code, the color scheme map (clrMap) is unknown at
// time of reading.
if (m_colorState == PptxXmlDocumentReader::defRPrState) {
defaultTextColors[defaultTextColors.size() - 1] = val;
}
else {
defaultBulletColors[defaultBulletColors.size() - 1] = val;
}
skipCurrentElement();
READ_EPILOGUE
#endif
......@@ -6019,17 +6070,17 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_buAutoNum()
- effectDag (Effect Container) §20.1.8.25
- effectLst (Effect Container) §20.1.8.26
- extLst (Extension List) §20.1.2.2.15
- [done] gradFill (Gradient Fill) §20.1.8.33
- [done] gradFill (Gradient Fill) §20.1.8.33
- grpFill (Group Fill) §20.1.8.35
- highlight (Highlight Color) §21.1.2.3.4
- hlinkClick (Click Hyperlink) §21.1.2.3.5
- hlinkMouseOver (Mouse-Over Hyperlink) §21.1.2.3.6
- [done] latin (Latin Font) §21.1.2.3.7
- [done] latin (Latin Font) §21.1.2.3.7
- ln (Outline) §20.1.2.2.24
- [done] noFill (No Fill) §20.1.8.44
- [done] noFill (No Fill) §20.1.8.44
- pattFill (Pattern Fill) §20.1.8.47
- rtl (Right to Left Run) §21.1.2.2.8
- [done] solidFill (Solid Fill) §20.1.8.54
- [done] solidFill (Solid Fill) §20.1.8.54
- sym (Symbol Font) §21.1.2.3.10
- uFill (Underline Fill) §21.1.2.3.12
- uFillTx (Underline Fill Properties Follow Text) §21.1.2.3.13
......@@ -6045,7 +6096,7 @@ KoFilter::ConversionStatus MSOOXML_CURRENT_CLASS::read_defRPr()
m_currentColor = QColor();
#ifdef PPTXXMLDOCUMENTREADER_CPP
m_colorState = PptxXmlDocumentReader::rprState;
m_colorState = PptxXmlDocumentReader::defRPrState;
#endif
while (!atEnd()) {
......
......@@ -207,6 +207,7 @@ KoFilter::ConversionStatus read_bodyPr();
KoFilter::ConversionStatus read_normAutofit();
KoFilter::ConversionStatus read_spAutoFit();
KoFilter::ConversionStatus read_masterClrMapping();
KoFilter::ConversionStatus read_overrideClrMapping();
//! Sets style:wrap attribute of style:style/style:graphic-properties element. Used in read_anchor()
......
......@@ -119,15 +119,17 @@ QColor DrawingMLColorSchemeSystemItem::value() const
return lastColor;
}
//TODO: use the style:use-window-font-color attribute
//! 20.1.10.58 ST_SystemColorVal (System Color Value)
if ( systemColor == QLatin1String("windowText")
|| systemColor == QLatin1String("menuText"))
if ( systemColor == QLatin1String("windowText") ||
systemColor == QLatin1String("menuText"))
{
return QPalette().color(QPalette::Active, QPalette::WindowText);
}
else if ( systemColor == QLatin1String("window")
|| systemColor == QLatin1String("menu")
|| systemColor == QLatin1String("menuBar"))
else if ( systemColor == QLatin1String("window") ||
systemColor == QLatin1String("menu") ||
systemColor == QLatin1String("menuBar"))
{
return QPalette().color(QPalette::Active, QPalette::Window);
}
......@@ -782,12 +784,12 @@ KoFilter::ConversionStatus MsooXmlThemesReader::read_sysClr()
READ_ATTR_WITHOUT_NS(lastClr)
color.get()->lastColor = Utils::ST_HexColorRGB_to_QColor(lastClr);
//kDebug() << "lastClr:" << color.get()->lastColor;
// kDebug() << "lastClr:" << color.get()->lastColor.name();
// System color value. This color is based upon the value that this color currently has
// within the system on which the document is being viewed.
// System color value. This color is based upon the value that this color
// currently has within the system on which the document is being viewed.
READ_ATTR_WITHOUT_NS_INTO(val, color.get()->systemColor)
//kDebug() << "val:" << color.get()->systemColor;
// kDebug() << "val:" << color.get()->systemColor;
readNext();
READ_EPILOGUE_WITHOUT_RETURN
......
......@@ -80,10 +80,13 @@ public:
DrawingMLColorScheme();
~DrawingMLColorScheme();
DrawingMLColorSchemeItemBase* value(const QString& name) const { return DrawingMLColorSchemeItemHash::value(name); }
DrawingMLColorSchemeItemBase* value(const QString& name) const {
return DrawingMLColorSchemeItemHash::value(name);
}
/*! @return color value for index. Needed because while PPTX uses lookup by name: value(QString&),
XLSX uses lookup by index. When index is invalid, 0 is returned. */
/*! @return color value for index. Needed because while PPTX uses lookup by
name: value(QString&), XLSX uses lookup by index. When index is
invalid, 0 is returned. */
DrawingMLColorSchemeItemBase* value(int index) const;
DrawingMLColorScheme(const DrawingMLColorScheme& scheme);
......@@ -241,11 +244,13 @@ protected:
KoFilter::ConversionStatus read_extLst();
KoFilter::ConversionStatus read_extraClrSchemeLst();
KoFilter::ConversionStatus read_extraClrScheme();
KoFilter::ConversionStatus read_clrScheme();
KoFilter::ConversionStatus read_color(); //!< helper
KoFilter::ConversionStatus read_srgbClr();
KoFilter::ConversionStatus read_sysClr();
DrawingMLColorSchemeItemBase* m_currentColor; //!< used by *Clr()
KoFilter::ConversionStatus read_fmtScheme();
KoFilter::ConversionStatus read_fontScheme();
KoFilter::ConversionStatus read_clrMap();
......
......@@ -1110,8 +1110,9 @@ KoFilter::ConversionStatus PptxImport::parseParts(KoOdfWriters *writers,
PptxXmlDocumentReader documentReader(writers);
RETURN_IF_ERROR( loadAndParseDocument(
d->mainDocumentContentType(), &documentReader, writers, errorMessage, &context) )
// We are reading twice, in the first round we ignore everything except defaultTextStyle
// except that we count the number of slides/slideMasters/noteMasters for progress reporting purposes
// Reading twice. In the 1st round everything except defaultTextStyle
// is ignored and the number of slides/slideMasters/noteMasters for
// progress reporting purposes is calculated.
context.firstReadRound = false;
RETURN_IF_ERROR( loadAndParseDocument(
d->mainDocumentContentType(), &documentReader, writers, errorMessage, &context) )
......
......@@ -137,11 +137,9 @@ KoFilter::ConversionStatus PptxXmlDocumentReader::readInternal()
if (!expectNS(MSOOXML::Schemas::presentationml)) {
return KoFilter::WrongFormat;
}
/*
const QXmlStreamAttributes attrs( attributes() );
for (int i=0; i<attrs.count(); i++) {
kDebug() << "1 NS prefix:" << attrs[i].name() << "uri:" << attrs[i].namespaceUri();
}*/
// const QXmlStreamAttributes attrs( attributes() );
// for (int i=0; i<attrs.count(); i++) {
// kDebug() << "1 NS prefix:" << attrs[i].name() << "uri:" << attrs[i].namespaceUri();
QXmlStreamNamespaceDeclarations namespaces(namespaceDeclarations());
for (int i = 0; i < namespaces.count(); i++) {
......@@ -260,9 +258,10 @@ PptxSlideProperties* PptxXmlDocumentReader::slideLayoutProperties(
#undef CURRENT_EL
#define CURRENT_EL sldId
//! p:sldId handler (Slide ID)
/*! This element specifies a presentation slide that is available within the corresponding presentation.
ECMA-376, 19.2.1.33, p. 2797.
//! p:sldId handler (Slide ID) ECMA-376, 19.2.1.33, p. 2797.
/*! This element specifies a presentation slide that is available within the
* corresponding presentation.
Parent elements:
- [done] sldIdLst (§19.2.1.34)
Child elements:
......@@ -314,7 +313,8 @@ KoFilter::ConversionStatus PptxXmlDocumentReader::read_sldId()
MSOOXML::Utils::splitPathAndFile(m_context->relationships->targetForType(slidePath, slideFile, QLatin1String(MSOOXML::Schemas::officeDocument::relationships) + "/slideLayout"), &slideMasterPath, &slideMasterFile);
const QString slideMasterPathAndFile = m_context->relationships->targetForType(slideMasterPath, slideMasterFile, QLatin1String(MSOOXML::Schemas::officeDocument::relationships) + "/slideMaster");
// Delay the reding of a tableStyle until we find a table as we need the clrMap from the master slide
// Delay the reading of a tableStyle until we find a table as we need the
// clrMap from the master slide
const QString tableStylesFilePath = m_context->relationships->targetForType(m_context->path, m_context->file, MSOOXML::Relationships::tableStyles);
PptxSlideProperties *notes = 0;
......@@ -340,7 +340,7 @@ KoFilter::ConversionStatus PptxXmlDocumentReader::read_sldId()
tableStylesFilePath
);
// In first round we only read possible colorMap override
// 1st reading round - read possible colorMap override
PptxXmlSlideReader slideReader(this);
context.firstReadingRound = true;
......@@ -354,7 +354,7 @@ KoFilter::ConversionStatus PptxXmlDocumentReader::read_sldId()
context.initializeContext(d->slideMasterPageProperties[slideLayoutProperties->m_slideMasterName].theme, defaultParagraphStyles,
defaultTextStyles, defaultListStyles, defaultBulletColors, defaultTextColors, defaultLatinFonts);
// In this round we read rest
// 2nd reading round
context.firstReadingRound = false;
status = m_context->import->loadAndParseDocument(
&slideReader, slidePath + '/' + slideFile, &context);
......
......@@ -90,7 +90,7 @@ protected:
QVector<QString> defaultTextColors;
QVector<QString> defaultLatinFonts;
enum ColorReadingState {rprState, buClrState};
enum ColorReadingState {defRPrState, buClrState};
ColorReadingState m_colorState;
private:
......
......@@ -110,6 +110,7 @@ PptxPlaceholder::~PptxPlaceholder()
PptxSlideProperties::PptxSlideProperties()
{
overrideClrMapping = false;
m_drawingPageProperties = KoGenStyle(KoGenStyle::DrawingPageAutoStyle, "drawing-page");
}
......@@ -140,6 +141,7 @@ PptxXmlSlideReaderContext::PptxXmlSlideReaderContext(
commentAuthors(_commentAuthors),
vmlReader(_vmlReader),
firstReadingRound(false),
overrideClrMapping(false),
tableStylesFilePath(_tableStylesFilePath)
{
colorMap = masterColorMap;
......@@ -164,6 +166,15 @@ void PptxXmlSlideReaderContext::initializeContext(
defaultLatinFonts = _defaultLatinFonts;
int defaultIndex = 0;
// NOTE: Workaround! The color mapping changed compared to slideMaster.
// Let's use theme specific default colors until we get correct
// style:use-window-font-color support.
QMap<QString, QString> colorMapBkp;
if (type == PptxXmlSlideReader::Slide && slideLayoutProperties->overrideClrMapping) {
colorMapBkp = colorMap;
colorMap = slideLayoutProperties->colorMap;
}
while (defaultIndex < defaultTextStyles.size()) {
if (!defaultTextColors.at(defaultIndex).isEmpty()) {
QString valTransformed = colorMap.value(defaultTextColors.at(defaultIndex));
......@@ -195,6 +206,11 @@ void PptxXmlSlideReaderContext::initializeContext(
}
++defaultIndex;
}
// NOTE: Workaround Part!
if (type == PptxXmlSlideReader::Slide && slideLayoutProperties->overrideClrMapping) {
colorMap = colorMapBkp;
}
}
class PptxXmlSlideReader::Private
......@@ -1169,15 +1185,16 @@ KoFilter::ConversionStatus PptxXmlSlideReader::read_clrMap()
#undef CURRENT_EL
#define CURRENT_EL clrMapOvr
// clrMapOvr handler (Color map override)
// clrMapOvr handler (Color Scheme Map Override)
/*
Parent elements:
- [done] sldLayout (§19.3.1.27)
- [done] sld (§19.3.1.42)
- notes (§19.3.1.26)
- [done] sld (§19.3.1.38)
- [done] sldLayout (§19.3.1.39)
Child elements:
- extLst (Extension List) §20.1.2.2.15
- [done] masterClrMapping (Master Color Mapping) §20.1.6.6
- [done] overrideClrMapping (Override Color Mapping) §20.1.6.8
*/
KoFilter::ConversionStatus PptxXmlSlideReader::read_clrMapOvr()
{
......@@ -1188,7 +1205,9 @@ KoFilter::ConversionStatus PptxXmlSlideReader::read_clrMapOvr()
BREAK_IF_END_OF(CURRENT_EL)
if (isStartElement()) {
TRY_READ_IF_NS(a, overrideClrMapping)
SKIP_UNKNOWN
ELSE_TRY_READ_IF_NS(a, masterClrMapping)
ELSE_WRONG_FORMAT
// SKIP_UNKNOWN
}
}
......@@ -1638,9 +1657,9 @@ KoFilter::ConversionStatus PptxXmlSlideReader::read_txBody()
#undef CURRENT_EL
#define CURRENT_EL graphicFrame
//! graphicFrame
/*!
This element specifies the existence of a graphics frame. This frame contains a graphic that was generated
by an external source and needs a container in which to be displayed on the slide surface.
/*! This element specifies the existence of a graphics frame. This frame
contains a graphic that was generated by an external source and needs a
container in which to be displayed on the slide surface.
Parent Elements:
- [done] grpSp (§4.4.1.19); spTree (§4.4.1.42)
......@@ -2686,6 +2705,27 @@ void PptxXmlSlideReader::inheritTextStyle(KoGenStyle& targetStyle)
}
}
}
// NOTE: Workaround! Themes support is not perfect at the moment so DO NOT
// inherit fo:color from SlideMaster when a color mapping override was
// applied. The p:txStyles element content requires an update.
if ((m_context->type == Slide || m_context->type == SlideLayout) &&
(m_context->slideLayoutProperties->overrideClrMapping)) {
targetStyle.removeProperty("fo:color", KoGenStyle::TextType);
// Theme specific default colors should be used until we get correct
// style:use-window-font-color support.
if (m_context->type == Slide) {
const int listLevel = qMax(1, m_currentListLevel);
if (m_context->defaultTextStyles.size() >= listLevel) {
QString textColor = m_context->defaultTextStyles[listLevel-1].property("fo:color", KoGenStyle::TextType);
if (!textColor.isEmpty()) {
targetStyle.addProperty("fo:color", textColor, KoGenStyle::TextType);
}
}
}
}
//Reset the text formatting inherited from the Master Slide.
if (!type.isEmpty()) {
if (m_context->type == Slide || m_context->type == SlideLayout) {
......@@ -2728,6 +2768,7 @@ void PptxXmlSlideReader::inheritTextStyle(KoGenStyle& targetStyle)
}
}
}
if (!id.isEmpty()) {
if (m_context->type == Slide || m_context->type == SlideLayout) {
#ifdef PPTX_DEBUG_TEXT_STYLES
......@@ -2753,6 +2794,23 @@ void PptxXmlSlideReader::inheritTextStyle(KoGenStyle& targetStyle)
}
}
}
// NOTE: Workaround! Themes support is not perfect at the moment so DO NOT
// inherit fo:color from slideMaster/slideLayout when a color mapping
// override was applied. (disabled at the moment)
// if (m_context->type == Slide && m_context->overrideClrMapping) {
// targetStyle.removeProperty("fo:color", KoGenStyle::TextType);
// // default text color
// const int listLevel = qMax(1, m_currentListLevel);
// if (m_context->defaultTextStyles.size() >= listLevel) {
// QString textColor = m_context->defaultTextStyles[listLevel-1].property("fo:color", KoGenStyle::TextType);
// if (!textColor.isEmpty()) {
// targetStyle.addProperty("fo:color", KoGenStyle::TextType);
// }
// }
// }
#ifdef PPTX_INHERIT_CURRENT_SHAPE_PROPERTIES
if (m_context->type == Slide) {
QString slideIdentifier = type + id;
......
......@@ -149,6 +149,10 @@ public:
QMap<QString, QString> colorMap;
// Temporary attribute providing the info that the color mapping changed
// compared to the slideMaster.
bool overrideClrMapping;
private:
};
......@@ -337,18 +341,21 @@ public:
VmlDrawingReader& vmlReader;
// Used to keep track, whether we should skip elements
// currently we need to read some slides twice
// This because some elements from the later part of the document are needed
// to fully understand cSld element
// Used to keep track, whether we should skip elements. At the moment we
// need to read some slides twice because some elements from the later part
// of the document are needed to fully understand cSld element.
bool firstReadingRound;
// Temporary attribute providing the info that the color mapping changed
// compared to the slideMaster.
bool overrideClrMapping;
void initializeContext(const MSOOXML::DrawingMLTheme& theme, const QVector<KoGenStyle>& _defaultParagraphStyles,
const QVector<KoGenStyle>& _defaultTextStyles, const QVector<MSOOXML::Utils::ParagraphBulletProperties>& _defaultListStyles,
const QVector<QString>& _defaultBulletColors, const QVector<QString>& _defaultTextColors, const QVector<QString>& _defaultLatinFonts);
// These have to be in context, because each slide/layout/master may define their own colormap
// therefore the way default text is interpreted cannot be static
// Must be in context, because each slide/layout/master may overwrite the
// color mapping and the default text colors have to be re-interpreted.
QVector<KoGenStyle> defaultTextStyles;
QVector<KoGenStyle> defaultParagraphStyles;
QVector<MSOOXML::Utils::ParagraphBulletProperties> defaultListStyles;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment