|
|
|
/*
|
|
|
|
This file is part of the KDE project
|
|
|
|
Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE <goutte@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqtextcodec.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
|
|
|
|
#include <KWEFUtil.h>
|
|
|
|
#include <KWEFBaseWorker.h>
|
|
|
|
|
|
|
|
#include "ExportFilter.h"
|
|
|
|
#include "ExportCss.h"
|
|
|
|
|
|
|
|
TQString HtmlCssWorker::escapeCssIdentifier(const TQString& strText) const
|
|
|
|
{
|
|
|
|
// Reference: section 4.1.3 of the CSS2 recommendation
|
|
|
|
// However most HTML user agents support this section only in a restrictive way, so we cannot use any CSS escape
|
|
|
|
|
|
|
|
// NOTE: we do not guarantee anymore that the style name is unique! (### FIXME)
|
|
|
|
|
|
|
|
TQString strReturn;
|
|
|
|
|
|
|
|
// Taken in the restrictive way, an identifier can only start with a letter.
|
|
|
|
const TQChar qch0(strText[0]);
|
|
|
|
if (((int)qch0<'a' || (int)qch0>'z') && ((int)qch0<'A' || (int)qch0>'Z'))
|
|
|
|
{
|
|
|
|
// Not a letter, so we have to add a prefix
|
|
|
|
strReturn+="kWoRd_"; // The curious spelling is for allowing a HTML import to identfy it and to remove it.
|
|
|
|
// The processing of the character itself is done below
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint i=0; i<strText.length(); i++)
|
|
|
|
{
|
|
|
|
const TQChar qch(strText.at(i));
|
|
|
|
const ushort ch=qch.tqunicode();
|
|
|
|
|
|
|
|
if (((ch>='a') && (ch<='z'))
|
|
|
|
|| ((ch>='A') && (ch<='Z'))
|
|
|
|
|| ((ch>='0') && (ch<='9'))
|
|
|
|
|| (ch=='-') || (ch=='_')) // The underscore is allowed by the CSS2 errata
|
|
|
|
{
|
|
|
|
// Normal allowed characters (without any problem)
|
|
|
|
strReturn+=qch;
|
|
|
|
}
|
|
|
|
else if ((ch<=' ') || (ch>=128 && ch<=160)) // space (breaking or not) and control characters
|
|
|
|
{
|
|
|
|
// CSS2 would allow to escape it but not any HTML user agent supports this
|
|
|
|
strReturn+='_';
|
|
|
|
}
|
|
|
|
else if ((ch>=161) && (getCodec()->canEncode(qch)))
|
|
|
|
{
|
|
|
|
// Any Unicode character greater or egual to 161 is allowed
|
|
|
|
// except if it cannot be written in the encoding
|
|
|
|
strReturn+=qch;
|
|
|
|
}
|
|
|
|
else // if ch >= 33 && ch <=127 with holes (or not in encoding)
|
|
|
|
{
|
|
|
|
// Either CSS2 does not allow this character unescaped or it is not in the encoding
|
|
|
|
// but a CSS escape would break some HTML user agents (e.g. Mozilla 1.4)
|
|
|
|
// So we have to do our own incompatible cooking. :-(
|
|
|
|
strReturn+="--"; // start our private escape
|
|
|
|
strReturn+=TQString::number(ch,16);
|
|
|
|
strReturn+="--"; // end our private escape
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString HtmlCssWorker::textFormatToCss(const TextFormatting& formatOrigin,
|
|
|
|
const TextFormatting& formatData, const bool force) const
|
|
|
|
{
|
|
|
|
// TODO: as this method comes from the AbiWord filter,
|
|
|
|
// TODO: verify that it is working for HTML
|
|
|
|
|
|
|
|
// TODO: rename variable formatData
|
|
|
|
TQString strElement; // TODO: rename this variable
|
|
|
|
|
|
|
|
// Font name
|
|
|
|
TQString fontName = formatData.fontName;
|
|
|
|
if (!fontName.isEmpty()
|
|
|
|
&& (force || (formatOrigin.fontName!=formatData.fontName)))
|
|
|
|
{
|
|
|
|
strElement+="font-family: ";
|
|
|
|
if (fontName.find(' ')==-1)
|
|
|
|
strElement+=escapeHtmlText(fontName);
|
|
|
|
else
|
|
|
|
{ // If the font name contains a space, it should be quoted.
|
|
|
|
strElement+='\'';
|
|
|
|
strElement+=escapeHtmlText(fontName);
|
|
|
|
strElement+='\'';
|
|
|
|
}
|
|
|
|
// ### TODO: add alternative font names
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.italic!=formatData.italic))
|
|
|
|
{
|
|
|
|
// Font style
|
|
|
|
strElement+="font-style: ";
|
|
|
|
if ( formatData.italic )
|
|
|
|
{
|
|
|
|
strElement+="italic";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strElement+="normal";
|
|
|
|
}
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
|
|
|
|
{
|
|
|
|
strElement+="font-weight: ";
|
|
|
|
if ( formatData.weight >= 75 )
|
|
|
|
{
|
|
|
|
strElement+="bold";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strElement+="normal";
|
|
|
|
}
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.fontSize!=formatData.fontSize))
|
|
|
|
{
|
|
|
|
const int size=formatData.fontSize;
|
|
|
|
if (size>0)
|
|
|
|
{
|
|
|
|
// We use absolute font sizes.
|
|
|
|
strElement+="font-size: ";
|
|
|
|
strElement+=TQString::number(size,10);
|
|
|
|
strElement+="pt; ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.fgColor!=formatData.fgColor))
|
|
|
|
{
|
|
|
|
if ( formatData.fgColor.isValid() )
|
|
|
|
{
|
|
|
|
// Give colour
|
|
|
|
strElement+="color: ";
|
|
|
|
strElement+=formatData.fgColor.name();
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.bgColor!=formatData.bgColor))
|
|
|
|
{
|
|
|
|
if ( formatData.bgColor.isValid() )
|
|
|
|
{
|
|
|
|
// Give background colour
|
|
|
|
strElement+="background-color: ";
|
|
|
|
strElement+=formatData.bgColor.name();
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.underline!=formatData.underline)
|
|
|
|
|| (formatOrigin.strikeout!=formatData.strikeout))
|
|
|
|
{
|
|
|
|
strElement+="text-decoration: ";
|
|
|
|
if ( formatData.underline )
|
|
|
|
{
|
|
|
|
strElement+="underline";
|
|
|
|
}
|
|
|
|
else if ( formatData.strikeout )
|
|
|
|
{
|
|
|
|
strElement+="line-through";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strElement+="none";
|
|
|
|
}
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (formatOrigin.fontAttribute!=formatData.fontAttribute))
|
|
|
|
{
|
|
|
|
bool smallcaps=false;
|
|
|
|
strElement+="text-transform: ";
|
|
|
|
if ( formatData.fontAttribute=="uppercase" )
|
|
|
|
{
|
|
|
|
strElement+="uppercase";
|
|
|
|
}
|
|
|
|
else if ( formatData.fontAttribute=="lowercase" )
|
|
|
|
{
|
|
|
|
strElement+="lowercase";
|
|
|
|
}
|
|
|
|
else if ( formatData.fontAttribute=="smallcaps" )
|
|
|
|
{
|
|
|
|
strElement+="none";
|
|
|
|
smallcaps=true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strElement+="none";
|
|
|
|
}
|
|
|
|
strElement+="; ";
|
|
|
|
// ### TODO: mostly issuing font-variant is not necessary.
|
|
|
|
strElement+="font-variant:";
|
|
|
|
if (smallcaps)
|
|
|
|
strElement+="small-caps";
|
|
|
|
else
|
|
|
|
strElement+="normal";
|
|
|
|
strElement+="; ";
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: As this is the last property, do not put a semi-colon
|
|
|
|
|
|
|
|
return strElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString HtmlCssWorker::getStartOfListOpeningTag(const CounterData::Style typeList, bool& ordered)
|
|
|
|
{
|
|
|
|
TQString strResult;
|
|
|
|
switch (typeList)
|
|
|
|
{
|
|
|
|
case CounterData::STYLE_CUSTOMBULLET: // We cannot keep the custom type/style
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
ordered=false;
|
|
|
|
strResult="<ul>\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_NONE:
|
|
|
|
{
|
|
|
|
ordered=false;
|
|
|
|
strResult="<ul style=\"list-style-type:none\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_CIRCLEBULLET:
|
|
|
|
{
|
|
|
|
ordered=false;
|
|
|
|
strResult="<ul style=\"list-style-type:circle\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_SQUAREBULLET:
|
|
|
|
{
|
|
|
|
ordered=false;
|
|
|
|
strResult="<ul style=\"list-style-type:square\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_DISCBULLET:
|
|
|
|
{
|
|
|
|
ordered=false;
|
|
|
|
strResult="<ul style=\"list-style-type:disc\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_NUM:
|
|
|
|
{
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol style=\"list-style-type:decimal\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_ALPHAB_L:
|
|
|
|
{
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol style=\"list-style-type:lower-alpha\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_ALPHAB_U:
|
|
|
|
{
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol style=\"list-style-type:upper-alpha\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_ROM_NUM_L:
|
|
|
|
{
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol style=\"list-style-type:lower-roman\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_ROM_NUM_U:
|
|
|
|
{
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol style=\"list-style-type:upper-roman\">\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case CounterData::STYLE_CUSTOM:
|
|
|
|
{
|
|
|
|
// We cannot keep the custom type/style
|
|
|
|
ordered=true;
|
|
|
|
strResult="<ol>\n";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return strResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString HtmlCssWorker::layoutToCss(const LayoutData& layoutOrigin,
|
|
|
|
const LayoutData& tqlayout, const bool force) const
|
|
|
|
{
|
|
|
|
TQString strLayout;
|
|
|
|
|
|
|
|
if (force || (layoutOrigin.alignment!=tqlayout.alignment))
|
|
|
|
{
|
|
|
|
if ( (tqlayout.alignment=="left") || (tqlayout.alignment== "right")
|
|
|
|
|| (tqlayout.alignment=="center") || (tqlayout.alignment=="justify"))
|
|
|
|
{
|
|
|
|
strLayout += TQString("text-align:%1; ").arg(tqlayout.alignment);
|
|
|
|
}
|
|
|
|
else if ( tqlayout.alignment=="auto")
|
|
|
|
{
|
|
|
|
// Do nothing, the user-agent should be more intelligent than us.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdWarning(30503) << "Unknown alignment: " << tqlayout.alignment << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tqlayout.indentLeft>=0.0)
|
|
|
|
&& (force || (layoutOrigin.indentLeft!=tqlayout.indentLeft)))
|
|
|
|
{
|
|
|
|
strLayout += TQString("margin-left:%1pt; ").arg(tqlayout.indentLeft);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tqlayout.indentRight>=0.0)
|
|
|
|
&& (force || (layoutOrigin.indentRight!=tqlayout.indentRight)))
|
|
|
|
{
|
|
|
|
strLayout += TQString("margin-right:%1pt; ").arg(tqlayout.indentRight);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force || (layoutOrigin.indentLeft!=tqlayout.indentLeft))
|
|
|
|
{
|
|
|
|
strLayout += TQString("text-indent:%1pt; ").arg(tqlayout.indentFirst);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tqlayout.marginBottom>=0.0)
|
|
|
|
&& ( force || ( layoutOrigin.marginBottom != tqlayout.marginBottom ) ) )
|
|
|
|
{
|
|
|
|
strLayout += TQString("margin-bottom:%1pt; ").arg(tqlayout.marginBottom);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tqlayout.marginTop>=0.0)
|
|
|
|
&& ( force || ( layoutOrigin.marginTop != tqlayout.marginTop ) ) )
|
|
|
|
{
|
|
|
|
strLayout += TQString("margin-top:%1pt; ").arg(tqlayout.marginTop);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force
|
|
|
|
|| ( layoutOrigin.lineSpacingType != tqlayout.lineSpacingType )
|
|
|
|
|| ( layoutOrigin.lineSpacing != tqlayout.lineSpacing ) )
|
|
|
|
{
|
|
|
|
switch ( tqlayout.lineSpacingType )
|
|
|
|
{
|
|
|
|
case LayoutData::LS_CUSTOM:
|
|
|
|
{
|
|
|
|
// ### TODO: CSS 2 does not known "at-least".
|
|
|
|
#if 0
|
|
|
|
// We have a custom line spacing (in points)
|
|
|
|
const TQString height ( TQString::number(tqlayout.lineSpacing) ); // ### TODO: rounding?
|
|
|
|
strLayout += "style:line-spacing:";
|
|
|
|
strLayout += height;
|
|
|
|
strLayout += "pt; ";
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_SINGLE:
|
|
|
|
{
|
|
|
|
strLayout += "line-height:normal; "; // One
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_ONEANDHALF:
|
|
|
|
{
|
|
|
|
strLayout += "line-height:150%; "; // One-and-half
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_DOUBLE:
|
|
|
|
{
|
|
|
|
strLayout += "line-height:200%; "; // Two
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_MULTIPLE:
|
|
|
|
{
|
|
|
|
const TQString mult ( TQString::number( tqRound( tqlayout.lineSpacing * 100 ) ) );
|
|
|
|
strLayout += "line-height:";
|
|
|
|
strLayout += mult;
|
|
|
|
strLayout += "%; ";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_FIXED:
|
|
|
|
{
|
|
|
|
// We have a fixed line height (in points)
|
|
|
|
const TQString height ( TQString::number(tqlayout.lineSpacing) ); // ### TODO: rounding?
|
|
|
|
strLayout += "line-height:";
|
|
|
|
strLayout += height;
|
|
|
|
strLayout += "pt; ";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case LayoutData::LS_ATLEAST:
|
|
|
|
{
|
|
|
|
// ### TODO: CSS 2 does not known "at-least".
|
|
|
|
// ### TODO: however draft CCS3 (module 'line') has 'line-stacking-strategy' to tweak this behaviour
|
|
|
|
// We have a at-least line height (in points)
|
|
|
|
const TQString height ( TQString::number(tqlayout.lineSpacing) ); // ### TODO: rounding?
|
|
|
|
strLayout += "line-height:";
|
|
|
|
strLayout += height;
|
|
|
|
strLayout += "pt; ";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
kdWarning(30503) << "Unsupported lineSpacingType: " << tqlayout.lineSpacingType << " (Ignoring!)" << endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Konqueror/KHTML does not support "text-shadow"
|
|
|
|
if (!force
|
|
|
|
&& ( layoutOrigin.shadowDirection == tqlayout.shadowDirection )
|
|
|
|
&& ( layoutOrigin.shadowDistance == tqlayout.shadowDistance ) )
|
|
|
|
{
|
|
|
|
// Do nothing!
|
|
|
|
}
|
|
|
|
else if ((!tqlayout.shadowDirection) || (!tqlayout.shadowDistance))
|
|
|
|
{
|
|
|
|
strLayout += "text-shadow:";
|
|
|
|
strLayout+="none; ";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double xDistance,yDistance;
|
|
|
|
const double distance=tqlayout.shadowDistance;
|
|
|
|
switch (tqlayout.shadowDirection)
|
|
|
|
{
|
|
|
|
case 1: // SD_LEFT_UP
|
|
|
|
{
|
|
|
|
xDistance= (-distance);
|
|
|
|
yDistance= (-distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 2: // SD_UP
|
|
|
|
{
|
|
|
|
xDistance= 0;
|
|
|
|
yDistance= (-distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 3: // SD_RIGHT_UP
|
|
|
|
{
|
|
|
|
xDistance= (distance);
|
|
|
|
yDistance= (-distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 4: // SD_RIGHT
|
|
|
|
{
|
|
|
|
xDistance= (distance);
|
|
|
|
yDistance= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 5: // SD_RIGHT_BOTTOM
|
|
|
|
{
|
|
|
|
xDistance= (distance);
|
|
|
|
yDistance= (distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 6: // SD_BOTTOM
|
|
|
|
{
|
|
|
|
xDistance= 0;
|
|
|
|
yDistance= (distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 7: // SD_LEFT_BOTTOM
|
|
|
|
{
|
|
|
|
xDistance= (-distance);
|
|
|
|
yDistance= (distance);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case 8: // SD_LEFT
|
|
|
|
{
|
|
|
|
xDistance= (distance);
|
|
|
|
yDistance= 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
xDistance=0;
|
|
|
|
yDistance=0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( (!xDistance) && (!yDistance) )
|
|
|
|
{
|
|
|
|
strLayout += "text-shadow:";
|
|
|
|
strLayout+="none; ";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strLayout += "text-shadow:";
|
|
|
|
strLayout+=TQString("%1 %2pt %3pt; ").arg(tqlayout.shadowColor.name())
|
|
|
|
.arg(xDistance,0,'f',0).arg(yDistance,0,'f',0);
|
|
|
|
// We do not want any scientific notation or any decimal
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: borders
|
|
|
|
|
|
|
|
// This must remain last, as the last property does not have a semi-colon
|
|
|
|
strLayout+=textFormatToCss(layoutOrigin.formatData.text,
|
|
|
|
tqlayout.formatData.text,force);
|
|
|
|
|
|
|
|
return strLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HtmlCssWorker::openParagraph(const TQString& strTag,
|
|
|
|
const LayoutData& tqlayout, TQChar::Direction direction)
|
|
|
|
{
|
|
|
|
const LayoutData& styleLayout=m_styleMap[tqlayout.styleName];
|
|
|
|
|
|
|
|
*m_streamOut << '<' << strTag;
|
|
|
|
|
|
|
|
// Opening elements
|
|
|
|
*m_streamOut << " class=\"" << escapeCssIdentifier(tqlayout.styleName);
|
|
|
|
*m_streamOut << "\"";
|
|
|
|
|
|
|
|
TQString strStyle=layoutToCss(styleLayout,tqlayout,false);
|
|
|
|
if (!strStyle.isEmpty())
|
|
|
|
{
|
|
|
|
*m_streamOut << " style=\"" << strStyle;
|
|
|
|
if (direction == TQChar::DirRLE) {
|
|
|
|
*m_streamOut << "direction: rtl; tqunicode-bidi: embed; ";
|
|
|
|
} else if (direction == TQChar::DirRLO) {
|
|
|
|
*m_streamOut << "direction: rtl; tqunicode-bidi: override; ";
|
|
|
|
}
|
|
|
|
*m_streamOut<< "\"";
|
|
|
|
}
|
|
|
|
|
|
|
|
*m_streamOut << ">";
|
|
|
|
|
|
|
|
if ( 1==tqlayout.formatData.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "<sub>"; //Subscript
|
|
|
|
}
|
|
|
|
else if ( 2==tqlayout.formatData.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "<sup>"; //Superscript
|
|
|
|
}
|
|
|
|
if ( tqlayout.alignment == "center" ) *m_streamOut << "<center>";
|
|
|
|
}
|
|
|
|
|
|
|
|
void HtmlCssWorker::closeParagraph(const TQString& strTag,
|
|
|
|
const LayoutData& tqlayout)
|
|
|
|
{
|
|
|
|
if ( 2==tqlayout.formatData.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "</sup>"; //Superscript
|
|
|
|
}
|
|
|
|
else if ( 1==tqlayout.formatData.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "</sub>"; //Subscript
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( tqlayout.alignment == "center" ) *m_streamOut << "</center>";
|
|
|
|
*m_streamOut << "</" << strTag << ">\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void HtmlCssWorker::openSpan(const FormatData& formatOrigin, const FormatData& format)
|
|
|
|
{
|
|
|
|
*m_streamOut << "<span style=\"";
|
|
|
|
*m_streamOut << textFormatToCss(formatOrigin.text,format.text,false);
|
|
|
|
*m_streamOut << "\">"; // close span opening tag
|
|
|
|
|
|
|
|
if ( 1==format.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "<sub>"; //Subscript
|
|
|
|
}
|
|
|
|
else if ( 2==format.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "<sup>"; //Superscript
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void HtmlCssWorker::closeSpan(const FormatData& formatOrigin, const FormatData& format)
|
|
|
|
{
|
|
|
|
if ( 2==format.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "</sup>"; //Superscript
|
|
|
|
}
|
|
|
|
else if ( 1==format.text.verticalAlignment )
|
|
|
|
{
|
|
|
|
*m_streamOut << "</sub>"; //Subscript
|
|
|
|
}
|
|
|
|
|
|
|
|
*m_streamOut << "</span>";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HtmlCssWorker::doFullPaperFormat(const int format,
|
|
|
|
const double width, const double height, const int orientation)
|
|
|
|
{
|
|
|
|
TQString strWidth, strHeight, strUnits;
|
|
|
|
KWEFUtil::GetNativePaperFormat(format, strWidth, strHeight, strUnits);
|
|
|
|
|
|
|
|
if ((strWidth.isEmpty())||(strHeight.isEmpty())||(strUnits.isEmpty()))
|
|
|
|
{
|
|
|
|
// page format is unknown, so we need the size information
|
|
|
|
strUnits="pt";
|
|
|
|
strWidth=TQString::number(width);
|
|
|
|
strHeight=TQString::number(height);
|
|
|
|
}
|
|
|
|
if (orientation==1)
|
|
|
|
{
|
|
|
|
// Landscape, so we must swap the sizes
|
|
|
|
TQString strTemp(strWidth);
|
|
|
|
strWidth=strHeight;
|
|
|
|
strHeight=strTemp;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_strPageSize="size: ";
|
|
|
|
m_strPageSize+=strWidth;
|
|
|
|
m_strPageSize+=strUnits;
|
|
|
|
m_strPageSize+=" ";
|
|
|
|
m_strPageSize+=strHeight;
|
|
|
|
m_strPageSize+=strUnits;
|
|
|
|
m_strPageSize+=";";
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HtmlCssWorker::doFullPaperBorders (const double top, const double left,
|
|
|
|
const double bottom, const double right)
|
|
|
|
{
|
|
|
|
m_strPaperBorders=" margin-top: ";
|
|
|
|
m_strPaperBorders+=TQString::number(top);
|
|
|
|
m_strPaperBorders+="pt;\n";
|
|
|
|
m_strPaperBorders+=" margin-left: ";
|
|
|
|
m_strPaperBorders+=TQString::number(left);
|
|
|
|
m_strPaperBorders+="pt;\n";
|
|
|
|
m_strPaperBorders+=" margin-bottom: ";
|
|
|
|
m_strPaperBorders+=TQString::number(bottom);
|
|
|
|
m_strPaperBorders+="pt;\n";
|
|
|
|
m_strPaperBorders+=" margin-right: ";
|
|
|
|
m_strPaperBorders+=TQString::number(right);
|
|
|
|
m_strPaperBorders+="pt;\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HtmlCssWorker::doOpenStyles(void)
|
|
|
|
{
|
|
|
|
*m_streamOut << "<style type=\"text/css\">\n";
|
|
|
|
if (!isXML())
|
|
|
|
{
|
|
|
|
// Put the style under comment to increase the compatibility with old browsers
|
|
|
|
// However in XHTML 1.0, you cannot put the style definition into HTML comments
|
|
|
|
*m_streamOut << "<!--\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Say who we are (with the CVS revision number)
|
|
|
|
const TQString strVersion("$Revision: 483471 $");
|
|
|
|
// Eliminate the dollar signs
|
|
|
|
// (We don't want that the version number changes if the HTML file is itself put in a CVS storage.)
|
|
|
|
*m_streamOut << "/* KWORD_CSS_EXPORT ="
|
|
|
|
<< strVersion.mid(10).remove('$')
|
|
|
|
<< "*/\n";
|
|
|
|
|
|
|
|
// TODO: does KWord gives a paper colour?
|
|
|
|
*m_streamOut << "BODY\n{\n background-color: #FFFFFF\n}\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HtmlCssWorker::doFullDefineStyle(LayoutData& tqlayout)
|
|
|
|
{
|
|
|
|
//Register style in the style map
|
|
|
|
m_styleMap[tqlayout.styleName]=tqlayout;
|
|
|
|
|
|
|
|
// We do not limit (anymore) any style to <h1> ... <h6>, because
|
|
|
|
// the style could be forced on <p> by the tqlayout.
|
|
|
|
|
|
|
|
*m_streamOut << "." << escapeCssIdentifier(tqlayout.styleName);
|
|
|
|
*m_streamOut << "\n{\n " << layoutToCss(tqlayout,tqlayout,true) << "\n}\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HtmlCssWorker::doCloseStyles(void)
|
|
|
|
{
|
|
|
|
if (!m_strPageSize.isEmpty())
|
|
|
|
{
|
|
|
|
*m_streamOut << "@page\n{\n ";
|
|
|
|
*m_streamOut << m_strPageSize;
|
|
|
|
*m_streamOut << "\n";
|
|
|
|
*m_streamOut << m_strPaperBorders; // ends with a LF
|
|
|
|
*m_streamOut << "}\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isXML())
|
|
|
|
{
|
|
|
|
// Put the style under comment to increase the compatibility with old browsers
|
|
|
|
// However in XHTML 1.0, you cannot put the style definition into HTML comments
|
|
|
|
*m_streamOut << "-->\n";
|
|
|
|
}
|
|
|
|
*m_streamOut << "</style>\n";
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|