Krita Source Code Documentation
Loading...
Searching...
No Matches
KoSvgTextShape_p_layout.cpp File Reference
#include "KoSvgTextShape.h"
#include "KoSvgTextShape_p.h"
#include "KoSvgTextShapeLayoutFunc.h"
#include "KoCssTextUtils.h"
#include "KoFontLibraryResourceUtils.h"
#include "KoFontRegistry.h"
#include "KoSvgTextProperties.h"
#include "KoColorBackground.h"
#include "KoWritingSystemUtils.h"
#include <FlakeDebug.h>
#include <KoPathShape.h>
#include <kis_global.h>
#include <QPainterPath>
#include <QtMath>
#include <variant>
#include <graphemebreak.h>
#include <wordbreak.h>
#include <linebreak.h>
#include <ft2build.h>
#include <hb.h>
#include <hb-ft.h>
#include <hb-ot.h>
#include <raqm.h>

Go to the source code of this file.

Typedefs

using raqm_t_sp = KisLibraryResourcePointer<raqm_t, raqm_destroy>
 

Functions

QPair< QPainterPath, QPointF > generateDecorationPath (const QLineF length, const qreal strokeWidth, const KoSvgText::TextDecorationStyle style, const bool isHorizontal, const bool onTextPath, const qreal minimumDecorationThickness)
 
QString langToLibUnibreakLang (const QString lang)
 
static QMap< int, int > logicalToVisualCursorPositions (const QVector< CursorPos > &cursorPos, const QVector< CharacterResult > &result, const QVector< LineBox > &lines, const bool &ltr=false)
 logicalToVisualCursorPositions Create a map that sorts the cursor positions by the visual index of the cluster.
 

Variables

const QString bidiControls = "\u202a\u202b\u202c\u202d\u202e\u2066\u2067\u2068\u2069"
 KoSvgTextShape::Private::resolveTransforms This resolves transforms and applies whitespace collapse.
 

Typedef Documentation

◆ raqm_t_sp

using raqm_t_sp = KisLibraryResourcePointer<raqm_t, raqm_destroy>

Definition at line 43 of file KoSvgTextShape_p_layout.cpp.

Function Documentation

◆ generateDecorationPath()

QPair< QPainterPath, QPointF > generateDecorationPath ( const QLineF length,
const qreal strokeWidth,
const KoSvgText::TextDecorationStyle style,
const bool isHorizontal,
const bool onTextPath,
const qreal minimumDecorationThickness )

Definition at line 1360 of file KoSvgTextShape_p_layout.cpp.

1367 {
1368 QPainterPath p;
1369 QPointF pathWidth;
1370 if (style != KoSvgText::Wavy) {
1371 p.moveTo(QPointF());
1372 // We're segmenting the path here so it'll be easier to warp
1373 // when text-on-path is happening.
1374 if (onTextPath) {
1375 const int total = std::floor(length.length() / (strokeWidth * 2));
1376 const qreal segment = qreal(length.length() / total);
1377 if (isHorizontal) {
1378 for (int i = 0; i < total; i++) {
1379 p.lineTo(p.currentPosition() + QPointF(segment, 0));
1380 }
1381 } else {
1382 for (int i = 0; i < total; i++) {
1383 p.lineTo(p.currentPosition() + QPointF(0, segment));
1384 }
1385 }
1386 } else {
1387 if (isHorizontal) {
1388 p.lineTo(length.length(), 0);
1389 } else {
1390 p.lineTo(0, length.length());
1391 }
1392 }
1393 }
1394 if (style == KoSvgText::Double) {
1395 qreal linewidthOffset = qMax(strokeWidth * 1.5, minimumDecorationThickness * 2);
1396 if (isHorizontal) {
1397 p.addPath(p.translated(0, linewidthOffset));
1398 pathWidth = QPointF(0, -linewidthOffset);
1399 } else {
1400 p.addPath(p.translated(linewidthOffset, 0));
1401 pathWidth = QPointF(linewidthOffset, 0);
1402 }
1403
1404 } else if (style == KoSvgText::Wavy) {
1405 qreal width = length.length();
1406 qreal height = strokeWidth * 2;
1407
1408 bool down = true;
1409 p.moveTo(QPointF());
1410
1411 for (int i = 0; i < qFloor(width / height); i++) {
1412 if (down) {
1413 p.lineTo(p.currentPosition().x() + height, height);
1414 } else {
1415 p.lineTo(p.currentPosition().x() + height, 0);
1416 }
1417 down = !down;
1418 }
1419 qreal offset = fmod(width, height);
1420 if (down) {
1421 p.lineTo(width, offset);
1422 } else {
1423 p.lineTo(width, height - offset);
1424 }
1425 pathWidth = QPointF(0, -strokeWidth);
1426
1427 // Rotate for vertical.
1428 if (!isHorizontal) {
1429 for (int i = 0; i < p.elementCount(); i++) {
1430 p.setElementPositionAt(i, p.elementAt(i).y - (strokeWidth * 2), p.elementAt(i).x);
1431 }
1432 pathWidth = QPointF(strokeWidth, 0);
1433 }
1434 }
1435 return qMakePair(p, pathWidth);
1436}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
const Params2D p
@ Double
Draw two lines. Ex: =====.
Definition KoSvgText.h:267
@ Wavy
Draw a wavy line. We currently make a zigzag, ex: ^^^^^.
Definition KoSvgText.h:270

