Subversion Repositories Scribus

Rev

Rev 9636 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6443 avox 1
/*
2
 For general Scribus (>=1.3.2) copyright and licensing information please refer
3
 to the COPYING file provided with the program. Following this notice may exist
4
 a copyright and/or license notice that predates the release of Scribus 1.3.2
5
 for which a new license (GPL+exception) is in place.
6
 */
7
 
8
 
9
#include <qvaluelist.h>
10
#include <qobject.h>
11
#include "sctextstruct.h"
12
#include "scfonts.h"
8455 avox 13
#include "resourcecollection.h"
8382 avox 14
 
15
#include "styles/style.h"
8337 avox 16
#include "charstyle.h"
8193 avox 17
#include "desaxe/saxiohelper.h"
8266 avox 18
#include "desaxe/simple_actions.h"
19
#include "prefsmanager.h"
6443 avox 20
 
7456 jghali 21
StyleFlag& StyleFlag::operator&= (const StyleFlag& right){        
22
        int result = static_cast<int>(value) & static_cast<int>(right.value);        
23
        value = static_cast<StyleFlagValue>(result);
24
        return *this;
6443 avox 25
}
26
 
7456 jghali 27
StyleFlag& StyleFlag::operator|= (const StyleFlag& right)
6443 avox 28
{
7456 jghali 29
        int result = static_cast<int>(value) | static_cast<int>(right.value);
30
        value = static_cast<StyleFlagValue>(result);
31
        return *this;
6443 avox 32
}
33
 
7456 jghali 34
StyleFlag StyleFlag::operator& (const StyleFlag& right)
6443 avox 35
{
7456 jghali 36
        int val = static_cast<int>(value) & static_cast<int>(right.value);
37
        StyleFlag result(static_cast<StyleFlagValue>(val));
38
        return result;
6443 avox 39
}
40
 
7456 jghali 41
StyleFlag StyleFlag::operator& (int right)
42
{
43
        int val = static_cast<int>(value) & right;
44
        StyleFlag result(static_cast<StyleFlagValue>(val));
45
        return result;
46
}
47
 
48
StyleFlag StyleFlag::operator| (const StyleFlag& right)
6443 avox 49
{        
7456 jghali 50
        int val = static_cast<int>(value) | static_cast<int>(right.value);
51
        StyleFlag result(static_cast<StyleFlagValue>(val));
52
        return result;
6443 avox 53
}
54
 
7456 jghali 55
StyleFlag StyleFlag::operator^ (const StyleFlag& right)
56
{
57
        int val = static_cast<int>(value) ^ static_cast<int>(right.value);
58
        StyleFlag result(static_cast<StyleFlagValue>(val));
59
        return result;
6443 avox 60
}
61
 
7456 jghali 62
StyleFlag StyleFlag::operator^  (int right)
6443 avox 63
{
7456 jghali 64
        int val = static_cast<int>(value) ^ right;
65
        StyleFlag result(static_cast<StyleFlagValue>(val));
66
        return result;
6443 avox 67
}
68
 
7456 jghali 69
StyleFlag StyleFlag::operator~ ()
70
{
71
        int val = ~ static_cast<int>(value);
72
        StyleFlag result(static_cast<StyleFlagValue>(val));
73
        return result;
74
}
75
 
76
bool StyleFlag::operator== (const StyleFlag& right) const
7017 avox 77
{        
7456 jghali 78
        int result = static_cast<int>( (value ^ right.value) & ScStyle_UserStyles);
79
        return (result == 0);
7017 avox 80
}
6443 avox 81
 
7456 jghali 82
bool StyleFlag::operator== (const StyleFlagValue right) const
7017 avox 83
{
7456 jghali 84
        int result = static_cast<int>( (value ^ right) & ScStyle_UserStyles);
85
        return (result == 0);
7017 avox 86
}
87
 
7456 jghali 88
bool StyleFlag::operator== (int right) const
89
{
90
        int result = static_cast<int>( (value ^ right) & ScStyle_UserStyles);
91
        return (result == 0);
92
}
93
 
94
bool StyleFlag::operator!= (const StyleFlag& right) const
95
{
96
        return !(*this==right);
97
}
98
 
99
bool StyleFlag::operator!= (const StyleFlagValue right) const
100
{
101
        return !(*this==right);
102
}
103
 
8193 avox 104
 
