Skip to content

Commit 78dd84b

Browse files
Merge pull request #22 from T-V-J/dev
Fractal Designer 6.0.9 Alpha
2 parents 161bcc4 + edcadec commit 78dd84b

File tree

333 files changed

+148601
-1021
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

333 files changed

+148601
-1021
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,9 @@ compile_commands.json
6060
/Outdated/
6161
/src/release/
6262
/src/debug/
63+
/tmp/
6364
!lib/qscintilla2_qt6.dll
64-
!lib/qscintilla2_qt6d.dll
65+
!lib/qscintilla2_qt6d.dll
66+
src/Fractal_Designer_resource.rc
67+
src/Fractal_Designer_resource.rc
68+
src/Fractal_Designer_resource.rc
File renamed without changes.

README.md

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,42 @@
1-
# Fractal_Designer
2-
This is an application to make fractal videos based on Qt(6.1.1), C++ and FFmpeg.
1+
# Fractal Designer
2+
This is an application to make fractal videos based on Qt(6.2.0), C++ and FFmpeg.
33

44
## Version Information
5-
This is version 5.6.3 updated in 2021/07/15.
6-
Beta version is now only available for Windows.
5+
This is version 6.0.9 updated in 2021/08/01.
6+
Current version is now only available for Windows.
77
Release for Linux will be published in the near future.
88

