Basic drawing script parsing and execution is working.
This commit is contained in:
parent
e49b5793fc
commit
7551144902
5 changed files with 247 additions and 65 deletions
|
@ -26,11 +26,13 @@ project(joeydev C)
|
|||
set(CMAKE_C_STANDARD 99)
|
||||
|
||||
set(SOURCE_FILES
|
||||
src/main.c
|
||||
src/utils.c
|
||||
src/joeydev.c
|
||||
src/vector.c
|
||||
src/array.c src/draw.c)
|
||||
src/main.c
|
||||
src/utils.c
|
||||
src/joeydev.c
|
||||
src/vector.c
|
||||
src/array.c
|
||||
src/draw.c
|
||||
)
|
||||
|
||||
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})
|
||||
|
||||
|
|
35
include/scintillaHeaders.h
Normal file
35
include/scintillaHeaders.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* JoeyDev
|
||||
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SCINTILLAHEADERS_H
|
||||
#define SCINTILLAHEADERS_H
|
||||
|
||||
|
||||
#define PLAT_GTK 1
|
||||
#define GTK 3
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
#include "ScintillaWidget.h"
|
||||
#include "Lexilla.h"
|
||||
|
||||
|
||||
#endif //SCINTILLAHEADERS_H
|
21
src/draw.c
21
src/draw.c
|
@ -352,11 +352,11 @@ void jlDrawLine(jlContextT *c, jint16 x1, jint16 y1, jint16 x2, jint16 y2) {
|
|||
|
||||
|
||||
jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) {
|
||||
int offset = (x + y * 320) * 4;
|
||||
int r = c->_pixels[offset + 1];
|
||||
int g = c->_pixels[offset + 2];
|
||||
int b = c->_pixels[offset + 3];
|
||||
int index = 0;
|
||||
unsigned int offset = (x + y * 320) * 4;
|
||||
int r = c->_pixels[offset + 2];
|
||||
int g = c->_pixels[offset + 1];
|
||||
int b = c->_pixels[offset];
|
||||
int index = 0;
|
||||
int i;
|
||||
|
||||
// Find the palette index for this color.
|
||||
|
@ -372,12 +372,13 @@ jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) {
|
|||
|
||||
|
||||
void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y) {
|
||||
int offset = (x + y * 320) * 4;
|
||||
unsigned int offset = (x + y * 320) * 4;
|
||||
|
||||
c->_pixels[offset] = 255;
|
||||
c->_pixels[offset + 1] = c->_jlPalette[c->_jlDrawColor].r;
|
||||
c->_pixels[offset + 2] = c->_jlPalette[c->_jlDrawColor].g;
|
||||
c->_pixels[offset + 3] = c->_jlPalette[c->_jlDrawColor].b;
|
||||
c->_pixels[offset] = c->_jlPalette[c->_jlDrawColor].b;
|
||||
c->_pixels[offset + 1] = c->_jlPalette[c->_jlDrawColor].g;
|
||||
c->_pixels[offset + 2] = c->_jlPalette[c->_jlDrawColor].r;
|
||||
// We're using CAIRO_FORMAT_RGB24 so the upper 8 bits are not used.
|
||||
//c->_pixels[offset + 3] = 255; // This is alpha in CAIRO_FORMAT_ARGB32 mode.
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
|
||||
#include "common.h"
|
||||
#include "scintillaHeaders.h"
|
||||
#include "joeydev.h"
|
||||
#include "stddclmr.h"
|
||||
|
||||
|
@ -30,6 +31,7 @@ int main(int argc, char **argv) {
|
|||
gtk_init(&argc, &argv);
|
||||
winJoeyDevCreate();
|
||||
gtk_main();
|
||||
scintilla_release_resources();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
242
src/vector.c
242
src/vector.c
|
@ -28,14 +28,7 @@
|
|||
#include "common.h"
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define PLAT_GTK 1
|
||||
#define GTK 3
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
#include "ScintillaWidget.h"
|
||||
#include "Lexilla.h"
|
||||
|
||||
#include "scintillaHeaders.h"
|
||||
#include "gladeVector.h"
|
||||
#include "vector.h"
|
||||
#include "utils.h"
|
||||
|
@ -44,6 +37,8 @@
|
|||
|
||||
#define SSM(m, w, l) scintilla_send_message(self->sci, m, w, l)
|
||||
#define MARGIN_SCRIPT_FOLD_INDEX 1
|
||||
#define MARKER_ERROR_ARROW 0
|
||||
#define MARKER_ERROR_HIGHLIGHT 1
|
||||
|
||||
|
||||
enum PassE {
|
||||
|
@ -74,6 +69,12 @@ typedef struct CommandsS {
|
|||
} CommandsT;
|
||||
|
||||
|
||||
typedef struct PointS {
|
||||
int x;
|
||||
int y;
|
||||
} PointT;
|
||||
|
||||
|
||||
static int _nextEditorId = 0;
|
||||
|
||||
|
||||
|
@ -82,27 +83,30 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCN
|
|||
EVENT void menuVectorFileClose(GtkWidget *object, gpointer userData);
|
||||
static gboolean parseBox(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseCircle(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseClear(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseColor(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseComment(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseEllipse(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseFill(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseLine(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parsePalette(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parsePlot(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseRectangle(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static gboolean parseReset(PassT pass, char **tokenEnd, VectorDataT *self);
|
||||
static void parser(PassT pass, gpointer userData);
|
||||
static gboolean parserGetNextValue(char *token, char **valueEnd, int *x);
|
||||
static gboolean parserGetWord(char *word, char **tokenEnd);
|
||||
static gboolean parserGetX(char **tokenEnd, int *x);
|
||||
static gboolean parserGetXY(char **tokenEnd, int *x, int *y);
|
||||
static gboolean parserGetXYZ(char **tokenEnd, int *x, int *y, int *z);
|
||||
EVENT gboolean winVectorClose(GtkWidget *object, gpointer userData);
|
||||
static void winVectorDelete(gpointer userData);
|
||||
|
||||
|
||||
EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
cairo_surface_t *target = cairo_get_target(cr);
|
||||
int width = cairo_image_surface_get_width(target);
|
||||
int height = cairo_image_surface_get_height(target);
|
||||
int width = cairo_image_surface_get_width(self->surface);
|
||||
int height = cairo_image_surface_get_height(self->surface);
|
||||
|
||||
(void)widget;
|
||||
(void)userData;
|
||||
|
@ -118,39 +122,36 @@ EVENT gboolean drawVectorImageDraw(GtkWidget *widget, cairo_t *cr, gpointer user
|
|||
|
||||
cairo_surface_flush(self->surface);
|
||||
|
||||
printf("Redrew image\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotification *notifyData, gpointer userData) {
|
||||
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position , (sptr_t)0);
|
||||
int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position, (sptr_t)0);
|
||||
|
||||
(void)sciWidget;
|
||||
(void)ctrlID;
|
||||
|
||||
//printf("Notification %d\n", notifyData->nmhdr.code);
|
||||
//printf("Notification %d\n", notifyData->modificationType);
|
||||
|
||||
switch (notifyData->nmhdr.code) {
|
||||
case SCN_CHARADDED:
|
||||
parser(PASS_DRAW, userData);
|
||||
gtk_widget_queue_draw(self->drawVectorImage);
|
||||
break;
|
||||
|
||||
case SCN_SAVEPOINTLEFT:
|
||||
self->windowData.isDirty = TRUE; //***TODO*** I don't think this is very accurate.
|
||||
break;
|
||||
|
||||
case SCN_SAVEPOINTREACHED:
|
||||
self->windowData.isDirty = FALSE;
|
||||
case SCN_MODIFIED:
|
||||
if (notifyData->modificationType & SC_MOD_INSERTTEXT || notifyData->modificationType & SC_MOD_DELETETEXT) {
|
||||
// Parse code.
|
||||
parser(PASS_DRAW, userData);
|
||||
// Refresh widget.
|
||||
gtk_widget_queue_draw(self->drawVectorImage);
|
||||
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
|
||||
self->windowData.isDirty = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCN_MARGINCLICK:
|
||||
switch (notifyData->margin) {
|
||||
case MARGIN_SCRIPT_FOLD_INDEX:
|
||||
SSM(SCI_TOGGLEFOLD, lineNumber, (sptr_t)0);
|
||||
SSM(SCI_TOGGLEFOLD, lineNumber, (sptr_t) 0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -177,6 +178,8 @@ static gboolean parseBox(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (!parserGetWord("TO", tokenEnd)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &x2, &y2)) return FALSE;
|
||||
if (x2 < x1 || x1 < 0 || x2 < 0 || x1 > 319 || x2 > 319) return FALSE;
|
||||
if (y2 < y1 || y1 < 0 || y2 < 0 || y1 > 199 || y2 > 199) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -200,6 +203,8 @@ static gboolean parseCircle(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
if (!parserGetX(tokenEnd, &r)) return FALSE;
|
||||
if (!parserGetWord("AT", tokenEnd)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (x1 < 0 || x1 > 319) return FALSE;
|
||||
if (y1 < 0 || y1 > 199) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -214,12 +219,27 @@ static gboolean parseCircle(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
}
|
||||
|
||||
|
||||
static gboolean parseClear(PassT pass, char **tokenEnd, VectorDataT *self) {
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
jlDrawClear(self->jlc);
|
||||
break;
|
||||
|
||||
case PASS_GENERATE:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean parseColor(PassT pass, char **tokenEnd, VectorDataT *self) {
|
||||
int c;
|
||||
|
||||
// Color (short)
|
||||
|
||||
if (!parserGetX(tokenEnd, &c)) return FALSE;
|
||||
if (c < 0 || c > 15) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -256,6 +276,8 @@ static gboolean parseEllipse(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (!parserGetWord("TO", tokenEnd)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &x2, &y2)) return FALSE;
|
||||
if (x2 < x1 || x1 < 0 || x2 < 0 || x1 > 319 || x2 > 319) return FALSE;
|
||||
if (y2 < y1 || y1 < 0 || y2 < 0 || y1 > 199 || y2 > 199) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -271,10 +293,27 @@ static gboolean parseEllipse(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
|
||||
|
||||
static gboolean parseFill(PassT pass, char **tokenEnd, VectorDataT *self) {
|
||||
// Fill (on|to) (value),(value)
|
||||
int c = 16;
|
||||
int x1;
|
||||
int y1;
|
||||
|
||||
// Fill (value),(value) {to (value}
|
||||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (x1 < 0 || x1 > 319) return FALSE;
|
||||
if (y1 < 0 || y1 > 199) return FALSE;
|
||||
// Do they want to fill to a certain color? Or over the current color?
|
||||
if (parserGetWord("TO", tokenEnd)) {
|
||||
if (!parserGetX(tokenEnd, &c)) return FALSE;
|
||||
if (c < 0 || c > 15) return FALSE;
|
||||
}
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
if (c > 15) {
|
||||
jlDrawFill(self->jlc, x1, y1);
|
||||
} else {
|
||||
jlDrawFillTo(self->jlc, x1, y1, c);
|
||||
}
|
||||
break;
|
||||
|
||||
case PASS_GENERATE:
|
||||
|
@ -286,13 +325,67 @@ static gboolean parseFill(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
|
||||
|
||||
static gboolean parseLine(PassT pass, char **tokenEnd, VectorDataT *self) {
|
||||
int x;
|
||||
PointT p1;
|
||||
PointT p2;
|
||||
PointT *points = NULL;
|
||||
|
||||
// Line (value),(value) to (value),(value) [to ...]
|
||||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &p1.x, &p1.y)) return FALSE;
|
||||
if (!parserGetWord("TO", tokenEnd)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &x2, &y2)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &p2.x, &p2.y)) return FALSE;
|
||||
if (p1.x < 0 || p1.x > 319) return FALSE;
|
||||
if (p1.y < 0 || p1.y > 199) return FALSE;
|
||||
if (p2.x < 0 || p2.x > 319) return FALSE;
|
||||
if (p2.y < 0 || p2.y > 199) return FALSE;
|
||||
arrput(points, p1);
|
||||
arrput(points, p2);
|
||||
while (parserGetWord("TO", tokenEnd)) {
|
||||
if (!parserGetXY(tokenEnd, &p1.x, &p1.y)) {
|
||||
// Error. Unwind array.
|
||||
while (arrlen(points) > 0) arrdel(points, 0);
|
||||
arrfree(points);
|
||||
return FALSE;
|
||||
}
|
||||
arrput(points, p1);
|
||||
}
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
for (x=0; x<arrlen(points)-1; x++) {
|
||||
jlDrawLine(self->jlc, points[x].x, points[x].y, points[x+1].x, points[x+1].y);
|
||||
}
|
||||
break;
|
||||
|
||||
case PASS_GENERATE:
|
||||
break;
|
||||
}
|
||||
|
||||
// Unwind array.
|
||||
while (arrlen(points) > 0) arrdel(points, 0);
|
||||
arrfree(points);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean parsePalette(PassT pass, char **tokenEnd, VectorDataT *self) {
|
||||
int i;
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
|
||||
if (!parserGetX(tokenEnd, &i)) return FALSE;
|
||||
if (!parserGetWord("AS", tokenEnd)) return FALSE;
|
||||
if (!parserGetXYZ(tokenEnd, &r, &g, &b)) return FALSE;
|
||||
if (i < 0 || i > 15) return FALSE;
|
||||
if (r < 0 || r > 15) return FALSE;
|
||||
if (g < 0 || g > 15) return FALSE;
|
||||
if (b < 0 || b > 15) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
jlPaletteSet(self->jlc, i, r, g, b);
|
||||
break;
|
||||
|
||||
case PASS_GENERATE:
|
||||
|
@ -309,6 +402,8 @@ static gboolean parsePlot(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
|
||||
// Plot (value),(value)
|
||||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (x1 < 0 || x1 > 319) return FALSE;
|
||||
if (y1 < 0 || y1 > 199) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -333,6 +428,8 @@ static gboolean parseRectangle(PassT pass, char **tokenEnd, VectorDataT *self) {
|
|||
if (!parserGetXY(tokenEnd, &x1, &y1)) return FALSE;
|
||||
if (!parserGetWord("TO", tokenEnd)) return FALSE;
|
||||
if (!parserGetXY(tokenEnd, &x2, &y2)) return FALSE;
|
||||
if (x2 < x1 || x1 < 0 || x2 < 0 || x1 > 319 || x2 > 319) return FALSE;
|
||||
if (y2 < y1 || y1 < 0 || y2 < 0 || y1 > 199 || y2 > 199) return FALSE;
|
||||
|
||||
switch (pass) {
|
||||
case PASS_DRAW:
|
||||
|
@ -373,6 +470,7 @@ static void parser(PassT pass, gpointer userData) {
|
|||
VectorDataT *self = (VectorDataT *)userData;
|
||||
int length = SSM(SCI_GETLENGTH, 0, 0);
|
||||
int x;
|
||||
int lineNumber = 0;
|
||||
char *code;
|
||||
char *line;
|
||||
char *lineEnd;
|
||||
|
@ -382,11 +480,13 @@ static void parser(PassT pass, gpointer userData) {
|
|||
CommandsT commands[] = {
|
||||
{ "BOX", parseBox },
|
||||
{ "CIRCLE", parseCircle },
|
||||
{ "CLEAR", parseClear },
|
||||
{ "COLOR", parseColor },
|
||||
{ "//", parseComment },
|
||||
{ "ELLIPSE", parseEllipse },
|
||||
{ "FILL", parseFill },
|
||||
{ "LINE", parseLine },
|
||||
{ "PALETTE", parsePalette },
|
||||
{ "PLOT", parsePlot },
|
||||
{ "RECTANGLE", parseRectangle },
|
||||
{ "RESET", parseReset },
|
||||
|
@ -400,6 +500,12 @@ static void parser(PassT pass, gpointer userData) {
|
|||
// Fetch code.
|
||||
SSM(SCI_GETTEXT, length, (sptr_t)code);
|
||||
|
||||
if (pass == PASS_DRAW) {
|
||||
// Clear error markers.
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0);
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0);
|
||||
}
|
||||
|
||||
// Parse code.
|
||||
line = strtok_r(code, "\n", &lineEnd);
|
||||
while (line != NULL) {
|
||||
|
@ -417,11 +523,14 @@ static void parser(PassT pass, gpointer userData) {
|
|||
}
|
||||
x++;
|
||||
}
|
||||
if (lineOkay == FALSE) {
|
||||
//***TODO*** Mark lines that fail to parse.
|
||||
if (lineOkay == FALSE && pass == PASS_DRAW) {
|
||||
// Mark lines that fail to parse.
|
||||
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_ARROW);
|
||||
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_HIGHLIGHT);
|
||||
}
|
||||
// Move to next line.
|
||||
line = strtok_r(NULL, "\n", &lineEnd);
|
||||
lineNumber++;
|
||||
}
|
||||
|
||||
// Release code.
|
||||
|
@ -450,6 +559,24 @@ static void parser(PassT pass, gpointer userData) {
|
|||
*/
|
||||
}
|
||||
|
||||
|
||||
static gboolean parserGetNextValue(char *token, char **valueEnd, int *x) {
|
||||
char *value;
|
||||
char *endPtr = NULL;
|
||||
|
||||
// Return next value in a comma separated list.
|
||||
//***TODO*** Variable support.
|
||||
|
||||
value = strtok_r(token, ",", valueEnd);
|
||||
if (value == NULL) return FALSE;
|
||||
errno = 0; endPtr = NULL;
|
||||
*x = (int)strtol(value, &endPtr, 10);
|
||||
if (errno != 0) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean parserGetWord(char *word, char **tokenEnd) {
|
||||
char *token;
|
||||
|
||||
|
@ -482,27 +609,32 @@ static gboolean parserGetX(char **tokenEnd, int *x) {
|
|||
|
||||
static gboolean parserGetXY(char **tokenEnd, int *x, int *y) {
|
||||
char *token;
|
||||
char *value;
|
||||
char *valueEnd;
|
||||
char *endPtr;
|
||||
|
||||
// Return values of X,Y pair.
|
||||
//***TODO*** Variable support.
|
||||
|
||||
token = strtok_r(NULL, " ", tokenEnd);
|
||||
if (token == NULL) return FALSE;
|
||||
|
||||
value = strtok_r(token, ",", &valueEnd);
|
||||
if (value == NULL) return FALSE;
|
||||
errno = 0; endPtr = NULL;
|
||||
*x = (int)strtol(value, &endPtr, 10);
|
||||
if (errno != 0) return FALSE;
|
||||
if (!parserGetNextValue(token, &valueEnd, x)) return FALSE;
|
||||
if (!parserGetNextValue(NULL, &valueEnd, y)) return FALSE;
|
||||
|
||||
value = strtok_r(NULL, ",", &valueEnd);
|
||||
if (value == NULL) return FALSE;
|
||||
errno = 0; endPtr = NULL;
|
||||
*y = (int)strtol(value, &endPtr, 10);
|
||||
if (errno != 0) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean parserGetXYZ(char **tokenEnd, int *x, int *y, int *z) {
|
||||
char *token;
|
||||
char *valueEnd;
|
||||
|
||||
// Return values of X,Y pair.
|
||||
|
||||
token = strtok_r(NULL, " ", tokenEnd);
|
||||
if (token == NULL) return FALSE;
|
||||
|
||||
if (!parserGetNextValue(token, &valueEnd, x)) return FALSE;
|
||||
if (!parserGetNextValue(NULL, &valueEnd, y)) return FALSE;
|
||||
if (!parserGetNextValue(NULL, &valueEnd, z)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -560,8 +692,8 @@ void winVectorCreate(void) {
|
|||
SSM(SCI_STYLESETBACK, STYLE_DEFAULT, 0);
|
||||
SSM(SCI_STYLECLEARALL, 0, 0);
|
||||
SSM(SCI_SETTABWIDTH, 3, 0);
|
||||
SSM(SCI_SETMARGINWIDTHN, 0, (int)SSM(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"99999"));
|
||||
SSM(SCI_SETMARGINWIDTHN, 1, 0);
|
||||
SSM(SCI_SETMARGINWIDTHN, 0, (int)SSM(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999"));
|
||||
SSM(SCI_SETMARGINWIDTHN, 1, 16);
|
||||
SSM(SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
|
||||
SSM(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END, 0);
|
||||
SSM(SCI_SETWRAPINDENTMODE, SC_WRAPINDENT_INDENT, 0);
|
||||
|
@ -584,18 +716,25 @@ void winVectorCreate(void) {
|
|||
SSM(SCI_STYLESETFORE, SCE_C_STRING, 0xFF00FF);
|
||||
SSM(SCI_STYLESETBOLD, SCE_C_OPERATOR, 1);
|
||||
|
||||
// Margin markers.
|
||||
SSM(SCI_MARKERDEFINE, MARKER_ERROR_ARROW, SC_MARK_SHORTARROW); // Error
|
||||
SSM(SCI_MARKERSETBACK, MARKER_ERROR_ARROW, 255 | (0 << 8) | (0 << 16)); // RGB
|
||||
SSM(SCI_MARKERDEFINE, MARKER_ERROR_HIGHLIGHT, SC_MARK_BACKGROUND); // Error
|
||||
SSM(SCI_MARKERSETBACK, MARKER_ERROR_HIGHLIGHT, 127 | (0 << 8) | (0 << 16)); // RGB
|
||||
|
||||
// Debug
|
||||
SSM(SCI_INSERTTEXT, 0, (sptr_t)
|
||||
"reset\n"
|
||||
"palette 15 as 15,0,0\n"
|
||||
"color 15\n"
|
||||
"box 0,0 to 319,299\n"
|
||||
"box 0,0 to 319,199\n"
|
||||
);
|
||||
|
||||
// Connect editor to our code.
|
||||
g_signal_connect(G_OBJECT(self->editor), "sci-notify", G_CALLBACK(editorVectorNotify), self);
|
||||
|
||||
// Create our drawing surface and context.
|
||||
self->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 320, 200);
|
||||
self->surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 320, 200);
|
||||
self->cr = cairo_create(self->surface);
|
||||
cairo_surface_flush(self->surface);
|
||||
self->surfacePointer = cairo_image_surface_get_data(self->surface);
|
||||
|
@ -610,6 +749,9 @@ void winVectorCreate(void) {
|
|||
static void winVectorDelete(gpointer userData) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
|
||||
// Scintilla keeps sending events after we delete things it expects to still exist. Prevent that.
|
||||
g_signal_handlers_disconnect_by_func(G_OBJECT(self->editor), G_CALLBACK(editorVectorNotify), self);
|
||||
|
||||
utilWindowUnRegister(userData);
|
||||
|
||||
jlContextDel(&self->jlc);
|
||||
|
|
Loading…
Add table
Reference in a new issue