119 {
121
123
124 int weight = 400;
125 bool italic = false;
133 QString underlinePos;
134 for (
int i=0; i < PSDStyleSheet.keys().
size(); i++) {
135 const QString key = PSDStyleSheet.keys().at(i);
136 if (key == "/Font") {
137 KoCSSFontInfo fontInfo = fontNames.value(PSDStyleSheet.value(key).toInt());
139 italic = italic?
true: fontInfo.
slantMode != QFont::StyleNormal;
140 styles.append(
"font-family:"+fontInfo.
families.join(
","));
141 if (fontInfo.
width != 100) {
142 styles.append(
"font-width:"+QString::number(fontInfo.
width));
143 }
144 continue;
145 } else if (key == "/FontSize") {
146 double val = PSDStyleSheet.value(key).toDouble();
147 val =
scale.map(QPointF(val, val)).y();
148 styles.append("font-size:"+QString::number(val));
149 continue;
150 } else if (key == "/AutoKerning" || key == "/AutoKern") {
151 if (!PSDStyleSheet.value(key).toBool()) {
152 styles.append("font-kerning: none");
153 }
154 continue;
155 } else if (key == "/Kerning") {
156
157 unsupportedStyles << key;
158 continue;
159 } else if (key == "/FauxBold") {
160 if (PSDStyleSheet.value(key).toBool()) {
161 weight = 700;
162 }
163 continue;
164 } else if (key == "/FauxItalic") {
165 if (PSDStyleSheet.value(key).toBool()) {
166 italic = true;
167 }
168
169 continue;
170 } else if (key == "/Leading") {
171 bool autoleading = true;
172 if (PSDStyleSheet.keys().contains("AutoLeading")) {
173 autoleading = PSDStyleSheet.value("AutoLeading").toBool();
174 }
175 if (!autoleading) {
176 double fontSize = PSDStyleSheet.value("FontSize").toDouble();
177 double val = PSDStyleSheet.value(key).toDouble();
178 styles.append("line-height:"+QString::number(val/fontSize));
179 }
180
181 continue;
182 } else if (key == "/HorizontalScale" || key == "/VerticalScale") {
183
184 unsupportedStyles << key;
185 continue;
186 } else if (key == "/Tracking") {
187
188 double letterSpacing = (0.001 * PSDStyleSheet.value(key).toDouble());
189 styles.append("letter-spacing:"+QString::number(letterSpacing)+"em");
190 continue;
191 } else if (key == "/BaselineShift") {
192 if (PSDStyleSheet.value(key).toDouble() > 0) {
193 double val = PSDStyleSheet.value(key).toDouble();
194 val =
scale.map(QPointF(val, val)).
y();
195 baselineShift.append(QString::number(val));
196 }
197 continue;
198 } else if (key == "/FontCaps") {
199 switch (PSDStyleSheet.value(key).toInt()) {
200 case 0:
201 break;
202 case 1:
203 fontVariantCaps.append("all-small-caps");
204 break;
205 case 2:
206 styles.append("text-transform:uppercase");
207 break;
208 default:
209 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
210 }
211 continue;
212 } else if (key == "/FontBaseline") {
213
214
215
216 switch (PSDStyleSheet.value(key).toInt()) {
217 case 0:
218 break;
219 case 1:
220 baselineShift.append("super");
221 break;
222 case 2:
223 baselineShift.append("sub");
224 break;
225 default:
226 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
227 }
228 continue;
229 } else if (key == "/FontOTPosition") {
230
231
232 switch (PSDStyleSheet.value(key).toInt()) {
233 case 0:
234 break;
235 case 1:
236 styles.append("font-variant-position:super");
237 break;
238 case 2:
239 styles.append("font-variant-position:sub");
240 break;
241 case 3:
242 fontFeatureSettings.append("'numr' 1");
243 break;
244 case 4:
245 fontFeatureSettings.append("'dnum' 1");
246 break;
247 default:
248 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
249 }
250 continue;
251 } else if (key == "/Underline") {
252 if (PSDStyleSheet.value(key).toBool()) {
253 textDecor.append("underline");
254 }
255 continue;
256 } else if (key == "/UnderlinePosition") {
257 switch (PSDStyleSheet.value(key).toInt()) {
258 case 0:
259 break;
260 case 1:
261 textDecor.append("underline");
262 underlinePos = "auto left";
263 break;
264 case 2:
265 textDecor.append("underline");
266 underlinePos = "auto right";
267 break;
268 default:
269 d->warnings << QString(
"Unknown value for %1: %1").arg(key).arg(PSDStyleSheet.value(key).toString());
270 }
271 continue;
272 } else if (key == "/YUnderline") {
273
274 if (PSDStyleSheet.value(key).toInt() == 1) {
275 underlinePos = "auto left";
276 } else if (PSDStyleSheet.value(key).toInt() == 0) {
277 underlinePos = "auto right";
278 }
279 continue;
280 } else if (key == "/Strikethrough" || key == "/StrikethroughPosition") {
281 if (PSDStyleSheet.value(key).toBool()) {
282 textDecor.append("line-through");
283 }
284 continue;
285 } else if (key == "/Ligatures") {
286 if (!PSDStyleSheet.value(key).toBool()) {
287 fontVariantLigatures.append("no-common-ligatures");
288 }
289 continue;
290 } else if (key == "/DLigatures" || key == "/DiscretionaryLigatures" || key == "/AlternateLigatures") {
291 if (PSDStyleSheet.value(key).toBool()) {
292 fontVariantLigatures.append("discretionary-ligatures");
293 }
294 continue;
295 } else if (key == "/ContextualLigatures") {
296 if (PSDStyleSheet.value(key).toBool()) {
297 fontVariantLigatures.append("contextual");
298 }
299 continue;
300 } else if (key == "/Fractions") {
301 if (PSDStyleSheet.value(key).toBool()) {
302 fontVariantNumeric.append("diagonal-fractions");
303 }
304 continue;
305 } else if (key == "/Ordinals") {
306 if (PSDStyleSheet.value(key).toBool()) {
307 fontVariantNumeric.append("ordinal");
308 }
309 continue;
310 } else if (key == "/Swash") {
311 if (PSDStyleSheet.value(key).toBool()) {
312 fontFeatureSettings.append("'swsh' 1");
313 }
314 continue;
315 } else if (key == "/Titling") {
316 if (PSDStyleSheet.value(key).toBool()) {
317 fontVariantCaps.append("titling-caps");
318 }
319 continue;
320 } else if (key == "/StylisticAlternates") {
321 if (PSDStyleSheet.value(key).toBool()) {
322 fontFeatureSettings.append("'salt' 1");
323 }
324 continue;
325 } else if (key == "/Ornaments") {
326 if (PSDStyleSheet.value(key).toBool()) {
327 fontFeatureSettings.append("'ornm' 1");
328 }
329 continue;
330 } else if (key == "/OldStyle") {
331 if (PSDStyleSheet.value(key).toBool() && !fontVariantNumeric.contains("oldstyle-nums")) {
332 fontVariantNumeric.append("oldstyle-nums");
333 }
334 continue;
335 } else if (key == "/FigureStyle") {
336 switch (PSDStyleSheet.value(key).toInt()) {
337 case 0:
338 break;
339 case 1:
340 fontVariantNumeric.append("tabular-nums");
341 fontVariantNumeric.append("lining-nums");
342 break;
343 case 2:
344 fontVariantNumeric.append("proportional-nums");
345 fontVariantNumeric.append("oldstyle-nums");
346 break;
347 case 3:
348 fontVariantNumeric.append("proportional-nums");
349 fontVariantNumeric.append("lining-nums");
350 break;
351 case 4:
352 fontVariantNumeric.append("tabular-nums");
353 fontVariantNumeric.append("oldstyle-nums");
354 break;
355 default:
356 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
357 }
358 continue;
359 } else if (key == "/Italics") {
360
361 if (PSDStyleSheet.value(key).toBool()) {
362 fontFeatureSettings.append("'ital' 1");
363 }
364 continue;
365 } else if (key == "/BaselineDirection") {
366 int val = PSDStyleSheet.value(key).toInt();
367 if (val == 1) {
368 styles.append("text-orientation: upright");
369 } else if (val == 2) {
370 styles.append("text-orientation: mixed");
371 } else if (val == 3) {
372 styles.append("text-combine-upright: all");
373 } else {
374 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
375 }
376 continue;
377 } else if (key == "/Tsume" || key == "/LeftAki" || key == "/RightAki" || key == "/JiDori") {
378
379
380
381
382
383 unsupportedStyles << key;
384 continue;
385 } else if (key == "/StyleRunAlignment") {
386
387
388
389 QString dominantBaseline;
390 switch(PSDStyleSheet.value(key).toInt()) {
391 case 3:
392 dominantBaseline = "alphabetic";
393 break;
394 case 2:
395 dominantBaseline = "center";
396 break;
397 case 0:
398 dominantBaseline = "ideographic";
399 break;
400 case 4:
401 dominantBaseline = "text-top";
402 break;
403 case 1:
404 dominantBaseline = "text-bottom";
405 break;
406 default:
407 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
408 dominantBaseline = QString();
409 }
410 if (!dominantBaseline.isEmpty()) {
411 styles.append("dominant-baseline: "+dominantBaseline);
412 styles.append("alignment-baseline: "+dominantBaseline);
413 }
414 continue;
415 } else if (key == "/Language") {
416 int val = PSDStyleSheet.value(key).toInt();
419 } else {
420 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
421 }
422 continue;
423 } else if (key == "/ProportionalMetrics") {
424 if (PSDStyleSheet.value(key).toBool()) {
425 fontFeatureSettings.append("'palt' 1");
426 }
427 continue;
428 } else if (key == "/Kana") {
429 if (PSDStyleSheet.value(key).toBool()) {
430 fontFeatureSettings.append("'hkna' 1");
431 }
432 continue;
433 } else if (key == "/Ruby") {
434 if (PSDStyleSheet.value(key).toBool()) {
435 fontVariantEastAsian.append("ruby");
436 }
437 } else if (key == "/JapaneseAlternateFeature") {
438
439
440
441
442
443
444 int val = PSDStyleSheet.value(key).toInt();
445 if (val == 0) {
446 continue;
447 } else if (val == 1) {
448 fontVariantEastAsian.append("traditional");
449 } else if (val == 2) {
450 fontFeatureSettings.append("'expt' 1");
451 } else if (val == 3) {
452 fontVariantEastAsian.append("jis78");
453 } else {
454 d->warnings << QString(
"Unknown value for %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
455 }
456 continue;
457 } else if (key == "/NoBreak") {
458
459 if (PSDStyleSheet.value(key).toBool()) {
460 styles.append("word-break: keep-all");
461 }
462 continue;
463 } else if (key == "/DirOverride") {
464 QString dir = PSDStyleSheet.value(key).toBool()? "rtl": "ltr";
465 if (PSDStyleSheet.value(key).toBool()) {
466 styles.append("direction: "+dir);
467 styles.append("unicode-bidi: isolate");
468 }
469 continue;
470 } else if (key == "/FillColor") {
471 bool fill = true;
472 if (PSDStyleSheet.keys().contains("/FillFlag")) {
473 fill = PSDStyleSheet.value("/FillFlag").toBool();
474 }
475 if (fill) {
476 QVariantHash color = PSDStyleSheet.value(key).toHash();
478 } else {
479 styles.append("fill:none");
480 }
481 } else if (key == "/StrokeColor") {
482 bool fill = true;
483 if (PSDStyleSheet.keys().contains("/StrokeFlag")) {
484 fill = PSDStyleSheet.value("/StrokeFlag").toBool();
485 }
486 if (fill) {
487 QVariantHash color = PSDStyleSheet.value(key).toHash();
489 } else {
490 styles.append("stroke:none");
491 }
492 continue;
493 } else if (key == "/OutlineWidth" || key == "/LineWidth") {
494 double val = PSDStyleSheet.value(key).toDouble();
495 val =
scale.map(QPointF(val, val)).y();
496 styles.append("stroke-width:"+QString::number(val));
497 } else if (key == "/FillFirst") {
498
499 if (PSDStyleSheet.value(key).toBool()) {
500 styles.append("paint-order: fill");
501 }
502 continue;
503 } else if (key == "/HindiNumbers") {
504
505
506 unsupportedStyles << key;
507 continue;
508 } else if (key == "/Kashida") {
509
510
511 unsupportedStyles << key;
512 continue;
513 } else if (key == "/DiacriticPos") {
514
515
516 unsupportedStyles << key;
517 continue;
518 } else if (key == "/SlashedZero") {
519
520 if (PSDStyleSheet.value(key).toBool()) {
521 fontVariantNumeric.append("slashed-zero");
522 }
523 continue;
524 } else if (key == "/StylisticSets") {
525 int flags = PSDStyleSheet.value(key).toInt();
526 for (int i = 1; i <= 20; i++) {
527 const int bit = 2^(i-1);
528 const QString tag = i > 9? QString("ss%1").arg(i):QString("ss0%1").arg(i);
529 if (flags & bit) {
530 fontFeatureSettings.append(QString("\'%1\' 1").arg(tag));
531 }
532 }
533 continue;
534 } else if (key == "/LineCap") {
535 switch (PSDStyleSheet.value(key).toInt()) {
536 case 0:
537 styles.append("stroke-linecap: butt");
538 break;
539 case 1:
540 styles.append("stroke-linecap: round");
541 break;
542 case 2:
543 styles.append("stroke-linecap: square");
544 break;
545 default:
546 styles.append("stroke-linecap: butt");
547 }
548 } else if (key == "/LineJoin") {
549 switch (PSDStyleSheet.value(key).toInt()) {
550 case 0:
551 styles.append("stroke-linejoin: miter");
552 break;
553 case 1:
554 styles.append("stroke-linejoin: round");
555 break;
556 case 2:
557 styles.append("stroke-linejoin: bevel");
558 break;
559 default:
560 styles.append("stroke-linejoin: miter");
561 }
562 } else if (key == "/MiterLimit") {
563 styles.append("stroke-miterlimit: "+PSDStyleSheet.value(key).toString());
564
565
566 } else if (key == "/LineDashOffset") {
567 styles.append("stroke-dashoffset: "+PSDStyleSheet.value(key).toString());
568 } else if (key == "/EnableWariChu" || key == "/WariChuWidowAmount" || key == "/WariChuLineGap" || key == "/WariChuJustification"
569 || key == "/WariChuOrphanAmount" || key == "/WariChuLineCount" || key == "/WariChuSubLineAmount") {
570
571 unsupportedStyles << key;
572 continue;
573 } else if (key == "/TCYUpDownAdjustment" || key == "/TCYLeftRightAdjustment") {
574
575 unsupportedStyles << key;
576 continue;
577 } else if (key == "/Type1EncodingNames" || key == "/ConnectionForms") {
578
579 unsupportedStyles << key;
580 continue;
581 } else if (key == "/FillOverPrint" || key == "/StrokeOverPrint" || key == "/Blend") {
582
583 unsupportedStyles << key;
584 continue;
585 } else if (key == "/UnderlineOffset") {
586
587 unsupportedStyles << key;
588 continue;
589 } else {
590 if (key != "/FillFlag" && key != "/StrokeFlag" && key != "/AutoLeading") {
591 d->warnings << QString(
"Unknown PSD character stylesheet style key, %1: %2").arg(key).arg(PSDStyleSheet.value(key).toString());
592 }
593 }
594 }
595 if (weight != 400) {
596 styles.append("font-weight:"+QString::number(weight));
597 }
598 if (italic) {
599 styles.append("font-style:italic");
600 }
601 if (!textDecor.isEmpty()) {
602 styles.append("text-decoration:"+textDecor.join(" "));
603 }
604 if (!baselineShift.isEmpty()) {
605 styles.append("baseline-shift:"+baselineShift.join(" "));
606 }
607 if (!fontVariantLigatures.isEmpty()) {
608 styles.append("font-variant-ligatures:"+fontVariantLigatures.join(" "));
609 }
610 if (!fontVariantNumeric.isEmpty()) {
611 styles.append("font-variant-numeric:"+fontVariantNumeric.join(" "));
612 }
613 if (!fontVariantCaps.isEmpty()) {
614 styles.append("font-variant-caps:"+fontVariantCaps.join(" "));
615 }
616 if (!fontVariantEastAsian.isEmpty()) {
617 styles.append("font-variant-east-asian:"+fontVariantEastAsian.join(" "));
618 }
619 if (!fontFeatureSettings.isEmpty()) {
620 styles.append("font-feature-settings:"+fontFeatureSettings.join(", "));
621 }
622 if (!underlinePos.isEmpty()) {
623 styles.append("text-decoration-position:"+underlinePos);
624 }
625 d->warnings << QString(
"Unsupported styles: %1").arg(unsupportedStyles.join(
","));
626 return styles.join("; ");
627}
QColor colorFromPSDStyleSheet(QVariantHash color, const KoColorSpace *imageCs)
const char * name(StandardAction id)
static QHash< int, QString > psdLanguageMap