References KoSvgText::Double, length(), p, and KoSvgText::Wavy.

◆ langToLibUnibreakLang()

QString langToLibUnibreakLang ( const QString lang)

Definition at line 95 of file KoSvgTextShape_p_layout.cpp.

95 {
96 // Libunibreak only tests against "ko", "ja" and "zh".
98 if (locale.language() == QLocale::Japanese || locale.script() == QLocale::JapaneseScript) {
99 return "ja";
100 } else if (locale.language() == QLocale::Korean || locale.script() == QLocale::KoreanScript || locale.script() == QLocale::HangulScript) {
101 return "ko";
102 } else if (locale.script() == QLocale::SimplifiedChineseScript
103 || locale.script() == QLocale::TraditionalChineseScript
104 || locale.script() == QLocale::HanWithBopomofoScript
105 || locale.script() == QLocale::HanScript
106 || locale.script() == QLocale::BopomofoScript) {
107 return "zh";
108 }
109 return lang;
110}
static QLocale localeFromBcp47Locale(const Bcp47Locale &locale)

References KoWritingSystemUtils::localeFromBcp47Locale().

◆ logicalToVisualCursorPositions()

static QMap< int, int > logicalToVisualCursorPositions ( const QVector< CursorPos > & cursorPos,
const QVector< CharacterResult > & result,
const QVector< LineBox > & lines,
const bool & ltr = false )
static

logicalToVisualCursorPositions Create a map that sorts the cursor positions by the visual index of the cluster.

Definition at line 55 of file KoSvgTextShape_p_layout.cpp.

58 {
59 QMap<int, int> logicalToVisual;
60 for (int i = 0; i < lines.size(); i++) {
61 Q_FOREACH(const LineChunk chunk, lines.at(i).chunks) {
62 QMap<int, int> visualToLogical;
63 QVector<int> visual;
64 Q_FOREACH(const int j, chunk.chunkIndices) {
65 visualToLogical.insert(result.at(j).visualIndex, j);
66 }
67 Q_FOREACH(const int j, visualToLogical.values()) {
68 QMap<int, int> relevant;
69 for (int k = 0; k < cursorPos.size(); k++) {
70 if (j == cursorPos.at(k).cluster) {
71 relevant.insert(cursorPos.at(k).offset, k);
72 }
73 }
74 Q_FOREACH(const int k, relevant.keys()) {
75 int final = result.at(j).cursorInfo.rtl? relevant.size()-1-k: k;
76 visual.append(relevant.value(final));
77 }
78 }
79
80 if (ltr) {
81 for (int k = 0; k < visual.size(); k++) {
82 logicalToVisual.insert(visual.at(k), logicalToVisual.size());
83 }
84 } else {
85 for (int k = visual.size()-1; k > -1; k--) {
86 logicalToVisual.insert(visual.at(k), logicalToVisual.size());
87 }
88 }
89 }
90 }
91
92 return logicalToVisual;
93}
QVector< int > chunkIndices
charResult indices that belong to this chunk.

References LineChunk::chunkIndices.

Variable Documentation

◆ bidiControls

const QString bidiControls = "\u202a\u202b\u202c\u202d\u202e\u2066\u2067\u2068\u2069"

KoSvgTextShape::Private::resolveTransforms This resolves transforms and applies whitespace collapse.

Definition at line 888 of file KoSvgTextShape_p_layout.cpp.