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 1324 of file KoSvgTextShape_p_layout.cpp.

1331 {
1332 QPainterPath p;
1333 QPointF pathWidth;
1334 if (style != KoSvgText::Wavy) {
1335 p.moveTo(QPointF());
1336 // We're segmenting the path here so it'll be easier to warp
1337 // when text-on-path is happening.
1338 if (onTextPath) {
1339 const int total = std::floor(length.length() / (strokeWidth * 2));
1340 const qreal segment = qreal(length.length() / total);
1341 if (isHorizontal) {
1342 for (int i = 0; i < total; i++) {
1343 p.lineTo(p.currentPosition() + QPointF(segment, 0));
1344 }
1345 } else {
1346 for (int i = 0; i < total; i++) {
1347 p.lineTo(p.currentPosition() + QPointF(0, segment));
1348 }
1349 }
1350 } else {
1351 if (isHorizontal) {
1352 p.lineTo(length.length(), 0);
1353 } else {
1354 p.lineTo(0, length.length());
1355 }
1356 }
1357 }
1358 if (style == KoSvgText::Double) {
1359 qreal linewidthOffset = qMax(strokeWidth * 1.5, minimumDecorationThickness * 2);
1360 if (isHorizontal) {
1361 p.addPath(p.translated(0, linewidthOffset));
1362 pathWidth = QPointF(0, -linewidthOffset);
1363 } else {
1364 p.addPath(p.translated(linewidthOffset, 0));
1365 pathWidth = QPointF(linewidthOffset, 0);
1366 }
1367
1368 } else if (style == KoSvgText::Wavy) {
1369 qreal width = length.length();
1370 qreal height = strokeWidth * 2;
1371
1372 bool down = true;
1373 p.moveTo(QPointF());
1374
1375 for (int i = 0; i < qFloor(width / height); i++) {
1376 if (down) {
1377 p.lineTo(p.currentPosition().x() + height, height);
1378 } else {
1379 p.lineTo(p.currentPosition().x() + height, 0);
1380 }
1381 down = !down;
1382 }
1383 qreal offset = fmod(width, height);
1384 if (down) {
1385 p.lineTo(width, offset);
1386 } else {
1387 p.lineTo(width, height - offset);
1388 }
1389 pathWidth = QPointF(0, -strokeWidth);
1390
1391 // Rotate for vertical.
1392 if (!isHorizontal) {
1393 for (int i = 0; i < p.elementCount(); i++) {
1394 p.setElementPositionAt(i, p.elementAt(i).y - (strokeWidth * 2), p.elementAt(i).x);
1395 }
1396 pathWidth = QPointF(strokeWidth, 0);
1397 }
1398 }
1399 return qMakePair(p, pathWidth);
1400}
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 857 of file KoSvgTextShape_p_layout.cpp.