9-
## Main Features
10-
- You can create fractal images and videos at your command, with the freedom of designing colours and routes.
11-
- Equipped with the Route Tool, it is easy to find an appropriate route.
12-
- More functions are there to be discovered by you! For more information, you can find them in help.
13-
14-
## Tips
15-
- In this version, Fractal Designer is no longer compatible with previous versions.
16-
- You can report bugs if any.
17-
- Fractal Designer 5.6 is the LTS version.
18-
- **Help Documentation**
19-
- [Help (English Version)](https://frd.teddy-van-jerry.org/help/fractal-designer-5-6-lts-help)
20-
- [Help (Chinese Version)](https://frd.teddy-van-jerry.org/help/fractal-designer-5-6-lts-help-zh)
21-
- [Mandelbrot Sample](https://frd.teddy-van-jerry.org/sample/fractal-designer-5-6-lts-sample-1)
22-
- [Fractal Designer Website](https://frd.teddy-van-jerry.org)
23-
24-
## Username and Passcode
25-
You can use any of them to log in the application:
26-
27-
|Username|Passcode|
28-
|-|-|
29-
|CSDN|Southeast61|
30-
|GitHub|Southeast61|
31-
|SEU|SEU615205|
9+
Visit our [Fractal Designer Website](https://frd.teddy-van-jerry.org) for more information.
10+
11+
## Build the Project
12+
Besides the build version for Windows (using Qt 6.2.0), you can compile it yourself by following steps:
13+
14+
- Build project `include/qscintilla.pro` with both Debug and Release mode.
15+
Remember to uncheck *shadow build*.
16+
17+
- Open project `src/Fractal_Designer.pro` and *release translations* (lrelease).
18+
In Qt Creator, it is in `Tools->External->Qt Languist`.
19+
20+
- Build `src/Fractal_Designer.pro` with the same kit as that of building QScintilla.
21+
Also remember to uncheck *shadow build*.
22+
23+
- To distribute the project, you need to
24+
- Build in release mode.
25+
- Deploy with `windeployqt`, `macdeployqt`, `linuxdeployqt` or other methods to get the dependency files.
26+
- Copy the release dynamic library file of QScintilla (`qscintilla2_qt6.dll` in Windows) to directory `bin` and delete directory `lib`, `scintilla`, `include`, `tmp`.
27+
- Download [ffmpeg](http://www.ffmpeg.org/download.html) and put it in the right directory. (For Windows, it is `bin/win/ffmpeg.exe`.)
28+
29+
## Use Fractal Designer
30+
31+
Type `help` in the terminal to get the list of all commands supported by Fractal Designer 6.0.9.
32+
Use the sample file to have a quick look at how the `frd` language is like.
33+
Details about `frd` language will be updated in the near future.
34+
35+
## TODOs in Version 6.0
36+
- Validity Check in `frd` script.
37+
- Improve error indication of interpreter.
38+
- Add termination control in preview, creating images and creating video.
39+
- Add more terminal commands.
3240

3341
## Sample Videos
3442

bin/.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
/temp/
21
*.ini

include/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*.stash
2+
/debug/
3+
/release/
4+
Makefile
5+
*.Debug
6+
*.Release

include/InputMethod.cpp

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
// Copyright (c) 2021 Riverbank Computing Limited
2+
// Copyright (c) 2011 Archaeopteryx Software, Inc.
3+
// Copyright (c) 1990-2011, Scientific Toolworks, Inc.
4+
//
5+
// The License.txt file describes the conditions under which this software may
6+
// be distributed.
7+
8+
9+
#include <qglobal.h>
10+
11+
#include <QColor>
12+
#include <QFont>
13+
#include <QInputMethodEvent>
14+
#include <QRect>
15+
#include <QTextCharFormat>
16+
#include <QTextFormat>
17+
#include <QVariant>
18+
#include <QVarLengthArray>
19+
20+
#include "Qsci/qsciscintillabase.h"
21+
#include "ScintillaQt.h"
22+
23+
24+
#define INDIC_INPUTMETHOD 24
25+
26+
#define MAXLENINPUTIME 200
27+
#define SC_INDICATOR_INPUT INDIC_IME
28+
#define SC_INDICATOR_TARGET INDIC_IME+1
29+
#define SC_INDICATOR_CONVERTED INDIC_IME+2
30+
#define SC_INDICATOR_UNKNOWN INDIC_IME_MAX
31+
32+
33+
static bool IsHangul(const QChar qchar)
34+
{
35+
int unicode = (int)qchar.unicode();
36+
// Korean character ranges used for preedit chars.
37+
// http://www.programminginkorean.com/programming/hangul-in-unicode/
38+
const bool HangulJamo = (0x1100 <= unicode && unicode <= 0x11FF);
39+
const bool HangulCompatibleJamo = (0x3130 <= unicode && unicode <= 0x318F);
40+
const bool HangulJamoExtendedA = (0xA960 <= unicode && unicode <= 0xA97F);
41+
const bool HangulJamoExtendedB = (0xD7B0 <= unicode && unicode <= 0xD7FF);
42+
const bool HangulSyllable = (0xAC00 <= unicode && unicode <= 0xD7A3);
43+
return HangulJamo || HangulCompatibleJamo || HangulSyllable ||
44+
HangulJamoExtendedA || HangulJamoExtendedB;
45+
}
46+
47+
static void MoveImeCarets(QsciScintillaQt *sqt, int offset)
48+
{
49+
// Move carets relatively by bytes
50+
for (size_t r=0; r < sqt->sel.Count(); r++) {
51+
int positionInsert = sqt->sel.Range(r).Start().Position();
52+
sqt->sel.Range(r).caret.SetPosition(positionInsert + offset);
53+
sqt->sel.Range(r).anchor.SetPosition(positionInsert + offset);
54+
}
55+
}
56+
57+
static void DrawImeIndicator(QsciScintillaQt *sqt, int indicator, int len)
58+
{
59+
// Emulate the visual style of IME characters with indicators.
60+
// Draw an indicator on the character before caret by the character bytes of len
61+
// so it should be called after AddCharUTF().
62+
// It does not affect caret positions.
63+
if (indicator < 8 || indicator > INDIC_MAX) {
64+
return;
65+
}
66+
sqt->pdoc->DecorationSetCurrentIndicator(indicator);
67+
for (size_t r=0; r< sqt-> sel.Count(); r++) {
68+
int positionInsert = sqt->sel.Range(r).Start().Position();
69+
sqt->pdoc->DecorationFillRange(positionInsert - len, 1, len);
70+
}
71+
}
72+
73+
static int GetImeCaretPos(QInputMethodEvent *event)
74+
{
75+
foreach (QInputMethodEvent::Attribute attr, event->attributes()) {
76+
if (attr.type == QInputMethodEvent::Cursor)
77+
return attr.start;
78+
}
79+
return 0;
80+
}
81+
82+
static std::vector<int> MapImeIndicators(QInputMethodEvent *event)
83+
{
84+
std::vector<int> imeIndicator(event->preeditString().size(), SC_INDICATOR_UNKNOWN);
85+
foreach (QInputMethodEvent::Attribute attr, event->attributes()) {
86+
if (attr.type == QInputMethodEvent::TextFormat) {
87+
QTextFormat format = attr.value.value<QTextFormat>();
88+
QTextCharFormat charFormat = format.toCharFormat();
89+
90+
int indicator = SC_INDICATOR_UNKNOWN;
91+
switch (charFormat.underlineStyle()) {
92+
case QTextCharFormat::NoUnderline: // win32, linux
93+
indicator = SC_INDICATOR_TARGET;
94+
break;
95+
case QTextCharFormat::SingleUnderline: // osx
96+
case QTextCharFormat::DashUnderline: // win32, linux
97+
indicator = SC_INDICATOR_INPUT;
98+
break;
99+
case QTextCharFormat::DotLine:
100+
case QTextCharFormat::DashDotLine:
101+
case QTextCharFormat::WaveUnderline:
102+
case QTextCharFormat::SpellCheckUnderline:
103+
indicator = SC_INDICATOR_CONVERTED;
104+
break;
105+
106+
default:
107+
indicator = SC_INDICATOR_UNKNOWN;
108+
}
109+
110+
if (format.hasProperty(QTextFormat::BackgroundBrush)) // win32, linux
111+
indicator = SC_INDICATOR_TARGET;
112+
113+
#ifdef Q_OS_OSX
114+
if (charFormat.underlineStyle() == QTextCharFormat::SingleUnderline) {
115+
QColor uc = charFormat.underlineColor();
116+
if (uc.lightness() < 2) { // osx
117+
indicator = SC_INDICATOR_TARGET;
118+
}
119+
}
120+
#endif
121+
122+
for (int i = attr.start; i < attr.start+attr.length; i++) {
123+
imeIndicator[i] = indicator;
124+
}
125+
}
126+
}
127+
return imeIndicator;
128+
}
129+
130+
void QsciScintillaBase::inputMethodEvent(QInputMethodEvent *event)
131+
{
132+
// Copy & paste by johnsonj with a lot of helps of Neil
133+
// Great thanks for my forerunners, jiniya and BLUEnLIVE
134+
135+
if (sci->pdoc->IsReadOnly() || sci->SelectionContainsProtected()) {
136+
// Here, a canceling and/or completing composition function is needed.
137+
return;
138+
}
139+
140+
if (sci->pdoc->TentativeActive()) {
141+
sci->pdoc->TentativeUndo();
142+
} else {
143+
// No tentative undo means start of this composition so
144+
// Fill in any virtual spaces.
145+
sci->ClearBeforeTentativeStart();
146+
}
147+
148+
sci->view.imeCaretBlockOverride = false;
149+
150+
if (!event->commitString().isEmpty()) {
151+
const QString commitStr = event->commitString();
152+
const unsigned int commitStrLen = commitStr.length();
153+
154+
for (unsigned int i = 0; i < commitStrLen;) {
155+
const unsigned int ucWidth = commitStr.at(i).isHighSurrogate() ? 2 : 1;
156+
const QString oneCharUTF16 = commitStr.mid(i, ucWidth);
157+
const QByteArray oneChar = textAsBytes(oneCharUTF16);
158+
const int oneCharLen = oneChar.length();
159+
160+
sci->AddCharUTF(oneChar.data(), oneCharLen);
161+
i += ucWidth;
162+
}
163+
164+
} else if (!event->preeditString().isEmpty()) {
165+
const QString preeditStr = event->preeditString();
166+
const unsigned int preeditStrLen = preeditStr.length();
167+
if ((preeditStrLen == 0) || (preeditStrLen > MAXLENINPUTIME)) {
168+
sci->ShowCaretAtCurrentPosition();
169+
return;
170+
}
171+
172+
sci->pdoc->TentativeStart(); // TentativeActive() from now on.
173+
174+
std::vector<int> imeIndicator = MapImeIndicators(event);
175+
176+
const bool recording = sci->recordingMacro;
177+
sci->recordingMacro = false;
178+
for (unsigned int i = 0; i < preeditStrLen;) {
179+
const unsigned int ucWidth = preeditStr.at(i).isHighSurrogate() ? 2 : 1;
180+
const QString oneCharUTF16 = preeditStr.mid(i, ucWidth);
181+
const QByteArray oneChar = textAsBytes(oneCharUTF16);
182+
const int oneCharLen = oneChar.length();
183+
184+
sci->AddCharUTF(oneChar.data(), oneCharLen);
185+
186+
DrawImeIndicator(sci, imeIndicator[i], oneCharLen);
187+
i += ucWidth;
188+
}
189+
sci->recordingMacro = recording;
190+
191+
// Move IME carets.
192+
int imeCaretPos = GetImeCaretPos(event);
193+
int imeEndToImeCaretU16 = imeCaretPos - preeditStrLen;
194+
int imeCaretPosDoc = sci->pdoc->GetRelativePositionUTF16(sci->CurrentPosition(), imeEndToImeCaretU16);
195+
196+
MoveImeCarets(sci, - sci->CurrentPosition() + imeCaretPosDoc);
197+
198+
if (IsHangul(preeditStr.at(0))) {
199+
#ifndef Q_OS_WIN
200+
if (imeCaretPos > 0) {
201+
int oneCharBefore = sci->pdoc->GetRelativePosition(sci->CurrentPosition(), -1);
202+
MoveImeCarets(sci, - sci->CurrentPosition() + oneCharBefore);
203+
}
204+
#endif
205+
sci->view.imeCaretBlockOverride = true;
206+
}
207+
208+
// Set candidate box position for Qt::ImCursorRectangle.
209+
preeditPos = sci->CurrentPosition();
210+
sci->EnsureCaretVisible();
211+
updateMicroFocus();
212+
}
213+
sci->ShowCaretAtCurrentPosition();
214+
}
215+
216+
QVariant QsciScintillaBase::inputMethodQuery(Qt::InputMethodQuery query) const
217+
{
218+
int pos = SendScintilla(SCI_GETCURRENTPOS);
219+
int line = SendScintilla(SCI_LINEFROMPOSITION, pos);
220+
221+
switch (query) {
222+
case Qt::ImHints:
223+
return QWidget::inputMethodQuery(query);
224+
225+
case Qt::ImCursorRectangle:
226+
{
227+
int startPos = (preeditPos >= 0) ? preeditPos : pos;
228+
Scintilla::Point pt = sci->LocationFromPosition(startPos);
229+
int width = SendScintilla(SCI_GETCARETWIDTH);
230+
int height = SendScintilla(SCI_TEXTHEIGHT, line);
231+
return QRect(pt.x, pt.y, width, height);
232+
}
233+
234+
case Qt::ImFont:
235+
{
236+
char fontName[64];
237+
int style = SendScintilla(SCI_GETSTYLEAT, pos);
238+
int len = SendScintilla(SCI_STYLEGETFONT, style, (sptr_t)fontName);
239+
int size = SendScintilla(SCI_STYLEGETSIZE, style);
240+
bool italic = SendScintilla(SCI_STYLEGETITALIC, style);
241+
int weight = SendScintilla(SCI_STYLEGETBOLD, style) ? QFont::Bold : -1;
242+
return QFont(QString::fromUtf8(fontName, len), size, weight, italic);
243+
}
244+
245+
case Qt::ImCursorPosition:
246+
{
247+
int paraStart = sci->pdoc->ParaUp(pos);
248+
return pos - paraStart;
249+
}
250+
251+
case Qt::ImSurroundingText:
252+
{
253+
int paraStart = sci->pdoc->ParaUp(pos);
254+
int paraEnd = sci->pdoc->ParaDown(pos);
255+
QVarLengthArray<char,1024> buffer(paraEnd - paraStart + 1);
256+
257+
Sci_CharacterRange charRange;
258+
charRange.cpMin = paraStart;
259+
charRange.cpMax = paraEnd;
260+
261+
Sci_TextRange textRange;
262+
textRange.chrg = charRange;
263+
textRange.lpstrText = buffer.data();
264+
265+
SendScintilla(SCI_GETTEXTRANGE, 0, (sptr_t)&textRange);
266+
267+
return bytesAsText(buffer.constData());
268+
}
269+
270+
case Qt::ImCurrentSelection:
271+
{
272+
QVarLengthArray<char,1024> buffer(SendScintilla(SCI_GETSELTEXT));
273+
SendScintilla(SCI_GETSELTEXT, 0, (sptr_t)buffer.data());
274+
275+
return bytesAsText(buffer.constData());
276+
}
277+
278+
default:
279+
return QVariant();
280+
}
281+
}

0 commit comments

Comments
 (0)