9592 avox 105
 
6443 avox 106
void CharStyle::applyCharStyle(const CharStyle & other)
107
{
108
        Style::applyStyle(other);
109
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
110
        if (! other.inh_##attr_NAME) \
111
                set##attr_NAME(other.m_##attr_NAME);
112
#include "charstyle.attrdefs.cxx"
113
#undef ATTRDEF
9602 avox 114
        updateFeatures();
6443 avox 115
}
116
 
117
 
118
void CharStyle::eraseCharStyle(const CharStyle & other)
119
{
6805 avox 120
        other.validate();
6443 avox 121
        Style::eraseStyle(other);
122
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
6936 avox 123
        if (!inh_##attr_NAME && m_##attr_NAME == other.m_##attr_NAME) \
6443 avox 124
                reset##attr_NAME();
125
#include "charstyle.attrdefs.cxx"
126
#undef ATTRDEF
9602 avox 127
        updateFeatures();
6443 avox 128
}
129
 
130
bool CharStyle::equiv(const Style & other) const
131
{
6805 avox 132
        other.validate();
6443 avox 133
        const CharStyle * oth = dynamic_cast<const CharStyle*> ( & other );
134
        return  oth &&
6733 avox 135
                parent() == oth->parent()
6443 avox 136
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
6733 avox 137
                && (inh_##attr_NAME == oth->inh_##attr_NAME) \
138
                && (inh_##attr_NAME || m_##attr_NAME == oth->m_##attr_NAME)
6443 avox 139
#include "charstyle.attrdefs.cxx"
140
#undef ATTRDEF
141
                ;      
142
}
143
 
144
 
145
QString CharStyle::displayName() const
146
{
8134 avox 147
        if ( hasName() || !hasParent() || ! m_context)
6443 avox 148
                return name();
149
//      else if ( inheritsAll() )
150
//              return parent()->displayName();
151
        else
152
                return parentStyle()->displayName() + "+";
153
}
154
 
155
 
156
 
157
QString CharStyle::asString() const
158
{
159
        QString result;
160
        if ( !inh_Font )
161
                result += QObject::tr("font %1 ").arg(font().scName());
162
        if ( !inh_FontSize )
163
                result += QObject::tr("size %1 ").arg(fontSize());
9592 avox 164
        if ( !inh_Features )
6443 avox 165
                result += QObject::tr("+style ");
166
        if ( !inh_StrokeColor  ||  !inh_StrokeShade  ||  !inh_FillColor || !inh_FillShade )
167
                result += QObject::tr("+color ");
168
        if ( !inh_UnderlineWidth  ||  !inh_UnderlineOffset )
169
                result += underlineWidth() > 0 ? QObject::tr("+underline ") : QObject::tr("-underline ");
6733 avox 170
        if ( !inh_StrikethruWidth || !inh_StrikethruOffset )
6443 avox 171
                result += strikethruWidth() > 0 ? QObject::tr("+strikeout ") : QObject::tr("-strikeout ");
172
        if ( !inh_ShadowXOffset || !inh_ShadowYOffset )
6733 avox 173
                result += shadowXOffset() != 0 || shadowYOffset() != 0 ? QObject::tr("+shadow ") : QObject::tr("-shadow ");
6443 avox 174
        if ( !inh_OutlineWidth )
175
                result += outlineWidth() > 0 ? QObject::tr("+outline ") : QObject::tr("-outline ");
176
        if ( !inh_Tracking )
177
                result += tracking() > 0 ? QObject::tr("+tracking %1 ").arg(tracking()) : QObject::tr("-tracking ");
178
        if ( !inh_BaselineOffset )
179
                result += QObject::tr("+baseline %1 ").arg(baselineOffset());
180
        if ( !inh_ScaleH || !inh_ScaleV )
181
                result += QObject::tr("+stretch ");
182
        if ( hasParent() )
183
                result += QObject::tr("parent= %1").arg(parent());
184
        return result.stripWhiteSpace();
185
}
186
 
187
 
8134 avox 188
void CharStyle::update(const StyleContext* context)
6443 avox 189
{
8134 avox 190
        Style::update(context);
6443 avox 191
        const CharStyle * oth = dynamic_cast<const CharStyle*> ( parentStyle() );
192
        if (oth) {
193
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
194
                if (inh_##attr_NAME) \
6733 avox 195
                        m_##attr_NAME = oth->attr_GETTER();
6443 avox 196
#include "charstyle.attrdefs.cxx"
197
#undef ATTRDEF
198
        }
9592 avox 199
        updateFeatures();
6443 avox 200
}
201
 
202
 
9592 avox 203
 
204
const QString CharStyle::INHERIT = "inherit";
205
const QString CharStyle::BOLD = "bold";
206
const QString CharStyle::ITALIC = "italic";
207
const QString CharStyle::UNDERLINE = "underline";
208
const QString CharStyle::UNDERLINEWORDS = "underlinewords";
209
const QString CharStyle::STRIKETHROUGH = "strike";
210
const QString CharStyle::SUPERSCRIPT = "superscript";
211
const QString CharStyle::SUBSCRIPT = "subscript";
212
const QString CharStyle::OUTLINE = "outline";
213
const QString CharStyle::SHADOWED = "shadowed";
214
const QString CharStyle::ALLCAPS = "allcaps";
215
const QString CharStyle::SMALLCAPS = "smallcaps";
216
// This is for loading legacy docs only. Scribus 1.3.4 should write smart hyphens in another way 
217
static const QString SHYPHEN = "shyphen";
218
 
219
 
220
QStringList StyleFlag::featureList() const
221
{
222
        QStringList result(CharStyle::INHERIT);
223
        if (*this & ScStyle_Underline)
224
                result << CharStyle::UNDERLINE;
225
        if (*this & ScStyle_UnderlineWords)
226
                result << CharStyle::UNDERLINEWORDS;
227
        if (*this & ScStyle_Strikethrough)
228
                result << CharStyle::STRIKETHROUGH;
229
        if (*this & ScStyle_Superscript)
230
                result << CharStyle::SUPERSCRIPT;
231
        if (*this & ScStyle_Subscript)
232
                result << CharStyle::SUBSCRIPT;
233
        if (*this & ScStyle_Outline)
234
                result << CharStyle::OUTLINE;
235
        if (*this & ScStyle_Shadowed)
236
                result << CharStyle::SHADOWED;
237
        if (*this & ScStyle_AllCaps)
238
                result << CharStyle::ALLCAPS;
239
        if (*this & ScStyle_SmallCaps)
240
                result << CharStyle::SMALLCAPS;
241
        if (*this & ScStyle_HyphenationPossible)
242
                result << SHYPHEN;
243
        return result;
244
}
245
 
246
 
247
void CharStyle::updateFeatures()
248
{
249
        m_Effects &= ~ScStyle_UserStyles;
250
        runFeatures(m_Features, dynamic_cast<const CharStyle*>(parentStyle()));
9602 avox 251
/* need to access global fontlist :-/
252
        if (!font().name().endsWith(fontVariant()))
253
        {
254
                m_font = ScFonts.instance().findFont(font().family() + fontVariant());
255
        }
256
 */
9592 avox 257
}
258
 
259
 
260
void CharStyle::runFeatures(const QStringList& featureList, const CharStyle* parent)
261
{
262
        QStringList::ConstIterator it;
263
        for (it = featureList.begin(); it != featureList.end(); ++it)
264
        {
9636 avox 265
                QString feature = *it;
9592 avox 266
                if (feature == INHERIT)
267
                {
268
                        if (parent)
269
                                runFeatures(parent->features(), dynamic_cast<const CharStyle*>(parent->parentStyle()));
270
                }
271
                else if (feature == BOLD)
272
                {
273
                        // select bolder font
274
                }
275
                else if (feature == ITALIC)
276
                {
277
                        // select italic font
278
                }
279
                else if (feature == UNDERLINE)
280
                {
281
                        m_Effects |= ScStyle_Underline;
282
                }
283
                else if (feature == UNDERLINEWORDS)
284
                {
285
                        m_Effects |= ScStyle_UnderlineWords;
286
                }
287
                else if (feature == STRIKETHROUGH)
288
                {
289
                        m_Effects |= ScStyle_Strikethrough;
290
                }
291
                else if (feature == SUPERSCRIPT)
292
                {
293
                        m_Effects |= ScStyle_Superscript;
294
                }
295
                else if (feature == SUBSCRIPT)
296
                {
297
                        m_Effects |= ScStyle_Subscript;
298
                }
299
                else if (feature == OUTLINE)
300
                {
301
                        m_Effects |= ScStyle_Outline;
302
                }
303
                else if (feature == SHADOWED)
304
                {
305
                        m_Effects |= ScStyle_Shadowed;
306
                }
307
                else if (feature == ALLCAPS)
308
                {
309
                        m_Effects |= ScStyle_AllCaps;
310
                }
311
                else if (feature == SMALLCAPS)
312
                {
313
                        m_Effects |= ScStyle_SmallCaps;
314
                }
315
                else if (feature == SHYPHEN)
316
                {
317
                        m_Effects |= ScStyle_HyphenationPossible;
318
                }
319
                else if (feature.startsWith("-"))
320
                {
321
                        QString no_feature = feature.mid(1);
322
                        if (no_feature == BOLD)
323
                        {
324
                                // deselect bolder font
325
                        }
326
                        else if (no_feature == ITALIC)
327
                        {
328
                                // deselect italic font
329
                        }
330
                        else if (no_feature == UNDERLINE)
331
                        {
332
                                m_Effects &= ~ScStyle_Underline;
333
                        }
334
                        else if (no_feature == UNDERLINEWORDS)
335
                        {
336
                                m_Effects &= ~ScStyle_UnderlineWords;
337
                        }
338
                        else if (no_feature == STRIKETHROUGH)
339
                        {
340
                                m_Effects &= ~ScStyle_Strikethrough;
341
                        }
342
                        else if (no_feature == SUPERSCRIPT)
343
                        {
344
                                m_Effects &= ~ScStyle_Superscript;
345
                        }
346
                        else if (no_feature == SUBSCRIPT)
347
                        {
348
                                m_Effects &= ~ScStyle_Subscript;
349
                        }
350
                        else if (no_feature == OUTLINE)
351
                        {
352
                                m_Effects &= ~ScStyle_Outline;
353
                        }
354
                        else if (no_feature == SHADOWED)
355
                        {
356
                                m_Effects &= ~ScStyle_Shadowed;
357
                        }
358
                        else if (no_feature == ALLCAPS)
359
                        {
360
                                m_Effects &= ~ScStyle_AllCaps;
361
                        }
362
                        else if (no_feature == SMALLCAPS)
363
                        {
364
                                m_Effects &= ~ScStyle_SmallCaps;
365
                        }
366
                        else {
367
                                qDebug("CharStyle: unknown feature: %s", feature.ascii());
368
                        }
369
                }
370
                else {
371
                        qDebug("CharStyle: unknown feature: %s", feature.ascii());
372
                }
373
 
374
        }
375
}
376
 
377
 
378
 
7242 avox 379
void CharStyle::setStyle(const CharStyle& other)
380
{
381
        other.validate();
7993 avox 382
        setParent(other.parent());
9638 avox 383
        m_contextversion = -1;
7242 avox 384
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
7993 avox 385
        inh_##attr_NAME = other.inh_##attr_NAME; \
7242 avox 386
        m_##attr_NAME = other.m_##attr_NAME;
387
#include "charstyle.attrdefs.cxx"
388
#undef ATTRDEF
9602 avox 389
        updateFeatures();
7242 avox 390
}
6443 avox 391
 
8455 avox 392
void CharStyle::getNamedResources(ResourceCollection& lists) const
393
{
8857 avox 394
        for (const Style* sty = parentStyle(); sty != NULL; sty = sty->parentStyle())
395
                lists.collectCharStyle(sty->name());
8455 avox 396
        lists.collectColor(fillColor());
397
        lists.collectColor(strokeColor());
398
        lists.collectFont(font().scName());
399
}
6443 avox 400
 
7242 avox 401
 
8455 avox 402
void CharStyle::replaceNamedResources(ResourceCollection& newNames)
403
{
8716 avox 404
        QMap<QString,QString>::ConstIterator it;
8455 avox 405
 
8716 avox 406
        if (!inh_FillColor && (it = newNames.colors().find(fillColor())) != newNames.colors().end())
8455 avox 407
                setFillColor(it.data());
408
 
8716 avox 409
        if (!inh_StrokeColor && (it = newNames.colors().find(strokeColor())) != newNames.colors().end())
8455 avox 410
                setStrokeColor(it.data());
411
 
8716 avox 412
        if (hasParent() && (it = newNames.charStyles().find(parent())) != newNames.charStyles().end())
8455 avox 413
                setParent(it.data());
414
 
8716 avox 415
        if (!inh_Font && (it = newNames.fonts().find(font().scName())) != newNames.fonts().end())
416
                setFont(newNames.availableFonts->findFont(it.data(), NULL));
9602 avox 417
        updateFeatures();
8455 avox 418
}
419
 
420
                                                                  /*
6443 avox 421
bool CharStyle::definesAll() const
422
{
423
        return definesLineSpacing() &&
424
        definesLeftMargin() &&
425
        definesRightMargin() &&
426
        definesFirstIndent() &&
427
        definesAlignment() &&
428
        definesGapBefore()  &&
429
        definesLineSpacingMode()  &&
430
        definesGapAfter()  &&
431
        definesHasDropCap() &&
432
        definesDropCapOffset() &&
433
        definesDropCapLines() &&
434
        definesUseBaselineGrid() &&
435
        charStyle().definesAll() ;
436
 
437
}
438
 
7242 avox 439
// equiv. to "*this == CharStyle()"
6443 avox 440
bool CharStyle::inheritsAll() const
441
{
442
        return inheritsLineSpacing() &&
443
        inheritsLeftMargin() &&
444
        inheritsRightMargin() &&
445
        inheritsFirstIndent() &&
446
        inheritsAlignment() &&
447
        inheritsGapBefore()  &&
448
        inheritsLineSpacingMode()  &&
449
        inheritsGapAfter()  &&
450
        inheritsHasDropCap() &&
451
        inheritsDropCapOffset() &&
452
        inheritsDropCapLines() &&
453
        inheritsUseBaselineGrid() &&
454
        charStyle().inheritsAll() ;
455
}
456
*/
457
 
8266 avox 458
 
459
Xml_string toXMLString(StyleFlag val)
460
{
461
        return toXMLString(static_cast<unsigned int>(val & ScStyle_UserStyles));
462
}
463
 
464
 
8807 jghali 465
void CharStyle::saxx(SaxHandler& handler, const Xml_string& elemtag) const
8266 avox 466
{
467
        Xml_attr att;
8337 avox 468
        Style::saxxAttributes(att);
8266 avox 469
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
470
        if (!inh_##attr_NAME) \
471
                att.insert(# attr_NAME, toXMLString(m_##attr_NAME));
472
#include "charstyle.attrdefs.cxx"
473
#undef ATTRDEF
8382 avox 474
        if (!name().isEmpty())
8390 avox 475
                att["id"] = mkXMLName(elemtag + name());
8382 avox 476
        handler.begin(elemtag, att);
8455 avox 477
//      if (hasParent() && parentStyle())
478
//              parentStyle()->saxx(handler);   
8382 avox 479
        handler.end(elemtag);
8266 avox 480
}
481
 
482
 
483
 
484
template<>
8807 jghali 485
StyleFlag parse<StyleFlag>(const Xml_string& str)
8266 avox 486
{
487
        return StyleFlag(parseInt(str));
488
}
489
 
490
template<>
8807 jghali 491
ScFace parse<ScFace>(const Xml_string& str)
8266 avox 492
{
493
        // FIXME: enable font substitution here
494
        return PrefsManager::instance()->appPrefs.AvailFonts[str];
495
}
496
 
497
 
498
using namespace desaxe;
499
 
500
 
501
const Xml_string CharStyle::saxxDefaultElem("charstyle");
502
 
8832 avox 503
void CharStyle::desaxeRules(const Xml_string& prefixPattern, Digester& ruleset, Xml_string elemtag)
8382 avox 504
{
505
        Xml_string stylePrefix(Digester::concat(prefixPattern, elemtag));
506
        ruleset.addRule(stylePrefix, Factory<CharStyle>());
507
        ruleset.addRule(stylePrefix, IdRef<CharStyle>());
508
        Style::desaxeRules<CharStyle>(prefixPattern, ruleset, elemtag);
8266 avox 509
#define ATTRDEF(attr_TYPE, attr_GETTER, attr_NAME, attr_DEFAULT) \
8382 avox 510
        ruleset.addRule(stylePrefix, SetAttributeWithConversion<CharStyle, attr_TYPE> ( & CharStyle::set##attr_NAME,  # attr_NAME, &parse<attr_TYPE> ));
8266 avox 511
#include "charstyle.attrdefs.cxx"
512
#undef ATTRDEF          
8382 avox 513
}