Merge branch 'scintilla-update'

This commit is contained in:
Colomban Wendling 2011-10-22 23:28:46 +02:00
commit a0367acd2d
60 changed files with 4236 additions and 1422 deletions

6
NEWS
View File

@ -1,3 +1,9 @@
Geany 1.22 (unreleased)
Editor
* Update Scintilla to version 2.29.
Geany 0.21 (October 2, 2011)
General

View File

@ -6,6 +6,15 @@ command=keyword_1
tag=tag
math=number_1
comment=comment
# mappings below may need checking
tag2=tag
math2=number_1
comment2=comment
verbatim=default
shortcmd=keyword_1
special=keyword_2
cmdopt=keyword_1
error=error
[keywords]
# all items must be in one line

View File

@ -21,6 +21,7 @@ word5=keyword_1
word6=keyword_2
word7=keyword_3
word8=keyword_4
label=label
[keywords]
# all items must be in one line

View File

@ -31,6 +31,18 @@ string_qx=string_2
string_qr=string_2
string_qw=string_2
variable_indexer=default
# *_var mappings may need checking
string_var=identifier_1
regex_var=identifier_2
regsubst_var=identifier_2
backticks_var=identifier_2
here_qq_var=identifier_2
here_qx_var=identifier_2
string_qq_var=identifier_2
string_qx_var=identifier_2
string_qr_var=identifier_2
# translation: tr{}{} y{}{}
xlat=string_2
# not used
punctuation=default
# obsolete: replaced by qq, qx, qr, qw

View File

@ -9,6 +9,9 @@
#include <stddef.h>
#include <math.h>
#include <vector>
#include <map>
#include <glib.h>
#include <gmodule.h>
#include <gdk/gdk.h>
@ -40,9 +43,37 @@
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
#endif
#if GTK_CHECK_VERSION(2,22,0)
#define USE_CAIRO 1
#ifdef USE_CAIRO
static cairo_surface_t *CreateSimilarSurface(GdkWindow *window, cairo_content_t content, int width, int height) {
#if GTK_CHECK_VERSION(2,22,0)
return gdk_window_create_similar_surface(window, content, width, height);
#else
cairo_surface_t *window_surface, *surface;
g_return_val_if_fail(GDK_IS_WINDOW(window), NULL);
window_surface = GDK_DRAWABLE_GET_CLASS(window)->ref_cairo_surface(window);
surface = cairo_surface_create_similar(window_surface, content, width, height);
cairo_surface_destroy(window_surface);
return surface;
#endif
}
#endif
static GdkWindow *WindowFromWidget(GtkWidget *w) {
#if GTK_CHECK_VERSION(3,0,0)
return gtk_widget_get_window(w);
#else
return w->window;
#endif
}
#ifdef USE_CAIRO
#define DISABLE_GDK_FONT 1
@ -116,10 +147,17 @@ class FontHandle {
encodingType et;
public:
int ascent;
#ifndef DISABLE_GDK_FONT
GdkFont *pfont;
#endif
PangoFontDescription *pfd;
int characterSet;
FontHandle(GdkFont *pfont_) {
#ifdef DISABLE_GDK_FONT
FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
ResetWidths(et);
}
#else
FontHandle(GdkFont *pfont_=0) {
et = singleByte;
ascent = 0;
pfont = pfont_;
@ -127,10 +165,13 @@ public:
characterSet = -1;
ResetWidths(et);
}
#endif
FontHandle(PangoFontDescription *pfd_, int characterSet_) {
et = singleByte;
ascent = 0;
#ifndef DISABLE_GDK_FONT
pfont = 0;
#endif
pfd = pfd_;
characterSet = characterSet_;
ResetWidths(et);
@ -139,8 +180,8 @@ public:
#ifndef DISABLE_GDK_FONT
if (pfont)
gdk_font_unref(pfont);
#endif
pfont = 0;
#endif
if (pfd)
pango_font_description_free(pfd);
pfd = 0;
@ -183,9 +224,11 @@ static GtkWidget *PWidget(WindowID wid) {
return reinterpret_cast<GtkWidget *>(wid);
}
#if !GTK_CHECK_VERSION(3,0,0)
static GtkWidget *PWidget(Window &w) {
return PWidget(w.GetID());
}
#endif
Point Point::FromLong(long lpoint) {
return Point(
@ -254,6 +297,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
}
void Palette::Allocate(Window &w) {
#if !GTK_CHECK_VERSION(3,0,0)
// Disable palette on GTK+ 3.
if (allocatedPalette) {
gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
reinterpret_cast<GdkColor *>(allocatedPalette),
@ -274,14 +319,17 @@ void Palette::Allocate(Window &w) {
paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255);
paletteNew[iPal].pixel = entries[iPal].desired.AsLong();
}
#ifndef USE_CAIRO
gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)),
paletteNew, allocatedLen, FALSE, TRUE,
successPalette);
#endif
for (iPal = 0; iPal < used; iPal++) {
entries[iPal].allocated.Set(paletteNew[iPal].pixel);
}
}
delete []successPalette;
#endif
}
#ifndef DISABLE_GDK_FONT
@ -671,7 +719,7 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
}
return new FontHandle(newid);
#else
return new FontHandle(0);
return new FontHandle();
#endif
}
@ -695,6 +743,8 @@ void Font::Release() {
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
class SurfaceImpl : public Surface {
encodingType et;
#ifdef USE_CAIRO
@ -736,6 +786,7 @@ public:
void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags);
void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage);
void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back);
void Copy(PRectangle rc, Point from, Surface &surfaceSource);
@ -883,7 +934,11 @@ void SurfaceImpl::Init(WindowID wid) {
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
#if GTK_CHECK_VERSION(3,0,0)
GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
#else
GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
#endif
if (drawable_) {
context = gdk_cairo_create(drawable_);
PLATFORM_ASSERT(context);
@ -904,14 +959,17 @@ void SurfaceImpl::Init(WindowID wid) {
void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(sid);
GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
Release();
PLATFORM_ASSERT(wid);
#ifdef USE_CAIRO
context = gdk_cairo_create(drawable_);
#if GTK_CHECK_VERSION(3,0,0)
context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
#else
gc = gdk_gc_new(drawable_);
drawable = drawable_;
context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
#endif
#else
drawable = reinterpret_cast<GdkDrawable *>(sid);
gc = gdk_gc_new(drawable);
#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
layout = pango_layout_new(pcontext);
@ -942,8 +1000,8 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
PLATFORM_ASSERT(layout);
#ifdef USE_CAIRO
if (height > 0 && width > 0)
psurf = gdk_window_create_similar_surface(
gtk_widget_get_window(PWidget(wid)),
psurf = CreateSimilarSurface(
WindowFromWidget(PWidget(wid)),
CAIRO_CONTENT_COLOR_ALPHA, width, height);
#else
if (height > 0 && width > 0)
@ -974,9 +1032,9 @@ void SurfaceImpl::PenColour(ColourAllocated fore) {
if (context) {
ColourDesired cdFore(fore.AsLong());
cairo_set_source_rgb(context,
cdFore.GetBlue() / 255.0,
cdFore.GetRed() / 255.0,
cdFore.GetGreen() / 255.0,
cdFore.GetRed() / 255.0);
cdFore.GetBlue() / 255.0);
}
#else
if (gc) {
@ -1186,7 +1244,12 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
double degrees = M_PI / 180.0;
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 2, 0)
cairo_new_sub_path(context);
#else
// First arc is in the top-right corner and starts from a point on the top line
cairo_move_to(context, left + width - radius, top);
#endif
cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees);
@ -1216,8 +1279,6 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
return converter.val;
}
#endif
static unsigned int GetRValue(unsigned int co) {
return (co >> 16) & 0xff;
}
@ -1230,24 +1291,34 @@ static unsigned int GetBValue(unsigned int co) {
return co & 0xff;
}
#endif
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags) {
#ifdef USE_CAIRO
if (context && rc.Width() > 0) {
ColourDesired cdFill(fill.AsLong());
cairo_set_source_rgba(context,
GetRValue(fill.AsLong()) / 255.0,
GetGValue(fill.AsLong()) / 255.0,
GetBValue(fill.AsLong()) / 255.0,
cdFill.GetRed() / 255.0,
cdFill.GetGreen() / 255.0,
cdFill.GetBlue() / 255.0,
alphaFill / 255.0);
PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
else
cairo_rectangle(context, rc.left + 1.0, rc.top + 1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0);
cairo_fill(context);
ColourDesired cdOutline(outline.AsLong());
cairo_set_source_rgba(context,
GetRValue(outline.AsLong()) / 255.0,
GetGValue(outline.AsLong()) / 255.0,
GetBValue(outline.AsLong()) / 255.0,
cdOutline.GetRed() / 255.0,
cdOutline.GetGreen() / 255.0,
cdOutline.GetBlue() / 255.0,
alphaOutline / 255.0);
PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
if (cornerSize > 0)
PathRoundRectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
else
cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1);
cairo_stroke(context);
}
#else
@ -1293,6 +1364,51 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
#endif
}
void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) {
if (rc.Width() > width)
rc.left += (rc.Width() - width) / 2;
rc.right = rc.left + width;
if (rc.Height() > height)
rc.top += (rc.Height() - height) / 2;
rc.bottom = rc.top + height;
#ifdef USE_CAIRO
int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
int ucs = stride * height;
std::vector<unsigned char> image(ucs);
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
unsigned char *pixel = &image[0] + y*stride + x * 4;
unsigned char alpha = pixelsImage[3];
pixel[2] = (*pixelsImage++) * alpha / 255;
pixel[1] = (*pixelsImage++) * alpha / 255;
pixel[0] = (*pixelsImage++) * alpha / 255;
pixel[3] = *pixelsImage++;
}
}
cairo_surface_t *psurf = cairo_image_surface_create_for_data(&image[0], CAIRO_FORMAT_ARGB32, width, height, stride);
cairo_set_source_surface(context, psurf, rc.left, rc.top);
cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
cairo_fill(context);
cairo_surface_destroy(psurf);
#else
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(pixelsImage,
GDK_COLORSPACE_RGB,
TRUE,
8,
width,
height,
width * 4,
NULL,
NULL);
gdk_draw_pixbuf(drawable, gc, pixbuf,
0,0, rc.left,rc.top, width,height, GDK_RGB_DITHER_NORMAL, 0, 0);
g_object_unref(pixbuf);
#endif
}
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
PenColour(back);
#ifdef USE_CAIRO
@ -1474,7 +1590,6 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
int xText = rc.left;
if (PFont(font_)->pfd) {
char *utfForm = 0;
bool useGFree = false;
if (et == UTF8) {
pango_layout_set_text(layout, s, len);
} else {
@ -1508,11 +1623,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
#else
gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
#endif
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
return;
}
#ifndef DISABLE_GDK_FONT
@ -1690,7 +1801,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
if (positionsCalculated < 1 ) {
// Either Latin1 or DBCS conversion failed so treat as Latin1.
bool useGFree = false;
SetConverter(PFont(font_)->characterSet);
char *utfForm = UTF8FromIconv(conv, s, len);
if (!utfForm) {
@ -1712,11 +1822,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
clusterStart = clusterEnd;
}
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
PLATFORM_ASSERT(i == lenPositions);
}
}
@ -1792,7 +1898,6 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
char *utfForm = 0;
pango_layout_set_font_description(layout, PFont(font_)->pfd);
PangoRectangle pos;
bool useGFree = false;
if (et == UTF8) {
pango_layout_set_text(layout, s, len);
} else {
@ -1815,11 +1920,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
PangoLayoutLine *pangoLine = pango_layout_get_line(layout,0);
#endif
pango_layout_line_get_extents(pangoLine, NULL, &pos);
if (useGFree) {
g_free(utfForm);
} else {
delete []utfForm;
}
delete []utfForm;
return PANGO_PIXELS(pos.width);
}
#ifndef DISABLE_GDK_FONT
@ -2005,11 +2106,17 @@ PRectangle Window::GetPosition() {
// Before any size allocated pretend its 1000 wide so not scrolled
PRectangle rc(0, 0, 1000, 1000);
if (wid) {
rc.left = PWidget(wid)->allocation.x;
rc.top = PWidget(wid)->allocation.y;
if (PWidget(wid)->allocation.width > 20) {
rc.right = rc.left + PWidget(wid)->allocation.width;
rc.bottom = rc.top + PWidget(wid)->allocation.height;
GtkAllocation allocation;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_allocation(PWidget(wid), &allocation);
#else
allocation = PWidget(wid)->allocation;
#endif
rc.left = allocation.x;
rc.top = allocation.y;
if (allocation.width > 20) {
rc.right = rc.left + allocation.width;
rc.bottom = rc.top + allocation.height;
}
}
return rc;
@ -2027,7 +2134,7 @@ void Window::SetPosition(PRectangle rc) {
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
int ox = 0;
int oy = 0;
gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy);
gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
ox += rc.left;
if (ox < 0)
ox = 0;
@ -2113,9 +2220,13 @@ void Window::SetCursor(Cursor curs) {
break;
}
if (PWidget(wid)->window)
gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
if (WindowFromWidget(PWidget(wid)))
gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
#if GTK_CHECK_VERSION(3,0,0)
g_object_unref(gdkCurs);
#else
gdk_cursor_unref(gdkCurs);
#endif
}
void Window::SetTitle(const char *s) {
@ -2127,7 +2238,7 @@ void Window::SetTitle(const char *s) {
PRectangle Window::GetMonitorRect(Point pt) {
gint x_offset, y_offset;
gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
#if GTK_CHECK_VERSION(2,2,0)
// GTK+ 2.2+
@ -2150,15 +2261,17 @@ PRectangle Window::GetMonitorRect(Point pt) {
#endif
}
typedef std::map<int, RGBAImage*> ImageMap;
struct ListImage {
const char *xpm_data;
const RGBAImage *rgba_data;
GdkPixbuf *pixbuf;
};
static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value;
if (list_image->pixbuf)
g_object_unref (list_image->pixbuf);
g_object_unref(list_image->pixbuf);
g_free(list_image);
}
@ -2179,7 +2292,7 @@ class ListBoxX : public ListBox {
WindowID scroller;
void *pixhash;
GtkCellRenderer* pixbuf_renderer;
XPMSet xset;
RGBAImageSet images;
int desiredVisibleRows;
unsigned int maxItemCharacters;
unsigned int aveCharWidth;
@ -2211,7 +2324,9 @@ public:
virtual int GetSelection();
virtual int Find(const char *prefix);
virtual void GetValue(int n, char *value, int len);
void RegisterRGBA(int type, RGBAImage *image);
virtual void RegisterImage(int type, const char *xpm_data);
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage);
virtual void ClearRegisteredImages();
virtual void SetDoubleClickAction(CallBackAction action, void *data) {
doubleClickAction = action;
@ -2242,24 +2357,47 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
/* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
GtkStyle* style;
g_return_if_fail(w != NULL);
/* Copy the selected color to active. Note that the modify calls will cause
recursive calls to this function after the value is updated and w->style to
be set to a new object */
style = gtk_widget_get_style(w);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourForeSelected;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
GdkRGBA colourForeActive;
gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
styleContext = gtk_widget_get_style_context(w);
if (styleContext == NULL)
return;
GdkRGBA colourBaseSelected;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
GdkRGBA colourBaseActive;
gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
#else
GtkStyle *style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
#endif
}
void ListBoxX::Create(Window &, int, Point, int, bool) {
@ -2324,7 +2462,11 @@ void ListBoxX::SetFont(Font &scint_font) {
// Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(scint_font)->pfd) {
// Current font is Pango font
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
#else
gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
#endif
}
}
@ -2360,14 +2502,27 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
gtk_tree_view_column_cell_get_size(column, NULL,
NULL, NULL, &row_width, &row_height);
#if GTK_CHECK_VERSION(3,0,0)
GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
GtkBorder padding;
gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
height = (rows * row_height
+ padding.top + padding.bottom
+ 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
#else
int ythickness = PWidget(list)->style->ythickness;
height = (rows * row_height
+ 2 * (ythickness
+ GTK_CONTAINER(PWidget(list))->border_width + 1));
#endif
gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
#else
gtk_widget_size_request(GTK_WIDGET(scroller), &req);
#endif
rc.right = req.width;
rc.bottom = req.height;
@ -2396,25 +2551,21 @@ void ListBoxX::Clear() {
}
static void init_pixmap(ListImage *list_image) {
const char *textForm = list_image->xpm_data;
const char * const * xpm_lineform = reinterpret_cast<const char * const *>(textForm);
const char **xpm_lineformfromtext = 0;
// The XPM data can be either in atext form as will be read from a file
// or in a line form (array of char *) as will be used for images defined in code.
// Test for text form and convert to line form
if ((0 == memcmp(textForm, "/* X", 4)) && (0 == memcmp(textForm, "/* XPM */", 9))) {
// Test done is two parts to avoid possibility of overstepping the memory
// if memcmp implemented strangely. Must be 4 bytes at least at destination.
xpm_lineformfromtext = XPM::LinesFormFromTextForm(textForm);
xpm_lineform = xpm_lineformfromtext;
if (list_image->rgba_data) {
// Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_data(list_image->rgba_data->Pixels(),
GDK_COLORSPACE_RGB,
TRUE,
8,
list_image->rgba_data->GetWidth(),
list_image->rgba_data->GetHeight(),
list_image->rgba_data->GetWidth() * 4,
NULL,
NULL);
}
// Drop any existing pixmap/bitmap as data may have changed
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
delete []xpm_lineformfromtext;
}
#define SPACING 5
@ -2481,11 +2632,17 @@ void ListBoxX::Select(int n) {
// Move the scrollbar to show the selection.
int total = Length();
#if GTK_CHECK_VERSION(3,0,0)
GtkAdjustment *adj =
gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+ gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
#else
GtkAdjustment *adj =
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
+ adj->lower - adj->page_size / 2;
#endif
// Get cell height
int row_width;
int row_height;
@ -2504,8 +2661,13 @@ void ListBoxX::Select(int n) {
}
// Clamp it.
value = (value < 0)? 0 : value;
#if GTK_CHECK_VERSION(3,0,0)
value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
#else
value = (value > (adj->upper - adj->page_size))?
(adj->upper - adj->page_size) : value;
#endif
// Set it.
gtk_adjustment_set_value(adj, value);
@ -2571,13 +2733,8 @@ void ListBoxX::GetValue(int n, char *value, int len) {
#pragma warning(disable: 4127)
#endif
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
g_return_if_fail(xpm_data);
// Saved and use the saved copy so caller's copy can disappear.
xset.Add(type, xpm_data);
XPM *pxpm = xset.Get(type);
xpm_data = reinterpret_cast<const char *>(pxpm->InLinesForm());
void ListBoxX::RegisterRGBA(int type, RGBAImage *image) {
images.Add(type, image);
if (!pixhash) {
pixhash = g_hash_table_new(g_direct_hash, g_direct_equal);
@ -2589,17 +2746,27 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf = NULL;
list_image->xpm_data = xpm_data;
list_image->rgba_data = image;
} else {
list_image = g_new0(ListImage, 1);
list_image->xpm_data = xpm_data;
list_image->rgba_data = image;
g_hash_table_insert((GHashTable *) pixhash, GINT_TO_POINTER(type),
(gpointer) list_image);
}
}
void ListBoxX::RegisterImage(int type, const char *xpm_data) {
g_return_if_fail(xpm_data);
XPM xpmImage(xpm_data);
RegisterRGBA(type, new RGBAImage(xpmImage));
}
void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) {
RegisterRGBA(type, new RGBAImage(width, height, pixelsImage));
}
void ListBoxX::ClearRegisteredImages() {
xset.Clear();
images.Clear();
}
void ListBoxX::SetList(const char *listText, char separator, char typesep) {
@ -2663,7 +2830,11 @@ void Menu::Show(Point pt, Window &) {
GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
gtk_widget_show_all(GTK_WIDGET(widget));
GtkRequisition requisition;
#if GTK_CHECK_VERSION(3,0,0)
gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
#else
gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
#endif
if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width;
}
@ -2791,7 +2962,8 @@ bool Platform::IsDBCSLeadByte(int codePage, char ch) {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);

File diff suppressed because it is too large Load Diff

View File

@ -16,6 +16,7 @@
#define PLAT_GTK 0
#define PLAT_GTK_WIN32 0
#define PLAT_GTK_MACOSX 0
#define PLAT_MACOSX 0
#define PLAT_WIN 0
#define PLAT_WX 0
@ -38,6 +39,11 @@
#define PLAT_GTK_WIN32 1
#endif
#if defined(__APPLE__)
#undef PLAT_GTK_MACOSX
#define PLAT_GTK_MACOSX 1
#endif
#elif defined(__APPLE__)
#undef PLAT_MACOSX
@ -301,8 +307,11 @@ public:
FontID GetID() { return fid; }
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
#if PLAT_WX
void SetAscent(int ascent_) { ascent = ascent_; }
#endif
friend class Surface;
friend class SurfaceImpl;
friend class SurfaceImpl;
};
/**
@ -336,6 +345,7 @@ public:
virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags)=0;
virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0;
virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0;
@ -411,8 +421,8 @@ public:
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
void SetWindow(void *ref) { windowRef = ref; };
void SetControl(void *_control) { control = _control; };
void SetWindow(void *ref) { windowRef = ref; }
void SetControl(void *_control) { control = _control; }
#endif
private:
Cursor cursorLast;
@ -443,6 +453,7 @@ public:
virtual int Find(const char *prefix)=0;
virtual void GetValue(int n, char *value, int len)=0;
virtual void RegisterImage(int type, const char *xpm_data)=0;
virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0;
virtual void ClearRegisteredImages()=0;
virtual void SetDoubleClickAction(CallBackAction, void *)=0;
virtual void SetList(const char* list, char separator, char typesep)=0;

View File

@ -344,6 +344,16 @@
#define SCE_PL_SUB_PROTOTYPE 40
#define SCE_PL_FORMAT_IDENT 41
#define SCE_PL_FORMAT 42
#define SCE_PL_STRING_VAR 43
#define SCE_PL_XLAT 44
#define SCE_PL_REGEX_VAR 54
#define SCE_PL_REGSUBST_VAR 55
#define SCE_PL_BACKTICKS_VAR 57
#define SCE_PL_HERE_QQ_VAR 61
#define SCE_PL_HERE_QX_VAR 62
#define SCE_PL_STRING_QQ_VAR 64
#define SCE_PL_STRING_QX_VAR 65
#define SCE_PL_STRING_QR_VAR 66
#define SCE_RB_DEFAULT 0
#define SCE_RB_ERROR 1
#define SCE_RB_COMMENTLINE 2
@ -408,6 +418,14 @@
#define SCE_L_TAG 2
#define SCE_L_MATH 3
#define SCE_L_COMMENT 4
#define SCE_L_TAG2 5
#define SCE_L_MATH2 6
#define SCE_L_COMMENT2 7
#define SCE_L_VERBATIM 8
#define SCE_L_SHORTCMD 9
#define SCE_L_SPECIAL 10
#define SCE_L_CMDOPT 11
#define SCE_L_ERROR 12
#define SCE_LUA_DEFAULT 0
#define SCE_LUA_COMMENT 1
#define SCE_LUA_COMMENTLINE 2
@ -428,6 +446,7 @@
#define SCE_LUA_WORD6 17
#define SCE_LUA_WORD7 18
#define SCE_LUA_WORD8 19
#define SCE_LUA_LABEL 20
#define SCE_ERR_DEFAULT 0
#define SCE_ERR_PYTHON 1
#define SCE_ERR_GCC 2

View File

@ -124,6 +124,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MARK_LEFTRECT 27
#define SC_MARK_AVAILABLE 28
#define SC_MARK_UNDERLINE 29
#define SC_MARK_RGBAIMAGE 30
#define SC_MARK_CHARACTER 10000
#define SC_MARKNUM_FOLDEREND 25
#define SC_MARKNUM_FOLDEROPENMID 26
@ -136,6 +137,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
#define SCI_MARKERSETBACKSELECTED 2292
#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
@ -245,6 +248,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
#define INDIC_STRAIGHTBOX 8
#define INDIC_DASH 9
#define INDIC_DOTS 10
#define INDIC_SQUIGGLELOW 11
#define INDIC_DOTBOX 12
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
@ -328,6 +336,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETSELECTIONSTART 2143
#define SCI_SETSELECTIONEND 2144
#define SCI_GETSELECTIONEND 2145
#define SCI_SETEMPTYSELECTION 2556
#define SCI_SETPRINTMAGNIFICATION 2146
#define SCI_GETPRINTMAGNIFICATION 2147
#define SC_PRINT_NORMAL 0
@ -554,7 +563,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352
#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
@ -707,6 +718,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
#define SCI_INDICSETOUTLINEALPHA 2558
#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
@ -721,6 +734,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARGINTEXTCLEARALL 2536
#define SCI_MARGINSETSTYLEOFFSET 2537
#define SCI_MARGINGETSTYLEOFFSET 2538
#define SC_MARGINOPTION_NONE 0
#define SC_MARGINOPTION_SUBLINESELECT 1
#define SCI_SETMARGINOPTIONS 2539
#define SCI_GETMARGINOPTIONS 2557
#define SCI_ANNOTATIONSETTEXT 2540
#define SCI_ANNOTATIONGETTEXT 2541
#define SCI_ANNOTATIONSETSTYLE 2542
@ -792,6 +809,16 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_CHANGELEXERSTATE 2617
#define SCI_CONTRACTEDFOLDNEXT 2618
#define SCI_VERTICALCENTRECARET 2619
#define SCI_MOVESELECTEDLINESUP 2620
#define SCI_MOVESELECTEDLINESDOWN 2621
#define SCI_SETIDENTIFIER 2622
#define SCI_GETIDENTIFIER 2623
#define SCI_RGBAIMAGESETWIDTH 2624
#define SCI_RGBAIMAGESETHEIGHT 2625
#define SCI_MARKERDEFINERGBAIMAGE 2626
#define SCI_REGISTERRGBAIMAGE 2627
#define SCI_SCROLLTOSTART 2628
#define SCI_SCROLLTOEND 2629
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@ -868,6 +895,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCMOD_CTRL 2
#define SCMOD_ALT 4
#define SCMOD_SUPER 8
#define SCMOD_META 16
#define SCN_STYLENEEDED 2000
#define SCN_CHARADDED 2001
#define SCN_SAVEPOINTREACHED 2002
@ -960,11 +988,22 @@ struct Sci_NotifyHeader {
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
int position;
/* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
/* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
/* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
/* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
/* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
int ch; /* SCN_CHARADDED, SCN_KEY */
int modifiers; /* SCN_KEY */
int modifiers;
/* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
/* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
int modificationType; /* SCN_MODIFIED */
const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
const char *text;
/* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
@ -978,7 +1017,7 @@ struct SCNotification {
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
int updated; /* SCN_UPDATEUI */
};

View File

@ -268,6 +268,7 @@ val SC_MARK_FULLRECT=26
val SC_MARK_LEFTRECT=27
val SC_MARK_AVAILABLE=28
val SC_MARK_UNDERLINE=29
val SC_MARK_RGBAIMAGE=30
val SC_MARK_CHARACTER=10000
@ -292,6 +293,12 @@ fun void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number.
fun void MarkerSetBack=2042(int markerNumber, colour back)
# Set the background colour used for a particular marker number when its folding block is selected.
fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
# Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber)
@ -544,6 +551,11 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5
val INDIC_BOX=6
val INDIC_ROUNDBOX=7
val INDIC_STRAIGHTBOX=8
val INDIC_DASH=9
val INDIC_DOTS=10
val INDIC_SQUIGGLELOW=11
val INDIC_DOTBOX=12
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
@ -791,6 +803,9 @@ set void SetSelectionEnd=2144(position pos,)
# Returns the position at the end of the selection.
get position GetSelectionEnd=2145(,)
# Set caret to a position, while removing any existing selection.
fun void SetEmptySelection=2556(position pos,)
# Sets the print magnification added to the point size of each style for printing.
set void SetPrintMagnification=2146(int magnification,)
@ -1440,9 +1455,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2)
# Use specified indicator to highlight matching braces instead of changing their style.
fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
# Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,)
# Use specified indicator to highlight non matching brace instead of changing its style.
fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
# Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,)
@ -1884,6 +1905,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,)
# Set the alpha outline colour of the given indicator.
set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
# Get the alpha outline colour of the given indicator.
get int IndicGetOutlineAlpha=2559(int indicator,)
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
@ -1926,6 +1953,16 @@ set void MarginSetStyleOffset=2537(int style,)
# Get the start of the range of style numbers used for margin text
get int MarginGetStyleOffset=2538(,)
enu MarginOption=SC_MARGINOPTION_
val SC_MARGINOPTION_NONE=0
val SC_MARGINOPTION_SUBLINESELECT=1
# Set the margin options.
set void SetMarginOptions=2539(int marginOptions,)
# Get the margin options.
get int GetMarginOptions=2557(,)
# Set the annotation text for a line
set void AnnotationSetText=2540(int line, string text)
@ -2106,6 +2143,38 @@ fun int ContractedFoldNext=2618(int lineStart,)
# Centre current line in window.
fun void VerticalCentreCaret=2619(,)
# Move the selected lines up one line, shifting the line above after the selection
fun void MoveSelectedLinesUp=2620(,)
# Move the selected lines down one line, shifting the line below before the selection
fun void MoveSelectedLinesDown=2621(,)
# Set the identifier reported as idFrom in notification messages.
set void SetIdentifier=2622(int identifier,)
# Get the identifier.
get int GetIdentifier=2623(,)
# Set the width for future RGBA image data.
set void RGBAImageSetWidth=2624(int width,)
# Set the height for future RGBA image data.
set void RGBAImageSetHeight=2625(int height,)
# Define a marker from RGBA data.
# It has the width and height from RGBAImageSetWidth/Height
fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels)
# Register an RGBA image for use in autocompletion lists.
# It has the width and height from RGBAImageSetWidth/Height
fun void RegisterRGBAImage=2627(int type, string pixels)
# Scroll to start of document.
fun void ScrollToStart=2628(,)
# Scroll to end of document.
fun void ScrollToEnd=2629(,)
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@ -2247,6 +2316,7 @@ val SCMOD_SHIFT=1
val SCMOD_CTRL=2
val SCMOD_ALT=4
val SCMOD_SUPER=8
val SCMOD_META=16
################################################
# For SciLexer.h
@ -2613,6 +2683,16 @@ val SCE_PL_POD_VERB=31
val SCE_PL_SUB_PROTOTYPE=40
val SCE_PL_FORMAT_IDENT=41
val SCE_PL_FORMAT=42
val SCE_PL_STRING_VAR=43
val SCE_PL_XLAT=44
val SCE_PL_REGEX_VAR=54
val SCE_PL_REGSUBST_VAR=55
val SCE_PL_BACKTICKS_VAR=57
val SCE_PL_HERE_QQ_VAR=61
val SCE_PL_HERE_QX_VAR=62
val SCE_PL_STRING_QQ_VAR=64
val SCE_PL_STRING_QX_VAR=65
val SCE_PL_STRING_QR_VAR=66
# Lexical states for SCLEX_RUBY
lex Ruby=SCLEX_RUBY SCE_RB_
val SCE_RB_DEFAULT=0
@ -2687,6 +2767,14 @@ val SCE_L_COMMAND=1
val SCE_L_TAG=2
val SCE_L_MATH=3
val SCE_L_COMMENT=4
val SCE_L_TAG2=5
val SCE_L_MATH2=6
val SCE_L_COMMENT2=7
val SCE_L_VERBATIM=8
val SCE_L_SHORTCMD=9
val SCE_L_SPECIAL=10
val SCE_L_CMDOPT=11
val SCE_L_ERROR=12
# Lexical states for SCLEX_LUA
lex Lua=SCLEX_LUA SCE_LUA_
val SCE_LUA_DEFAULT=0
@ -2709,6 +2797,7 @@ val SCE_LUA_WORD5=16
val SCE_LUA_WORD6=17
val SCE_LUA_WORD7=18
val SCE_LUA_WORD8=19
val SCE_LUA_LABEL=20
# Lexical states for SCLEX_ERRORLIST
lex ErrorList=SCLEX_ERRORLIST SCE_ERR_
val SCE_ERR_DEFAULT=0
@ -3889,22 +3978,22 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers)
evt void DoubleClick=2006(void)
evt void UpdateUI=2007(void)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
evt void DoubleClick=2006(int modifiers, int position, int line)
evt void UpdateUI=2007(int updated)
evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void)
evt void UserListSelection=2014(int listType, string text)
evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text)
evt void DwellStart=2016(int position)
evt void DwellEnd=2017(int position)
evt void DwellStart=2016(int position, int x, int y)
evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
evt void AutoCSelection=2022(string text)
evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void)

View File

@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file LexBasic.cxx
** Lexer for BlitzBasic and PureBasic.
** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
@ -21,18 +22,25 @@
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <ctype.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <string>
#include <map>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
#include "OptionSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@ -89,8 +97,213 @@ static int LowerCase(int c)
return c;
}
static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler, char comment_char) {
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
// An individual named option for use in an OptionSet
// Options used for LexerBasic
struct OptionsBasic {
bool fold;
bool foldSyntaxBased;
bool foldCommentExplicit;
std::string foldExplicitStart;
std::string foldExplicitEnd;
bool foldExplicitAnywhere;
bool foldCompact;
OptionsBasic() {
fold = false;
foldSyntaxBased = true;
foldCommentExplicit = false;
foldExplicitStart = "";
foldExplicitEnd = "";
foldExplicitAnywhere = false;
foldCompact = true;
}
};
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
struct OptionSetBasic : public OptionSet<OptionsBasic> {
OptionSetBasic(const char * const wordListDescriptions[]) {
DefineProperty("fold", &OptionsBasic::fold);
DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
"Set this property to 0 to disable syntax based folding.");
DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
"This option enables folding explicit fold points when using the Basic lexer. "
"Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
"and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
"The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
"The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
"Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
DefineProperty("fold.compact", &OptionsBasic::foldCompact);
DefineWordListSets(wordListDescriptions);
}
};
class LexerBasic : public ILexer {
char comment_char;
int (*CheckFoldPoint)(char const *, int &);
WordList keywordlists[4];
OptionsBasic options;
OptionSetBasic osBasic;
public:
LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
comment_char(comment_char_),
CheckFoldPoint(CheckFoldPoint_),
osBasic(wordListDescriptions) {
}
~LexerBasic() {
}
void SCI_METHOD Release() {
delete this;
}
int SCI_METHOD Version() const {
return lvOriginal;
}
const char * SCI_METHOD PropertyNames() {
return osBasic.PropertyNames();
}
int SCI_METHOD PropertyType(const char *name) {
return osBasic.PropertyType(name);
}
const char * SCI_METHOD DescribeProperty(const char *name) {
return osBasic.DescribeProperty(name);
}
int SCI_METHOD PropertySet(const char *key, const char *val);
const char * SCI_METHOD DescribeWordListSets() {
return osBasic.DescribeWordListSets();
}
int SCI_METHOD WordListSet(int n, const char *wl);
void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
void * SCI_METHOD PrivateCall(int, void *) {
return 0;
}
static ILexer *LexerFactoryBlitzBasic() {
return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
}
static ILexer *LexerFactoryPureBasic() {
return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
}
static ILexer *LexerFactoryFreeBasic() {
return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
}
};
int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
if (osBasic.PropertySet(&options, key, val)) {
return 0;
}
return -1;
}
int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
WordList *wordListN = 0;
switch (n) {
case 0:
wordListN = &keywordlists[0];
break;
case 1:
wordListN = &keywordlists[1];
break;
case 2:
wordListN = &keywordlists[2];
break;
case 3:
wordListN = &keywordlists[3];
break;
}
int firstModification = -1;
if (wordListN) {
WordList wlNew;
wlNew.Set(wl);
if (*wordListN != wlNew) {
wordListN->Set(wl);
firstModification = 0;
}
}
return firstModification;
}
void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
LexAccessor styler(pAccess);
bool wasfirst = true, isfirst = true; // true if first token in a line
styler.StartAt(startPos);
@ -114,7 +327,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
};
sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) {
if (keywordlists[i]->InList(s)) {
if (keywordlists[i].InList(s)) {
sc.ChangeState(kstates[i]);
}
}
@ -205,66 +418,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
sc.Complete();
}
static int CheckBlitzFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
static int CheckPureFoldPoint(char const *token, int &level) {
if (!strcmp(token, "procedure") ||
!strcmp(token, "enumeration") ||
!strcmp(token, "interface") ||
!strcmp(token, "structure")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "endprocedure") ||
!strcmp(token, "endenumeration") ||
!strcmp(token, "endinterface") ||
!strcmp(token, "endstructure")) {
return -1;
}
return 0;
}
void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
static int CheckFreeFoldPoint(char const *token, int &level) {
if (!strcmp(token, "function") ||
!strcmp(token, "sub") ||
!strcmp(token, "type")) {
level |= SC_FOLDLEVELHEADERFLAG;
return 1;
}
if (!strcmp(token, "end function") ||
!strcmp(token, "end sub") ||
!strcmp(token, "end type")) {
return -1;
}
return 0;
}
if (!options.fold)
return;
LexAccessor styler(pAccess);
static void FoldBasicDoc(unsigned int startPos, int length,
Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line);
int go = 0, done = 0;
int endPos = startPos + length;
char word[256];
int wordlen = 0;
int i;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
int cNext = styler[startPos];
// Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function"
for (i = startPos; i < endPos; i++) {
int c = styler.SafeGetCharAt(i);
if (!done && !go) {
for (int i = startPos; i < endPos; i++) {
int c = cNext;
cNext = styler.SafeGetCharAt(i + 1);
bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
if (options.foldSyntaxBased && !done && !go) {
if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token
@ -294,8 +471,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
}
if (c == '\n') { // line end
if (!done && wordlen == 0 && foldCompact) // line was only space
if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
if (userDefinedFoldMarkers) {
if (styler.Match(i, options.foldExplicitStart.c_str())) {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
go = -1;
}
} else {
if (c == comment_char) {
if (cNext == '{') {
level |= SC_FOLDLEVELHEADERFLAG;
go = 1;
} else if (cNext == '}') {
go = -1;
}
}
}
}
if (atEOL) { // line end
if (!done && wordlen == 0 && options.foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line))
styler.SetLevel(line, level);
@ -311,66 +507,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
}
static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
}
static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
}
static void FoldPureBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
}
static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
}
static const char * const blitzbasicWordListDesc[] = {
"BlitzBasic Keywords",
"user1",
"user2",
"user3",
0
};
static const char * const purebasicWordListDesc[] = {
"PureBasic Keywords",
"PureBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
static const char * const freebasicWordListDesc[] = {
"FreeBasic Keywords",
"FreeBasic PreProcessor Keywords",
"user defined 1",
"user defined 2",
0
};
LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
FoldBlitzBasicDoc, blitzbasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
FoldPureBasicDoc, purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
FoldFreeBasicDoc, freebasicWordListDesc);
LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);

View File

@ -208,6 +208,14 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER;
} else if (column == 6 && ch == '*') {
// Cobol comment line: asterisk in column 7.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (ch == '*' && chNext == '>') {
// Cobol inline comment: asterisk, followed by greater than.
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;
} else if (column == 0 && ch == '*' && chNext != '*') {
ColourTo(styler, i-1, state);
state = SCE_C_COMMENTLINE;

View File

@ -324,6 +324,7 @@ class LexerCPP : public ILexer {
OptionsCPP options;
OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
public:
LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_),
@ -368,7 +369,9 @@ public:
static ILexer *LexerFactoryCPPInsensitive() {
return new LexerCPP(false);
}
static int MaskActive(int style) {
return style & ~activeFlag;
}
void EvaluateTokens(std::vector<std::string> &tokens);
bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
};
@ -432,7 +435,7 @@ int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
struct After {
int line;
After(int line_) : line(line_) {}
bool operator() (PPDefinition &p) const {
bool operator()(PPDefinition &p) const {
return p.line > line;
}
};
@ -508,11 +511,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
preprocessorDefinitions[itDef->key] = itDef->value;
}
const int maskActivity = 0x3F;
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
SparseState<std::string> rawSTNew(lineCurrent);
int activitySet = preproc.IsInactive() ? 0x40 : 0;
int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) {
@ -528,7 +530,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
lastWordWasUUID = false;
isIncludePreprocessor = false;
if (preproc.IsInactive()) {
activitySet = 0x40;
activitySet = activeFlag;
sc.SetState(sc.state | activitySet);
}
if (activitySet) {
@ -563,7 +565,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
const bool atLineEndBeforeSwitch = sc.atLineEnd;
// Determine if the current state should terminate.
switch (sc.state & maskActivity) {
switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR:
sc.SetState(SCE_C_DEFAULT|activitySet);
break;
@ -739,7 +741,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_TRIPLEVERBATIM:
if (sc.Match ("\"\"\"")) {
if (sc.Match("\"\"\"")) {
while (sc.Match('"')) {
sc.Forward();
}
@ -759,7 +761,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
// Determine if a new state should be entered.
if ((sc.state & maskActivity) == SCE_C_DEFAULT) {
if (MaskActive(sc.state) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward();
@ -801,15 +803,20 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
} else if (sc.ch == '\"') {
if (sc.chPrev == 'R') {
sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;;termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(')
break;
rawStringTerminator += chTerminator;
styler.Flush();
if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) {
sc.SetState(SCE_C_STRINGRAW|activitySet);
rawStringTerminator = ")";
for (int termPos = sc.currentPos + 1;; termPos++) {
char chTerminator = styler.SafeGetCharAt(termPos, '(');
if (chTerminator == '(')
break;
rawStringTerminator += chTerminator;
}
rawStringTerminator += '\"';
} else {
sc.SetState(SCE_C_STRING|activitySet);
}
rawStringTerminator += '\"';
} else {
sc.SetState(SCE_C_STRING|activitySet);
}
@ -844,12 +851,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else if (sc.Match("else")) {
if (!preproc.CurrentIfTaken()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
@ -861,19 +868,19 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
if (ifGood) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (!preproc.IsInactive()) {
preproc.InvertCurrentLevel();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
if (!activitySet)
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
}
} else if (sc.Match("endif")) {
preproc.EndSection();
activitySet = preproc.IsInactive() ? 0x40 : 0;
activitySet = preproc.IsInactive() ? activeFlag : 0;
sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
} else if (sc.Match("define")) {
if (options.updatePreprocessor && !preproc.IsInactive()) {
@ -933,15 +940,15 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
int styleNext = MaskActive(styler.StyleAt(startPos));
int style = MaskActive(initStyle);
const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {

View File

@ -57,7 +57,7 @@ inline bool IsOperator(int ch) {
}
static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
size_t i = 0;
unsigned int i = 0;
for (; (i < end - start + 1) && (i < len-1); i++) {
s[i] = static_cast<char>(MakeLowerCase(styler[start + i]));
}
@ -66,7 +66,7 @@ static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int en
static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, size_t sLen) {
size_t i = 0;
unsigned int i = 0;
for (; i < sLen-1; i++) {
char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch))
@ -318,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
char chAttr = SCE_HJ_WORD;
bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
if (wordIsNumber)
bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER;
else {
char s[30 + 1];
unsigned int i = 0;
for (; i < end - start + 1 && i < 30; i++) {
s[i] = styler[start + i];
}
s[i] = '\0';
if (keywords.InList(s))
chAttr = SCE_HJ_KEYWORD;
} else if (keywords.InList(s)) {
chAttr = SCE_HJ_KEYWORD;
}
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
}
@ -356,7 +356,7 @@ static int classifyWordHTVB(unsigned int start, unsigned int end, WordList &keyw
return SCE_HB_DEFAULT;
}
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType) {
static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) {
bool wordIsNumber = IsADigit(styler[start]);
char s[30 + 1];
unsigned int i = 0;
@ -373,6 +373,8 @@ static void classifyWordHTPy(unsigned int start, unsigned int end, WordList &key
chAttr = SCE_HP_NUMBER;
else if (keywords.InList(s))
chAttr = SCE_HP_WORD;
else if (isMako && 0 == strcmp(s, "block"))
chAttr = SCE_HP_WORD;
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
strcpy(prevWord, s);
}
@ -494,7 +496,10 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
(0 == strcmp(blockType, "page"))) {
return ((ch == '/') && (chNext == '>'));
} else if (0 == strcmp(blockType, "%")) {
return isLineEnd(ch);
if (ch == '/' && isLineEnd(chNext))
return 1;
else
return isLineEnd(ch);
} else if (0 == strcmp(blockType, "{")) {
return ch == '}';
} else {
@ -588,6 +593,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int state = stateForPrintState(StateToPrint);
char makoBlockType[200];
makoBlockType[0] = '\0';
int makoComment = 0;
char djangoBlockType[2];
djangoBlockType[0] = '\0';
@ -754,15 +760,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (styler.Match(j, "end")) {
levelCurrent--;
}
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*')) ) {
levelCurrent += ((ch == '{') || (ch == '/') ) ? 1 : -1;
} else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
}
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
levelCurrent--;
}
break;
case eScriptPython:
if (state != SCE_HP_COMMENTLINE) {
if (state != SCE_HP_COMMENTLINE && !isMako) {
if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) {
levelCurrent++;
} else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) {
@ -818,6 +824,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
lineStartVisibleChars = 0;
}
// handle start of Mako comment line
if (isMako && ch == '#' && chNext == '#') {
makoComment = 1;
}
// handle end of Mako comment line
else if (isMako && makoComment && (ch == '\r' || ch == '\n')) {
makoComment = 0;
styler.ColourTo(i, SCE_HP_COMMENTLINE);
state = SCE_HP_DEFAULT;
}
// Allow falling through to mako handling code if newline is going to end a block
if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
(!isMako || (0 != strcmp(makoBlockType, "%")))) {
@ -882,7 +900,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') &&
(chNext == '?') &&
!IsScriptCommentState(state) ) {
!IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
@ -911,9 +930,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
// handle the start Mako template Python code
else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
(lineStartVisibleChars == 1 && ch == '%') ||
(lineStartVisibleChars == 1 && ch == '/' && chNext == '%') ||
(ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%')
if (ch == '%' || ch == '/')
strcpy(makoBlockType, "%");
else if (ch == '$')
strcpy(makoBlockType, "{");
@ -938,12 +958,10 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HP_START;
scriptLanguage = eScriptPython;
styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && ch == '<')
levelCurrent++;
if (ch != '%' && ch != '$') {
i += strlen(makoBlockType);
visibleChars += strlen(makoBlockType);
if (ch != '%' && ch != '$' && ch != '/') {
i += static_cast<int>(strlen(makoBlockType));
visibleChars += static_cast<int>(strlen(makoBlockType));
if (keywords4.InList(makoBlockType))
styler.ColourTo(i, SCE_HP_WORD);
else
@ -954,6 +972,36 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
// handle the start/end of Django comment
else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
beforeLanguage = scriptLanguage;
if (inScriptType == eNonHtmlScript)
inScriptType = eNonHtmlScriptPreProc;
else
inScriptType = eNonHtmlPreProc;
i += 1;
visibleChars += 1;
scriptLanguage = eScriptComment;
state = SCE_H_COMMENT;
styler.ColourTo(i, SCE_H_ASP);
ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
continue;
} else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
styler.ColourTo(i - 1, StateToPrint);
i += 1;
visibleChars += 1;
styler.ColourTo(i, SCE_H_ASP);
state = beforePreProc;
if (inScriptType == eNonHtmlScriptPreProc)
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
scriptLanguage = beforeLanguage;
continue;
}
// handle the start Django template code
else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
if (chNext == '%')
@ -1024,7 +1072,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) &&
(!IsScriptCommentState(StateToPrint)) ) {
(!IsScriptCommentState(StateToPrint))) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
@ -1054,7 +1102,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
@ -1062,7 +1110,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%")) {
else if (0 == strcmp(makoBlockType, "%") && ch == '/') {
i++;
visibleChars++;
}
if (0 != strcmp(makoBlockType, "%") || ch == '/') {
styler.ColourTo(i, SCE_H_ASP);
}
state = beforePreProc;
@ -1070,9 +1122,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
inScriptType = eNonHtmlScript;
else
inScriptType = eHtml;
if (foldHTMLPreprocessor && ch != '\n' && ch != '\r') {
levelCurrent--;
}
scriptLanguage = eScriptNone;
continue;
}
@ -1087,7 +1136,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.GetStartSegment(), i - 1, aspScript);
}
if (state == SCE_HP_WORD) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
} else {
styler.ColourTo(i - 1, StateToPrint);
}
@ -1121,7 +1170,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
break;
case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler);
@ -1154,7 +1203,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
scriptLanguage = eScriptNone;
scriptLanguage = beforeLanguage;
continue;
}
/////////////////////////////////////
@ -1783,7 +1832,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
break;
case SCE_HP_WORD:
if (!IsAWordChar(ch)) {
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako);
state = SCE_HP_DEFAULT;
if (ch == '#') {
state = SCE_HP_COMMENTLINE;
@ -1934,7 +1983,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.ColourTo(i, StateToPrint);
state = SCE_HPHP_DEFAULT;
} else if (isLineEnd(chPrev)) {
const int psdLength = strlen(phpStringDelimiter);
const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) ||
@ -1957,7 +2006,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_HPHP_DEFAULT;
}
} else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) {
const int psdLength = strlen(phpStringDelimiter);
const int psdLength = static_cast<int>(strlen(phpStringDelimiter));
const char chAfterPsd = styler.SafeGetCharAt(i + psdLength);
const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1);
if (isLineEnd(chAfterPsd) ||
@ -2072,7 +2121,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType);
break;
case SCE_HP_WORD:
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType);
classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako);
break;
case SCE_HPHP_WORD:
classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler);

View File

@ -59,10 +59,11 @@ static void ColouriseLuaDoc(
// Accepts accented characters
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "_", 0x80, true);
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
// but probably enough in most cases. [pP] is for hex floats.
CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
CharacterSet setExponent(CharacterSet::setNone, "eEpP");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
@ -70,12 +71,16 @@ static void ColouriseLuaDoc(
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1.
// Continuation of a string (\z whitespace escaping) is controlled by stringWs.
int nestLevel = 0;
int sepCount = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
int stringWs = 0;
if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
int lineState = styler.GetLineState(currentLine - 1);
nestLevel = lineState >> 8;
nestLevel = lineState >> 9;
sepCount = lineState & 0xFF;
stringWs = lineState & 0x100;
}
// Do not leak onto next line
@ -95,8 +100,10 @@ static void ColouriseLuaDoc(
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT:
// Inside a literal string or block comment, we set the line state
styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
case SCE_LUA_STRING:
case SCE_LUA_CHARACTER:
// Inside a literal string, block comment or string, we set the line state
styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
break;
default:
// Reset the line state
@ -123,21 +130,91 @@ static void ColouriseLuaDoc(
// Determine if the current state should terminate.
if (sc.state == SCE_LUA_OPERATOR) {
if (sc.ch == ':' && sc.chPrev == ':') { // :: <label> :: forward scan
sc.Forward();
int ln = 0, maxln = startPos + length - sc.currentPos;
int c;
while (ln < maxln) { // determine line extent
c = sc.GetRelative(ln);
if (c == '\r' || c == '\n')
break;
ln++;
}
maxln = ln; ln = 0;
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws1 = ln;
if (setWordStart.Contains(sc.GetRelative(ln))) {
int i = 0;
char s[100];
while (ln < maxln) { // get potential label
c = sc.GetRelative(ln);
if (!setWord.Contains(c))
break;
if (i < 90)
s[i++] = c;
ln++;
}
s[i] = '\0'; int lbl = ln;
if (!keywords.InList(s)) {
while (ln < maxln) { // skip over spaces/tabs
if (!IsASpaceOrTab(sc.GetRelative(ln)))
break;
ln++;
}
int ws2 = ln - lbl;
if (sc.GetRelative(ln) == ':' && sc.GetRelative(ln + 1) == ':') {
// final :: found, complete valid label construct
sc.ChangeState(SCE_LUA_LABEL);
if (ws1) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws1);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(lbl - ws1);
if (ws2) {
sc.SetState(SCE_LUA_DEFAULT);
sc.Forward(ws2);
}
sc.SetState(SCE_LUA_LABEL);
sc.Forward(2);
}
}
}
}
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) {
// We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
// We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') {
if (sc.chPrev != 'E' && sc.chPrev != 'e')
if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
if (!setWord.Contains(sc.ch) || sc.Match('.', '.')) {
if (!(setWord.Contains(sc.ch) || sc.ch == '.') || sc.Match('.', '.')) {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_LUA_WORD);
if (strcmp(s, "goto") == 0) { // goto <label> forward scan
sc.SetState(SCE_LUA_DEFAULT);
while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
sc.Forward();
if (setWordStart.Contains(sc.ch)) {
sc.SetState(SCE_LUA_LABEL);
sc.Forward();
while (setWord.Contains(sc.ch))
sc.Forward();
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s))
sc.ChangeState(SCE_LUA_WORD);
}
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (keywords2.InList(s)) {
sc.ChangeState(SCE_LUA_WORD2);
} else if (keywords3.InList(s)) {
@ -160,24 +237,38 @@ static void ColouriseLuaDoc(
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_CHARACTER) {
if (stringWs) {
if (!IsASpace(sc.ch))
stringWs = 0;
}
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
} else if (sc.chNext == 'z') {
sc.Forward();
stringWs = 0x100;
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
} else if (sc.atLineEnd) {
} else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
@ -214,8 +305,10 @@ static void ColouriseLuaDoc(
sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
stringWs = 0;
} else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
stringWs = 0;
} else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc);
if (sepCount == 0) {
@ -246,7 +339,7 @@ static void ColouriseLuaDoc(
}
}
if (setWord.Contains(sc.chPrev)) {
if (setWord.Contains(sc.chPrev) || sc.chPrev == '.') {
char s[100];
sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {

View File

@ -113,6 +113,10 @@ static bool HasPrevLineContent(StyleContext &sc) {
return false;
}
static bool AtTermStart(StyleContext &sc) {
return sc.currentPos == 0 || isspacechar(sc.chPrev);
}
static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
int c, count = 1;
unsigned int i = 0;
@ -373,35 +377,38 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
}
}
// Code - also a special case for alternate inside spacing
if (sc.Match("``") && sc.GetRelative(3) != ' ') {
if (sc.Match("``") && sc.GetRelative(3) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE2);
sc.Forward();
}
else if (sc.ch == '`' && sc.chNext != ' ') {
else if (sc.ch == '`' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_CODE);
}
// Strong
else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
else if (sc.Match("**") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG1);
sc.Forward();
}
else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
else if (sc.Match("__") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRONG2);
sc.Forward();
}
// Emphasis
else if (sc.ch == '*' && sc.chNext != ' ')
else if (sc.ch == '*' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM1);
else if (sc.ch == '_' && sc.chNext != ' ')
}
else if (sc.ch == '_' && sc.chNext != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_EM2);
}
// Strikeout
else if (sc.Match("~~") && sc.GetRelative(2) != ' ') {
else if (sc.Match("~~") && sc.GetRelative(2) != ' ' && AtTermStart(sc)) {
sc.SetState(SCE_MARKDOWN_STRIKEOUT);
sc.Forward();
}
// Beginning of line
else if (IsNewline(sc.ch))
else if (IsNewline(sc.ch)) {
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
}
// Advance if not holding back the cursor for this iteration.
if (!freezeCursor)

View File

@ -106,12 +106,12 @@ static void ColouriseMatlabOctaveDoc(
transpose = true;
}
} else if (sc.state == SCE_MATLAB_STRING) {
if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
if (sc.ch == '\'') {
if (sc.chNext == '\'') {
sc.Forward();
} else {
sc.ForwardSetState(SCE_MATLAB_DEFAULT);
}
}
} else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
if (sc.ch == '\\') {

View File

@ -58,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators
static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') ||
(ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
(ch == '\"') || (ch == '\'') || (ch == '/');
}
static void ColouriseBatchLine(
@ -854,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return;
}
int varCount = 0;
while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
if (--varCount == 0) {
styler.ColourTo(startLine + i, state);
state = SCE_MAKE_DEFAULT;
}
}
// skip identifier and target styling if this is a command line
@ -1158,21 +1162,71 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
}
}
static int isSpecial(char s) {
return (s == '\\') || (s == ',') || (s == ';') || (s == '\'') || (s == ' ') ||
(s == '\"') || (s == '`') || (s == '^') || (s == '~');
static bool latexIsSpecial(int ch) {
return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
(ch == '{') || (ch == '}') || (ch == ' ');
}
static int isTag(int start, Accessor &styler) {
char s[6];
unsigned int i = 0, e = 1;
while (i < 5 && e) {
s[i] = styler[start + i];
static bool latexIsBlank(int ch) {
return (ch == ' ') || (ch == '\t');
}
static bool latexIsBlankAndNL(int ch) {
return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
}
static bool latexIsLetter(int ch) {
return isascii(ch) && isalpha(ch);
}
static bool latexIsTagValid(int &i, int l, Accessor &styler) {
while (i < l) {
if (styler.SafeGetCharAt(i) == '{') {
while (i < l) {
i++;
if (styler.SafeGetCharAt(i) == '}') {
return true;
} else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
styler.SafeGetCharAt(i)!='*') {
return false;
}
}
} else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
return false;
}
i++;
e = (strchr("{ \t", styler[start + i]) == NULL);
}
return false;
}
static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
char ch;
while (i < l) {
ch = styler.SafeGetCharAt(i);
if (!latexIsBlankAndNL(ch) && ch != '*') {
if (ch == needle)
return true;
else
return false;
}
i++;
}
return false;
}
static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
unsigned int i = 0;
unsigned int l = static_cast<unsigned int>(strlen(needle));
int ini = start-l+1;
char s[32];
while (i < l && i < 32) {
s[i] = styler.SafeGetCharAt(ini + i);
i++;
}
s[i] = '\0';
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
return (strcmp(s, needle) == 0);
}
static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
@ -1181,39 +1235,51 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.StartAt(startPos);
int state = initStyle;
char chNext = styler[startPos];
char chNext = styler.SafeGetCharAt(startPos);
styler.StartSegment(startPos);
int lengthDoc = startPos + length;
char chVerbatimDelim = '\0';
for (int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
if (styler.IsLeadByte(ch)) {
chNext = styler.SafeGetCharAt(i + 2);
i++;
chNext = styler.SafeGetCharAt(i + 1);
continue;
}
switch (state) {
case SCE_L_DEFAULT :
switch (ch) {
case '\\' :
styler.ColourTo(i - 1, state);
if (isSpecial(styler[i + 1])) {
styler.ColourTo(i + 1, SCE_L_COMMAND);
i++;
chNext = styler.SafeGetCharAt(i + 1);
if (latexIsSpecial(chNext)) {
state = SCE_L_SPECIAL;
} else {
if (isTag(i + 1, styler))
state = SCE_L_TAG;
else
if (latexIsLetter(chNext)) {
state = SCE_L_COMMAND;
} else {
if (chNext == '(' || chNext == '[') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
state = SCE_L_MATH;
if (chNext == '[')
state = SCE_L_MATH2;
i++;
chNext = styler.SafeGetCharAt(i+1);
} else {
state = SCE_L_SHORTCMD;
}
}
}
break;
case '$' :
styler.ColourTo(i - 1, state);
state = SCE_L_MATH;
if (chNext == '$') {
state = SCE_L_MATH2;
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
@ -1224,29 +1290,124 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
break;
}
break;
case SCE_L_ERROR:
styler.ColourTo(i-1, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_SPECIAL:
case SCE_L_SHORTCMD:
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
break;
case SCE_L_COMMAND :
if (chNext == '[' || chNext == '{' || chNext == '}' ||
chNext == ' ' || chNext == '\r' || chNext == '\n') {
if (!latexIsLetter(chNext)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
i++;
chNext = styler.SafeGetCharAt(i + 1);
if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
state = SCE_L_CMDOPT;
} else if (latexLastWordIs(i, styler, "\\begin")) {
state = SCE_L_TAG;
} else if (latexLastWordIs(i, styler, "\\end")) {
state = SCE_L_TAG2;
} else if (latexLastWordIs(i, styler, "\\verb") &&
chNext != '*' && chNext != ' ') {
chVerbatimDelim = chNext;
state = SCE_L_VERBATIM;
}
}
break;
case SCE_L_CMDOPT :
if (ch == ']') {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
}
break;
case SCE_L_TAG :
if (ch == '}') {
if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
if (latexLastWordIs(i, styler, "{verbatim}")) {
state = SCE_L_VERBATIM;
} else if (latexLastWordIs(i, styler, "{comment}")) {
state = SCE_L_COMMENT2;
} else if (latexLastWordIs(i, styler, "{math}")) {
state = SCE_L_MATH;
} else if (latexLastWordIs(i, styler, "{displaymath}")) {
state = SCE_L_MATH2;
} else if (latexLastWordIs(i, styler, "{equation}")) {
state = SCE_L_MATH2;
}
} else {
state = SCE_L_ERROR;
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
}
chNext = styler.SafeGetCharAt(i+1);
break;
case SCE_L_TAG2 :
if (latexIsTagValid(i, lengthDoc, styler)) {
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
state = SCE_L_ERROR;
}
chNext = styler.SafeGetCharAt(i+1);
break;
case SCE_L_MATH :
if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
}
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else if (ch == '\\' && chNext == ')') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{math}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_MATH2 :
if (ch == '$') {
if (chNext == '$') {
i++;
chNext = styler.SafeGetCharAt(i + 1);
styler.ColourTo(i, state);
state = SCE_L_DEFAULT;
} else {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
}
} else if (ch == '\\' && chNext == ']') {
styler.ColourTo(i-1, state);
styler.ColourTo(i+1, SCE_L_SHORTCMD);
i++;
chNext = styler.SafeGetCharAt(i+1);
state = SCE_L_DEFAULT;
} else if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{displaymath}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
} else if (latexLastWordIs(match, styler, "{equation}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_COMMENT :
@ -1254,6 +1415,43 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.ColourTo(i - 1, state);
state = SCE_L_DEFAULT;
}
break;
case SCE_L_COMMENT2 :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{comment}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
}
break;
case SCE_L_VERBATIM :
if (ch == '\\') {
int match = i + 3;
if (latexLastWordIs(match, styler, "\\end")) {
match++;
if (latexIsTagValid(match, lengthDoc, styler)) {
if (latexLastWordIs(match, styler, "{verbatim}")) {
styler.ColourTo(i-1, state);
state = SCE_L_COMMAND;
}
}
}
} else if (chNext == chVerbatimDelim) {
styler.ColourTo(i+1, state);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
} else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
styler.ColourTo(i, SCE_L_ERROR);
state = SCE_L_DEFAULT;
chVerbatimDelim = '\0';
}
break;
}
}
styler.ColourTo(lengthDoc-1, state);

File diff suppressed because it is too large Load Diff

View File

@ -28,7 +28,7 @@ using namespace Scintilla;
#endif
/* kwCDef, kwCTypeName only used for Cython */
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1;
@ -165,6 +165,11 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
// Set to 1 to allow strings to span newline characters.
bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;
// property lexer.python.keywords2.no.sub.identifiers
// When enabled, it will not style keywords2 items that are used as a sub-identifier.
// Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.
const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0;
initStyle = initStyle & 31;
if (initStyle == SCE_P_STRINGEOL) {
initStyle = SCE_P_DEFAULT;
@ -246,7 +251,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
} else if (kwLast == kwCDef) {
} else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') {
@ -264,7 +269,16 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
}
}
} else if (keywords2.InList(s)) {
style = SCE_P_WORD2;
if (keywords2NoSubIdentifiers) {
// We don't want to highlight keywords2
// that are used as a sub-identifier,
// i.e. not open in "foo.open".
int pos = styler.GetStartSegment() - 1;
if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
style = SCE_P_WORD2;
} else {
style = SCE_P_WORD2;
}
}
sc.ChangeState(style);
sc.SetState(SCE_P_DEFAULT);
@ -277,11 +291,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport;
else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef;
else if (0 == strcmp(s, "cpdef"))
kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport"))
kwLast = kwImport;
else if (kwLast != kwCDef)
else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther;
} else if (kwLast != kwCDef) {
} else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther;
}
}
@ -337,8 +353,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true;
}
// One cdef line, clear kwLast only at end of line
if (kwLast == kwCDef && sc.atLineEnd) {
// One cdef or cpdef line, clear kwLast only at end of line
if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther;
}
@ -412,12 +428,8 @@ static bool IsQuoteLine(int line, Accessor &styler) {
static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
WordList *[], Accessor &styler) {
const int maxPos = startPos + length;
const int maxLines = styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length() - 1); // Available last line
// property fold.comment.python
// This option enables folding multi-line comments when using the Python lexer.
const bool foldComment = styler.GetPropertyInt("fold.comment.python") != 0;
const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line
const int docLines = styler.GetLine(styler.Length()); // Available last line
// property fold.quotes.python
// This option enables folding multi-line quoted strings when using the Python lexer.
@ -448,14 +460,11 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineCurrent >= 1)
prev_state = styler.StyleAt(startPos - 1) & 31;
int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));
int prevComment = 0;
if (lineCurrent >= 1)
prevComment = foldComment && IsCommentLine(lineCurrent - 1, styler);
// Process all characters to end of requested range or end of any triple quote
// or comment that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote or comment at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote || prevComment)) {
//that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote at end).
while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {
// Gather info
int lev = indentCurrent;
@ -465,16 +474,13 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
if (lineNext <= docLines) {
// Information about next line is only available if not at end of document
indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
int style = styler.StyleAt(styler.LineStart(lineNext)) & 31;
int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
int style = styler.StyleAt(lookAtPos) & 31;
quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
}
const int quote_start = (quote && !prevQuote);
const int quote_continue = (quote && prevQuote);
const int comment = foldComment && IsCommentLine(lineCurrent, styler);
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
IsCommentLine(lineNext, styler) && (lev > SC_FOLDLEVELBASE));
const int comment_continue = (comment && prevComment);
if ((!quote || !prevQuote) && !comment)
if (!quote || !prevQuote)
indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
if (quote)
indentNext = indentCurrentLevel;
@ -487,12 +493,6 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
} else if (quote_continue || prevQuote) {
// Add level to rest of lines in the string
lev = lev + 1;
} else if (comment_start) {
// Place fold point at start of a block of comments
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (comment_continue) {
// Add level to rest of lines in the block
lev = lev + 1;
}
// Skip past any blank lines for next indent level info; we skip also
@ -540,18 +540,17 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
}
// Set fold header on non-quote/non-comment line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
// Set fold header on non-quote line
if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG;
}
// Keep track of triple quote and block comment state of previous line
// Keep track of triple quote state of previous line
prevQuote = quote;
prevComment = comment_start || comment_continue;
// Set fold level for this line and move to next line
styler.SetLevel(lineCurrent, lev);
styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
indentCurrent = indentNext;
lineCurrent = lineNext;
}

View File

@ -16,7 +16,6 @@
#include "Scintilla.h"
#include "SciLexer.h"
#include "PropSetSimple.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "Accessor.h"
@ -1729,7 +1728,13 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
) {
levelCurrent++;
}
}
} else if (style == SCE_RB_HERE_DELIM) {
if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
levelCurrent++;
} else if (styleNext == SCE_RB_DEFAULT) {
levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
@ -1765,4 +1770,4 @@ static const char * const rubyWordListDesc[] = {
0
};
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);

View File

@ -204,8 +204,8 @@ struct OptionSetSQL : public OptionSet<OptionsSQL> {
OptionSetSQL() {
DefineProperty("fold", &OptionsSQL::fold);
DefineProperty("lexer.sql.fold.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\"line of an IF statement.");
DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
"This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
DefineProperty("fold.comment", &OptionsSQL::foldComment);
@ -283,6 +283,20 @@ private:
style == SCE_SQL_COMMENTDOCKEYWORDERROR;
}
bool IsCommentStyle (int style) {
switch (style) {
case SCE_SQL_COMMENT :
case SCE_SQL_COMMENTDOC :
case SCE_SQL_COMMENTLINE :
case SCE_SQL_COMMENTLINEDOC :
case SCE_SQL_COMMENTDOCKEYWORD :
case SCE_SQL_COMMENTDOCKEYWORDERROR :
return true;
default :
return false;
}
}
OptionsSQL options;
OptionSetSQL osSQL;
SQLStates sqlStates;
@ -521,7 +535,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (atEOL || (ch == ';')) {
if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
if (endFound) {
//Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
@ -554,7 +568,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (ch == '(') {
if (levelCurrent > levelNext)
levelCurrent--;
levelNext++;
levelNext++;
} else if (ch == ')') {
levelNext--;
} else if ((!options.foldOnlyBegin) && ch == ';') {

View File

@ -235,7 +235,7 @@ static void FoldNoBoxVHDLDoc(
}
}
}
for(j=j+strlen(prevWord); j<endPos; j++)
for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
{
char ch = styler.SafeGetCharAt(j);
int style = styler.StyleAt(j);

View File

@ -29,7 +29,7 @@ using namespace Scintilla;
#endif
static inline bool IsAWordChar(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\''|| ch == '$');
}
static inline bool IsAWordStart(const int ch) {
@ -269,24 +269,36 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
if (styler.Match(j, "case") ||
styler.Match(j, "casex") ||
styler.Match(j, "casez") ||
styler.Match(j, "class") ||
styler.Match(j, "function") ||
styler.Match(j, "fork") ||
styler.Match(j, "generate") ||
styler.Match(j, "covergroup") ||
styler.Match(j, "package") ||
styler.Match(j, "primitive") ||
styler.Match(j, "program") ||
styler.Match(j, "sequence") ||
styler.Match(j, "specify") ||
styler.Match(j, "table") ||
styler.Match(j, "task") ||
styler.Match(j, "generate") ||
styler.Match(j, "specify") ||
styler.Match(j, "primitive") ||
styler.Match(j, "fork") ||
(styler.Match(j, "module") && foldAtModule) ||
styler.Match(j, "begin")) {
levelNext++;
} else if (styler.Match(j, "endcase") ||
styler.Match(j, "endclass") ||
styler.Match(j, "endfunction") ||
styler.Match(j, "join") ||
styler.Match(j, "endtask") ||
styler.Match(j, "endgenerate") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endgroup") ||
styler.Match(j, "endpackage") ||
styler.Match(j, "endprimitive") ||
styler.Match(j, "endprogram") ||
styler.Match(j, "endsequence") ||
styler.Match(j, "endspecify") ||
styler.Match(j, "endtable") ||
styler.Match(j, "endtask") ||
styler.Match(j, "join") ||
styler.Match(j, "join_any") ||
styler.Match(j, "join_none") ||
(styler.Match(j, "endmodule") && foldAtModule) ||
(styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
levelNext--;

View File

@ -71,7 +71,7 @@ int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsComment
*flags = spaceFlags;
indent += SC_FOLDLEVELBASE;
// if completely empty line or the start of a comment...
if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
return indent | SC_FOLDLEVELWHITEFLAG;
else

View File

@ -119,7 +119,6 @@ inline bool iswordstart(int ch) {
inline bool isoperator(int ch) {
if (IsASCII(ch) && IsAlphaNumeric(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
ch == '=' || ch == '|' || ch == '{' || ch == '}' ||

View File

@ -61,9 +61,10 @@ void PropSetSimple::Set(const char *keyVal) {
endVal++;
const char *eqAt = strchr(keyVal, '=');
if (eqAt) {
Set(keyVal, eqAt + 1, eqAt-keyVal, endVal - eqAt - 1);
Set(keyVal, eqAt + 1, static_cast<int>(eqAt-keyVal),
static_cast<int>(endVal - eqAt - 1));
} else if (*keyVal) { // No '=' so assume '=1'
Set(keyVal, "1", endVal-keyVal, 1);
Set(keyVal, "1", static_cast<int>(endVal-keyVal), 1);
}
}
@ -150,7 +151,7 @@ char *PropSetSimple::Expanded(const char *key) const {
int PropSetSimple::GetExpanded(const char *key, char *result) const {
char *val = Expanded(key);
const int n = strlen(val);
const int n = static_cast<int>(strlen(val));
if (result) {
strcpy(result, val);
}

View File

@ -43,12 +43,12 @@ public:
}
void Set(int position, T value) {
Delete(position);
if ((states.size() == 0) || (value != states[states.size()-1].value)) {
if (states.empty() || (value != states[states.size()-1].value)) {
states.push_back(State(position, value));
}
}
T ValueAt(int position) {
if (!states.size())
if (states.empty())
return T();
if (position < states[0].position)
return T();
@ -92,7 +92,7 @@ public:
changed = true;
}
typename stateVector::const_iterator startOther = other.states.begin();
if (!states.empty() && states.back().value == startOther->value)
if (!states.empty() && !other.states.empty() && states.back().value == startOther->value)
++startOther;
if (startOther != other.states.end()) {
states.insert(states.end(), startOther, other.states.end());

View File

@ -55,7 +55,6 @@ public:
styler(styler_),
endPos(startPos + length),
currentPos(startPos),
atLineStart(true),
atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
@ -63,6 +62,7 @@ public:
chNext(0) {
styler.StartAt(startPos, chMask);
styler.StartSegment(startPos);
atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) == startPos;
unsigned int pos = currentPos;
ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
if (styler.IsLeadByte(static_cast<char>(ch))) {

View File

@ -11,6 +11,8 @@
#include <stdio.h>
#include <stdarg.h>
#include <algorithm>
#include "WordList.h"
#ifdef SCI_NAMESPACE
@ -86,22 +88,34 @@ void WordList::Clear() {
len = 0;
}
extern "C" int cmpString(const void *a1, const void *a2) {
// Can't work out the correct incantation to use modern casts here
return strcmp(*(char **)(a1), *(char **)(a2));
#ifdef _MSC_VER
static bool cmpWords(const char *a, const char *b) {
return strcmp(a, b) == -1;
}
#else
static int cmpWords(const void *a, const void *b) {
return strcmp(*static_cast<const char * const *>(a), *static_cast<const char * const *>(b));
}
static void SortWordList(char **words, unsigned int len) {
qsort(reinterpret_cast<void *>(words), len, sizeof(*words),
cmpString);
qsort(reinterpret_cast<void *>(words), len, sizeof(*words), cmpWords);
}
#endif
void WordList::Set(const char *s) {
Clear();
list = new char[strlen(s) + 1];
strcpy(list, s);
words = ArrayFromWordList(list, &len, onlyLineEnds);
#ifdef _MSC_VER
std::sort(words, words + len, cmpWords);
#else
SortWordList(words, len);
#endif
for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
starts[k] = -1;
for (int l = len - 1; l >= 0; l--) {
@ -121,7 +135,7 @@ bool WordList::InList(const char *s) const {
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while ((unsigned char)words[j][0] == firstChar) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
if (s[1] == words[j][1]) {
const char *a = words[j] + 1;
const char *b = s + 1;
@ -163,7 +177,7 @@ bool WordList::InListAbbreviated(const char *s, const char marker) const {
unsigned char firstChar = s[0];
int j = starts[firstChar];
if (j >= 0) {
while (words[j][0] == firstChar) {
while (static_cast<unsigned char>(words[j][0]) == firstChar) {
bool isSubword = false;
int start = 1;
if (words[j][1] == marker) {

View File

@ -1,4 +1,4 @@
A patch to Scintilla 2.25 containing our changes to Scintilla
A patch to Scintilla 2.29 containing our changes to Scintilla
(removing unused lexers and an updated marshallers file).
diff -Naur scintilla_orig/gtk/scintilla-marshal.c scintilla/gtk/scintilla-marshal.c
--- scintilla_orig/gtk/scintilla-marshal.c 2010-10-27 23:15:45.000000000 +0200

View File

@ -100,7 +100,7 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int ends[numEnds + 2];
for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
(IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;

View File

@ -168,6 +168,14 @@ bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible
}
}
bool ContractionState::HiddenLines() const {
if (OneToOne()) {
return false;
} else {
return !visible->AllSameAs(1);
}
}
bool ContractionState::GetExpanded(int lineDoc) const {
if (OneToOne()) {
return true;
@ -223,7 +231,7 @@ int ContractionState::GetHeight(int lineDoc) const {
bool ContractionState::SetHeight(int lineDoc, int height) {
if (OneToOne() && (height == 1)) {
return false;
} else {
} else if (lineDoc < LinesInDoc()) {
EnsureData();
if (GetHeight(lineDoc) != height) {
if (GetVisible(lineDoc)) {
@ -236,6 +244,8 @@ bool ContractionState::SetHeight(int lineDoc, int height) {
Check();
return false;
}
} else {
return false;
}
}

View File

@ -48,6 +48,7 @@ public:
bool GetVisible(int lineDoc) const;
bool SetVisible(int lineDocStart, int lineDocEnd, bool visible);
bool HiddenLines() const;
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);

View File

@ -28,7 +28,7 @@ Decoration::~Decoration() {
}
bool Decoration::Empty() {
return rs.starts->Partitions() == 1;
return rs.Runs() == 1;
}
DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0),
@ -126,9 +126,13 @@ bool DecorationList::FillRange(int &position, int value, int &fillLength) {
}
void DecorationList::InsertSpace(int position, int insertLength) {
const bool atEnd = position == lengthDocument;
lengthDocument += insertLength;
for (Decoration *deco=root; deco; deco = deco->next) {
deco->rs.InsertSpace(position, insertLength);
if (atEnd) {
deco->rs.FillRange(position, 0, insertLength);
}
}
}

View File

@ -2,7 +2,7 @@
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
@ -87,10 +87,10 @@ void LexInterface::Colourise(int start, int end) {
Document::Document() {
refCount = 0;
#ifdef __unix__
eolMode = SC_EOL_LF;
#else
#ifdef _WIN32
eolMode = SC_EOL_CRLF;
#else
eolMode = SC_EOL_LF;
#endif
dbcsCodePage = 0;
stylingBits = 5;
@ -316,15 +316,18 @@ static bool IsSubordinate(int levelStart, int levelTry) {
return (levelStart & SC_FOLDLEVELNUMBERMASK) < (levelTry & SC_FOLDLEVELNUMBERMASK);
}
int Document::GetLastChild(int lineParent, int level) {
int Document::GetLastChild(int lineParent, int level, int lastLine) {
if (level == -1)
level = GetLevel(lineParent) & SC_FOLDLEVELNUMBERMASK;
int maxLine = LinesTotal();
int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1;
int lineMaxSubord = lineParent;
while (lineMaxSubord < maxLine - 1) {
EnsureStyledTo(LineStart(lineMaxSubord + 2));
if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1)))
break;
if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG))
break;
lineMaxSubord++;
}
if (lineMaxSubord > lineParent) {
@ -355,6 +358,76 @@ int Document::GetFoldParent(int line) {
}
}
void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) {
int level = GetLevel(line);
int lookLastLine = Platform::Maximum(line, lastLine) + 1;
int lookLine = line;
int lookLineLevel = level;
int lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) ||
((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))))) {
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine);
if (beginFoldBlock == -1) {
highlightDelimiter.Clear();
return;
}
int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine);
int firstChangeableLineBefore = -1;
if (endFoldBlock < line) {
lookLine = beginFoldBlock - 1;
lookLineLevel = GetLevel(lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) {
if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) {
if (GetLastChild(lookLine, -1, lookLastLine) == line) {
beginFoldBlock = lookLine;
endFoldBlock = line;
firstChangeableLineBefore = line - 1;
}
}
if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && ((GetLevel(lookLine - 1) & SC_FOLDLEVELNUMBERMASK) > lookLineLevelNum))
break;
lookLineLevel = GetLevel(--lookLine);
lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
}
}
if (firstChangeableLineBefore == -1) {
for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine >= beginFoldBlock;
lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > (level & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineBefore = lookLine;
break;
}
}
}
if (firstChangeableLineBefore == -1)
firstChangeableLineBefore = beginFoldBlock - 1;
int firstChangeableLineAfter = -1;
for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK;
lookLine <= endFoldBlock;
lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = lookLineLevel & SC_FOLDLEVELNUMBERMASK) {
if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < (GetLevel(lookLine + 1) & SC_FOLDLEVELNUMBERMASK))) {
firstChangeableLineAfter = lookLine;
break;
}
}
if (firstChangeableLineAfter == -1)
firstChangeableLineAfter = endFoldBlock + 1;
highlightDelimiter.beginFoldBlock = beginFoldBlock;
highlightDelimiter.endFoldBlock = endFoldBlock;
highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore;
highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter;
}
int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length());
}
@ -589,7 +662,8 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
case 932:
// Shift_jis
return ((uch >= 0x81) && (uch <= 0x9F)) ||
((uch >= 0xE0) && (uch <= 0xEF));
((uch >= 0xE0) && (uch <= 0xFC));
// Lead bytes F0 to FC may be a Microsoft addition.
case 936:
// GBK
return (uch >= 0x81) && (uch <= 0xFE);
@ -609,6 +683,55 @@ bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
return false;
}
inline bool IsSpaceOrTab(int ch) {
return ch == ' ' || ch == '\t';
}
// Need to break text into segments near lengthSegment but taking into
// account the encoding to not break inside a UTF-8 or DBCS character
// and also trying to avoid breaking inside a pair of combining characters.
// The segment length must always be long enough (more than 4 bytes)
// so that there will be at least one whole character to make a segment.
// For UTF-8, text must consist only of valid whole characters.
// In preference order from best to worst:
// 1) Break after space
// 2) Break before punctuation
// 3) Break after whole character
int Document::SafeSegment(const char *text, int length, int lengthSegment) {
if (length <= lengthSegment)
return length;
int lastSpaceBreak = -1;
int lastPunctuationBreak = -1;
int lastEncodingAllowedBreak = -1;
for (int j=0; j < lengthSegment;) {
unsigned char ch = static_cast<unsigned char>(text[j]);
if (j > 0) {
if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
lastSpaceBreak = j;
}
if (ch < 'A') {
lastPunctuationBreak = j;
}
}
lastEncodingAllowedBreak = j;
if (dbcsCodePage == SC_CP_UTF8) {
j += (ch < 0x80) ? 1 : BytesFromLead(ch);
} else if (dbcsCodePage) {
j += IsDBCSLeadByte(ch) ? 2 : 1;
} else {
j++;
}
}
if (lastSpaceBreak >= 0) {
return lastSpaceBreak;
} else if (lastPunctuationBreak >= 0) {
return lastPunctuationBreak;
}
return lastEncodingAllowedBreak;
}
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
@ -833,7 +956,7 @@ bool Document::InsertChar(int pos, char ch) {
* Insert a null terminated string.
*/
bool Document::InsertCString(int position, const char *s) {
return InsertString(position, s, strlen(s));
return InsertString(position, s, static_cast<int>(strlen(s)));
}
void Document::ChangeChar(int pos, char ch) {
@ -990,17 +1113,17 @@ void Document::Indent(bool forwards, int lineBottom, int lineTop) {
// Convert line endings for a piece of text to a particular mode.
// Stop at len or when a NUL is found.
// Caller must delete the returned pointer.
char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode) {
char *Document::TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted) {
char *dest = new char[2 * len + 1];
const char *sptr = s;
char *dptr = dest;
for (size_t i = 0; (i < len) && (*sptr != '\0'); i++) {
if (*sptr == '\n' || *sptr == '\r') {
if (eolMode == SC_EOL_CR) {
if (eolModeWanted == SC_EOL_CR) {
*dptr++ = '\r';
} else if (eolMode == SC_EOL_LF) {
} else if (eolModeWanted == SC_EOL_LF) {
*dptr++ = '\n';
} else { // eolMode == SC_EOL_CRLF
} else { // eolModeWanted == SC_EOL_CRLF
*dptr++ = '\r';
*dptr++ = '\n';
}
@ -1232,7 +1355,7 @@ size_t Document::ExtractChar(int pos, char *bytes) {
size_t widthChar = UTF8CharLength(ch);
bytes[0] = ch;
for (size_t i=1; i<widthChar; i++) {
bytes[i] = cb.CharAt(pos+i);
bytes[i] = cb.CharAt(static_cast<int>(pos+i));
if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte
widthChar = 1;
}
@ -1305,7 +1428,6 @@ long Document::FindText(int minPos, int maxPos, const char *search,
// Compute actual search ranges needed
const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length;
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
const int limitPos = Platform::Maximum(startPos, endPos);
@ -1315,6 +1437,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
pos = NextPosition(pos, increment);
}
if (caseSensitive) {
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
bool found = (pos + lengthFind) <= limitPos;
for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
@ -1330,8 +1453,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 4;
const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
const int lenSearch = static_cast<int>(
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int widthFirstCharacter = 0;
int indexDocument = 0;
int indexSearch = 0;
@ -1341,11 +1465,13 @@ long Document::FindText(int minPos, int maxPos, const char *search,
(indexSearch < lenSearch)) {
char bytes[maxBytesCharacter + 1];
bytes[maxBytesCharacter] = 0;
const int widthChar = ExtractChar(pos + indexDocument, bytes);
const int widthChar = static_cast<int>(ExtractChar(pos + indexDocument, bytes));
if (!widthFirstCharacter)
widthFirstCharacter = widthChar;
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0;
// Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1369,8 +1495,9 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const size_t maxBytesCharacter = 2;
const size_t maxFoldingExpansion = 4;
std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
const int lenSearch = static_cast<int>(
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind));
while (forward ? (pos < endPos) : (pos >= endPos)) {
int indexDocument = 0;
int indexSearch = 0;
bool characterMatches = true;
@ -1382,8 +1509,10 @@ long Document::FindText(int minPos, int maxPos, const char *search,
const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
if (widthChar == 2)
bytes[1] = cb.CharAt(pos + indexDocument + 1);
if ((pos + indexDocument + widthChar) > limitPos)
break;
char folded[maxBytesCharacter * maxFoldingExpansion + 1];
const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
const int lenFlat = static_cast<int>(pcf->Fold(folded, sizeof(folded), bytes, widthChar));
folded[lenFlat] = 0;
// Does folded match the buffer
characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
@ -1400,7 +1529,7 @@ long Document::FindText(int minPos, int maxPos, const char *search,
break;
}
} else {
CaseFolderTable caseFolder;
const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
std::vector<char> searchThing(lengthFind + 1);
pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
while (forward ? (pos < endSearch) : (pos >= endSearch)) {
@ -1950,10 +2079,17 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
// the start position is at end of line or between line end characters.
lineRangeStart++;
startPos = doc->LineStart(lineRangeStart);
} else if ((increment == -1) &&
(startPos <= doc->LineStart(lineRangeStart)) &&
(lineRangeStart > lineRangeEnd)) {
// the start position is at beginning of line.
lineRangeStart--;
startPos = doc->LineEnd(lineRangeStart);
}
int pos = -1;
int lenRet = 0;
char searchEnd = s[*length - 1];
char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0';
int lineRangeBreak = lineRangeEnd + increment;
for (int line = lineRangeStart; line != lineRangeBreak; line += increment) {
int startOfLine = doc->LineStart(line);
@ -1965,7 +2101,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = startPos;
}
if (line == lineRangeEnd) {
if ((endPos != endOfLine) && (searchEnd == '$'))
if ((endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if end position before end of line
endOfLine = endPos;
}
@ -1976,7 +2112,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
startOfLine = endPos;
}
if (line == lineRangeStart) {
if ((startPos != endOfLine) && (searchEnd == '$'))
if ((startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\'))
continue; // Can't match end of line if start position before end of line
endOfLine = startPos;
}
@ -1987,7 +2123,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) {
pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0];
if (increment == -1) {
// There can be only one start of a line, so no need to look for last match in line
if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {

View File

@ -2,7 +2,7 @@
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
@ -115,6 +115,46 @@ struct StyledText {
}
};
class HighlightDelimiter {
public:
HighlightDelimiter() : isEnabled(false) {
Clear();
}
void Clear() {
beginFoldBlock = -1;
endFoldBlock = -1;
firstChangeableLineBefore = -1;
firstChangeableLineAfter = -1;
}
bool NeedsDrawing(int line) {
return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter);
}
bool IsFoldBlockHighlighted(int line) {
return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
}
bool IsHeadOfFoldBlock(int line) {
return beginFoldBlock == line && line < endFoldBlock;
}
bool IsBodyOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
}
bool IsTailOfFoldBlock(int line) {
return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
}
int beginFoldBlock; // Begin of current fold block
int endFoldBlock; // End of current fold block
int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block
int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block
bool isEnabled;
};
class CaseFolder {
public:
virtual ~CaseFolder() {
@ -234,6 +274,7 @@ public:
bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
int SCI_METHOD CodePage() const;
bool SCI_METHOD IsDBCSLeadByte(char ch) const;
int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document
void ModifiedAt(int pos);
@ -262,7 +303,7 @@ public:
int GetColumn(int position);
int FindColumn(int line, int column);
void Indent(bool forwards, int lineBottom, int lineTop);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolMode);
static char *TransformLineEnds(int *pLenOut, const char *s, size_t len, int eolModeWanted);
void ConvertLineEnds(int eolModeSet);
void SetReadOnly(bool set) { cb.SetReadOnly(set); }
bool IsReadOnly() { return cb.IsReadOnly(); }
@ -297,8 +338,9 @@ public:
int SCI_METHOD SetLevel(int line, int level);
int SCI_METHOD GetLevel(int line) const;
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetLastChild(int lineParent, int level=-1, int lastLine=-1);
int GetFoldParent(int line);
void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
/** @file Editor.h
** Defines the main editor class.
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
@ -131,6 +131,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
* When a style attribute is changed, this cache is flushed. */
bool stylesValid;
ViewStyle vs;
Point sizeRGBAImage;
Palette palette;
int printMagnification;
@ -139,6 +140,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
int cursorMode;
int controlCharSymbol;
// Highlight current folding block
HighlightDelimiter highlightDelimiter;
bool hasFocus;
bool hideSelection;
bool inOverstrike;
@ -160,6 +164,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool verticalScrollBarVisible;
bool endAtLastLine;
int caretSticky;
int marginOptions;
bool multipleSelection;
bool additionalSelectionTyping;
int multiPasteMode;
@ -191,7 +196,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int dwellDelay;
int ticksToDwell;
bool dwelling;
enum { selChar, selWord, selLine } selectionType;
enum { selChar, selWord, selSubLine, selWholeLine } selectionType;
Point ptMouseLast;
enum { ddNone, ddInitial, ddDragging } inDragDrop;
bool dropWentOutside;
@ -199,7 +204,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
SelectionPosition posDrop;
int hotSpotClickPos;
int lastXChosen;
int lineAnchor;
int lineAnchorPos;
int originalAnchorPos;
int wordSelectAnchorStartPos;
int wordSelectAnchorEndPos;
@ -332,6 +337,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
void VerticalCentreCaret();
void MoveSelectedLines(int lineDelta);
void MoveSelectedLinesUp();
void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
@ -367,6 +375,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour);
void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@ -413,6 +423,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyChange() = 0;
virtual void NotifyFocus(bool focus);
virtual void SetCtrlID(int identifier);
virtual int GetCtrlID() { return ctrlID; }
virtual void NotifyParent(SCNotification scn) = 0;
virtual void NotifyStyleToNeeded(int endStyleNeeded);
@ -455,6 +466,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int StartEndDisplayLine(int pos, bool start);
virtual int KeyCommand(unsigned int iMessage);
virtual int KeyDefault(int /* key */, int /*modifiers*/);
int KeyDownWithModifiers(int key, int modifiers, bool *consumed);
int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0);
int GetWhitespaceVisible();
@ -484,7 +496,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
Window::Cursor GetMarginCursor(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine);
void WordSelection(int pos);
void DwellEnd(bool mouseMoved);
void MouseLeave();

View File

@ -5,9 +5,17 @@
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <vector>
#include <map>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include "Platform.h"
#include "Scintilla.h"
#include "XPM.h"
#include "Indicator.h"
#ifdef SCI_NAMESPACE
@ -27,6 +35,17 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
y = 2 - y;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_SQUIGGLELOW) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 3;
int y = 0;
while (x < rc.right) {
surface->LineTo(x-1, rc.top + y);
y = 1 - y;
surface->LineTo(x, rc.top + y);
x += 3;
}
surface->LineTo(rc.right, rc.top + y); // Finish the line
} else if (style == INDIC_TT) {
surface->MoveTo(rc.left, ymid);
int x = rc.left + 5;
@ -67,12 +86,47 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
} else if (style == INDIC_ROUNDBOX) {
} else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 0);
} else if (style == INDIC_DOTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
// Cap width at 4000 to avoid large allocations when mistakes made
int width = Platform::Minimum(rcBox.Width(), 4000);
RGBAImage image(width, rcBox.Height(), 0);
// Draw horizontal lines top and bottom
for (int x=0; x<width; x++) {
for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
// Draw vertical lines left and right
for (int y=1; y<rcBox.Height(); y++) {
for (int x=0; x<width; x += width-1) {
image.SetPixel(x, y, fore.desired, ((x + y) % 2) ? outlineAlpha : fillAlpha);
}
}
surface->DrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels());
} else if (style == INDIC_DASH) {
int x = rc.left;
while (x < rc.right) {
surface->MoveTo(x, ymid);
surface->LineTo(Platform::Minimum(x + 4, rc.right), ymid);
x += 7;
}
} else if (style == INDIC_DOTS) {
int x = rc.left;
while (x < rc.right) {
PRectangle rcDot(x, ymid, x+1, ymid+1);
surface->FillRectangle(rcDot, fore.allocated);
x += 2;
}
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);

View File

@ -20,7 +20,8 @@ public:
bool under;
ColourPair fore;
int fillAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
int outlineAlpha;
Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};

View File

@ -66,14 +66,42 @@ unsigned int KeyMap::Find(int key, int modifiers) {
return 0;
}
#if PLAT_GTK_MACOSX
#define OS_X_KEYS 1
#else
#define OS_X_KEYS 0
#endif
// Define a modifier that is exactly Ctrl key on all platforms
// Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META
#if OS_X_KEYS
#define SCI_CTRL_META SCI_META
#define SCI_SCTRL_META (SCI_META | SCI_SHIFT)
#else
#define SCI_CTRL_META SCI_CTRL
#define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT)
#endif
const KeyToCommand KeyMap::MapDefault[] = {
#if OS_X_KEYS
{SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_VCHOME},
{SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_LINEEND},
{SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND},
#endif
{SCK_DOWN, SCI_NORM, SCI_LINEDOWN},
{SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND},
{SCK_DOWN, SCI_CTRL, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN},
{SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND},
{SCK_UP, SCI_NORM, SCI_LINEUP},
{SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND},
{SCK_UP, SCI_CTRL, SCI_LINESCROLLUP},
{SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP},
{SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND},
{'[', SCI_CTRL, SCI_PARAUP},
{'[', SCI_CSHIFT, SCI_PARAUPEXTEND},
@ -81,13 +109,13 @@ const KeyToCommand KeyMap::MapDefault[] = {
{']', SCI_CSHIFT, SCI_PARADOWNEXTEND},
{SCK_LEFT, SCI_NORM, SCI_CHARLEFT},
{SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND},
{SCK_LEFT, SCI_CTRL, SCI_WORDLEFT},
{SCK_LEFT, SCI_CSHIFT, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT},
{SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND},
{SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND},
{SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT},
{SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_CSHIFT, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT},
{SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND},
{SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND},
{'/', SCI_CTRL, SCI_WORDPARTLEFT},
{'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND},
@ -98,14 +126,12 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART},
{SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND},
{SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY},
// {SCK_HOME, SCI_ASHIFT, SCI_HOMEDISPLAYEXTEND},
{SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND},
{SCK_END, SCI_NORM, SCI_LINEEND},
{SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND},
{SCK_END, SCI_CTRL, SCI_DOCUMENTEND},
{SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND},
{SCK_END, SCI_ALT, SCI_LINEENDDISPLAY},
// {SCK_END, SCI_ASHIFT, SCI_LINEENDDISPLAYEXTEND},
{SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND},
{SCK_PRIOR, SCI_NORM, SCI_PAGEUP},
{SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND},
@ -127,7 +153,11 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_BACK, SCI_ALT, SCI_UNDO},
{SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT},
{'Z', SCI_CTRL, SCI_UNDO},
#if OS_X_KEYS
{'Z', SCI_CSHIFT, SCI_REDO},
#else
{'Y', SCI_CTRL, SCI_REDO},
#endif
{'X', SCI_CTRL, SCI_CUT},
{'C', SCI_CTRL, SCI_COPY},
{'V', SCI_CTRL, SCI_PASTE},
@ -139,7 +169,6 @@ const KeyToCommand KeyMap::MapDefault[] = {
{SCK_ADD, SCI_CTRL, SCI_ZOOMIN},
{SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT},
{SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM},
//'L', SCI_CTRL, SCI_FORMFEED,
{'L', SCI_CTRL, SCI_LINECUT},
{'L', SCI_CSHIFT, SCI_LINEDELETE},
{'T', SCI_CSHIFT, SCI_LINECOPY},

View File

@ -16,6 +16,7 @@ namespace Scintilla {
#define SCI_SHIFT SCMOD_SHIFT
#define SCI_CTRL SCMOD_CTRL
#define SCI_ALT SCMOD_ALT
#define SCI_META SCMOD_META
#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT)
#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT)

View File

@ -2,11 +2,14 @@
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
#include <vector>
#include <map>
#include "Platform.h"
#include "Scintilla.h"
@ -20,6 +23,7 @@ using namespace Scintilla;
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want);
pal.WantFind(back, want);
pal.WantFind(backSelected, want);
if (pxpm) {
pxpm->RefreshColourPalette(pal, want);
}
@ -37,6 +41,12 @@ void LineMarker::SetXPM(const char *const *linesForm) {
markType = SC_MARK_PIXMAP;
}
void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
delete image;
image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
markType = SC_MARK_RGBAIMAGE;
}
static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourAllocated fore, ColourAllocated back) {
PRectangle rc;
rc.left = centreX - armSize;
@ -67,11 +77,39 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore);
}
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
ColourPair head = back;
ColourPair body = back;
ColourPair tail = back;
switch (tFold) {
case LineMarker::head :
case LineMarker::headWithTail :
head = backSelected;
tail = backSelected;
break;
case LineMarker::body :
head = backSelected;
body = backSelected;
break;
case LineMarker::tail :
body = backSelected;
tail = backSelected;
break;
default :
// LineMarker::undefined
break;
}
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
}
if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
surface->DrawRGBAImage(rcWhole, image->GetWidth(), image->GetHeight(), image->Pixels());
return;
}
// Restrict most shapes a bit
PRectangle rc = rcWhole;
rc.top++;
@ -159,106 +197,145 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
surface->PenColour(back.allocated);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNER) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2 + 1);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNERCURVE) {
surface->PenColour(back.allocated);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNERCURVE) {
surface->PenColour(back.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-2);
surface->PenColour(head.allocated);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXPLUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
if (tFold == LineMarker::headWithTail)
surface->PenColour(tail.allocated);
else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_BOXMINUS) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_BOXMINUS) {
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
surface->PenColour(back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
if (tFold == LineMarker::body) {
surface->PenColour(tail.allocated);
surface->MoveTo(centreX + 1, centreY + blobSize);
surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
surface->MoveTo(centreX + blobSize, centreY + blobSize);
surface->LineTo(centreX + blobSize, centreY - blobSize);
surface->MoveTo(centreX + 1, centreY - blobSize);
surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
}
} else if (markType == SC_MARK_CIRCLEPLUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
if (tFold == LineMarker::headWithTail)
surface->PenColour(tail.allocated);
else
surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEMINUS) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
surface->PenColour(back.allocated);
DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);

View File

@ -2,7 +2,7 @@
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
// Copyright 1998-2011 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
@ -12,47 +12,61 @@
namespace Scintilla {
#endif
/**
*/
class LineMarker {
public:
enum typeOfFold { undefined, head, body, tail, headWithTail };
int markType;
ColourPair fore;
ColourPair back;
ColourPair backSelected;
int alpha;
XPM *pxpm;
RGBAImage *image;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
image = NULL;
}
LineMarker(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real copy constructor
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
image = NULL;
}
~LineMarker() {
delete pxpm;
delete image;
}
LineMarker &operator=(const LineMarker &) {
// Defined to avoid pxpm being blindly copied, not as real assignment operator
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
delete pxpm;
pxpm = NULL;
delete image;
image = NULL;
return *this;
}
void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
};
#ifdef SCI_NAMESPACE

View File

@ -425,10 +425,10 @@ void LineAnnotation::SetText(int line, const char *text) {
if (annotations[line]) {
delete []annotations[line];
}
annotations[line] = AllocateAnnotation(strlen(text), style);
annotations[line] = AllocateAnnotation(static_cast<int>(strlen(text)), style);
AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
pah->style = static_cast<short>(style);
pah->length = strlen(text);
pah->length = static_cast<int>(strlen(text));
pah->lines = static_cast<short>(NumberLines(text));
memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length);
} else {

View File

@ -12,6 +12,7 @@
#include <string>
#include <vector>
#include <map>
#include "Platform.h"
@ -151,15 +152,15 @@ void LineLayout::SetLineStart(int line, int start) {
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight) {
if (rangeLine.ContainsCharacter(braces[0])) {
char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle;
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset];
@ -172,14 +173,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
}
}
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
if (rangeLine.ContainsCharacter(braces[0])) {
void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0];
}
}
if (rangeLine.ContainsCharacter(braces[1])) {
if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1];
@ -391,18 +392,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1;
}
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
utf8(utf8_),
nextBreak(lineStart_),
saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
subBreak(-1) {
subBreak(-1),
pdoc(pdoc_) {
saeSize = 8;
selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) {
@ -435,7 +437,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
if (utf8) {
if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0;
for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@ -456,10 +458,6 @@ int BreakFinder::First() const {
return nextBreak;
}
static bool IsTrailByte(int ch) {
return (ch >= 0x80) && (ch < (0x80 + 0x40));
}
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
@ -490,34 +488,7 @@ int BreakFinder::Next() {
subBreak = -1;
return nextBreak;
} else {
int lastGoodBreak = -1;
int lastOKBreak = -1;
int lastUTF8Break = -1;
int j;
for (j = subBreak + 1; j <= nextBreak; j++) {
if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
lastGoodBreak = j;
}
if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
lastOKBreak = j;
}
if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
lastUTF8Break = j;
}
if (((j - subBreak) >= lengthEachSubdivision) &&
((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
break;
}
}
if (lastGoodBreak >= 0) {
subBreak = lastGoodBreak;
} else if (lastOKBreak >= 0) {
subBreak = lastOKBreak;
} else if (lastUTF8Break >= 0) {
subBreak = lastUTF8Break;
} else {
subBreak = nextBreak;
}
subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
if (subBreak >= nextBreak) {
subBreak = -1;
return nextBreak;
@ -571,16 +542,16 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
}
}
int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned int len) {
int PositionCacheEntry::Hash(unsigned int styleNumber_, const char *s, unsigned int len_) {
unsigned int ret = s[0] << 7;
for (unsigned int i=0; i<len; i++) {
for (unsigned int i=0; i<len_; i++) {
ret *= 1000003;
ret ^= s[i];
}
ret *= 1000003;
ret ^= len;
ret ^= len_;
ret *= 1000003;
ret ^= styleNumber;
ret ^= styleNumber_;
return ret;
}
@ -624,7 +595,8 @@ void PositionCache::SetSize(size_t size_) {
}
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions) {
const char *s, unsigned int len, int *positions, Document *pdoc) {
allClear = false;
int probe = -1;
if ((size > 0) && (len < 30)) {
@ -633,11 +605,11 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
// Two way associative: try two probe positions.
int hashValue = PositionCacheEntry::Hash(styleNumber, s, len);
probe = hashValue % size;
probe = static_cast<int>(hashValue % size);
if (pces[probe].Retrieve(styleNumber, s, len, positions)) {
return;
}
int probe2 = (hashValue * 37) % size;
int probe2 = static_cast<int>((hashValue * 37) % size);
if (pces[probe2].Retrieve(styleNumber, s, len, positions)) {
return;
}
@ -646,7 +618,22 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
probe = probe2;
}
}
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
if (len > BreakFinder::lengthStartSubdivision) {
// Break up into segments
unsigned int startSegment = 0;
int xStartSegment = 0;
while (startSegment < len) {
unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
positions[startSegment + inSeg] += xStartSegment;
}
xStartSegment = positions[startSegment + lenSegment - 1];
startSegment += lenSegment;
}
} else {
surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
}
if (probe >= 0) {
clock++;
if (clock > 60000) {

View File

@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const;
void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[],
char bracesMatchStyle, int xHighlight);
void RestoreBracesHighlight(Range rangeLine, Position braces[]);
char bracesMatchStyle, int xHighlight, bool ignoreStyle);
void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const;
};
@ -110,23 +110,17 @@ public:
void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_, unsigned int clock);
void Clear();
bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
static int Hash(unsigned int styleNumber, const char *s, unsigned int len);
static int Hash(unsigned int styleNumber_, const char *s, unsigned int len);
bool NewerThan(const PositionCacheEntry &other) const;
void ResetClock();
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
LineLayout *ll;
int lineStart;
int lineEnd;
int posLineStart;
bool utf8;
int nextBreak;
int *selAndEdge;
unsigned int saeSize;
@ -134,9 +128,16 @@ class BreakFinder {
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
Document *pdoc;
void Insert(int val);
public:
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
enum { lengthStartSubdivision = 300 };
// Try to make each subdivided run lengthEachSubdivision or shorter.
enum { lengthEachSubdivision = 100 };
BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder();
int First() const;
int Next();
@ -152,9 +153,9 @@ public:
~PositionCache();
void Clear();
void SetSize(size_t size_);
int GetSize() const { return size; }
size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
const char *s, unsigned int len, int *positions);
const char *s, unsigned int len, int *positions, Document *pdoc);
};
inline bool IsSpaceOrTab(int ch) {

View File

@ -321,7 +321,7 @@ void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) {
}
}
const unsigned char escapeValue(unsigned char ch) {
unsigned char escapeValue(unsigned char ch) {
switch (ch) {
case 'a': return '\a';
case 'b': return '\b';
@ -888,10 +888,10 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
return NOTFOUND;
break;
case BOT:
bopat[*ap++] = lp;
bopat[static_cast<int>(*ap++)] = lp;
break;
case EOT:
eopat[*ap++] = lp;
eopat[static_cast<int>(*ap++)] = lp;
break;
case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))

View File

@ -21,7 +21,7 @@ using namespace Scintilla;
#endif
// Find the first run at a position
int RunStyles::RunFromPosition(int position) {
int RunStyles::RunFromPosition(int position) const {
int run = starts->PartitionFromPosition(position);
// Go to first element with this position
while ((run > 0) && (position == starts->PositionFromPartition(run-1))) {
@ -147,6 +147,8 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart);
runEnd = RunFromPosition(end);
RemoveRunIfEmpty(runEnd);
return true;
} else {
return false;
@ -216,3 +218,33 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
}
}
int RunStyles::Runs() const {
return starts->Partitions();
}
bool RunStyles::AllSame() const {
for (int run = 1; run < starts->Partitions(); run++) {
if (styles->ValueAt(run) != styles->ValueAt(run - 1))
return false;
}
return true;
}
bool RunStyles::AllSameAs(int value) const {
return AllSame() && (styles->ValueAt(0) == value);
}
int RunStyles::Find(int value, int start) const {
if (start < Length()) {
int run = start ? RunFromPosition(start) : 0;
if (styles->ValueAt(run) == value)
return start;
run++;
while (run < starts->Partitions()) {
if (styles->ValueAt(run) == value)
return starts->PositionFromPartition(run);
run++;
}
}
return -1;
}

View File

@ -15,10 +15,10 @@ namespace Scintilla {
#endif
class RunStyles {
public:
private:
Partitioning *starts;
SplitVector<int> *styles;
int RunFromPosition(int position);
int RunFromPosition(int position) const;
int SplitRun(int position);
void RemoveRun(int run);
void RemoveRunIfEmpty(int run);
@ -37,6 +37,10 @@ public:
void InsertSpace(int position, int insertLength);
void DeleteAll();
void DeleteRange(int position, int deleteLength);
int Runs() const;
bool AllSame() const;
bool AllSameAs(int value) const;
int Find(int value, int start) const;
};
#ifdef SCI_NAMESPACE

View File

@ -13,6 +13,7 @@
#include <string>
#include <vector>
#include <map>
#include "Platform.h"
@ -135,16 +136,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
AutoCompleteMove(1);
return 0;
case SCI_LINEUP:
AutoCompleteMove( -1);
AutoCompleteMove(-1);
return 0;
case SCI_PAGEDOWN:
AutoCompleteMove(5);
return 0;
case SCI_PAGEUP:
AutoCompleteMove( -5);
AutoCompleteMove(-5);
return 0;
case SCI_VCHOME:
AutoCompleteMove( -5000);
AutoCompleteMove(-5000);
return 0;
case SCI_LINEEND:
AutoCompleteMove(5000);
@ -204,7 +205,8 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
if (ac.chooseSingle && (listType == 0)) {
if (list && !strchr(list, ac.GetSeparator())) {
const char *typeSep = strchr(list, ac.GetTypesep());
size_t lenInsert = (typeSep) ? (typeSep-list) : strlen(list);
int lenInsert = typeSep ?
static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
if (ac.ignoreCase) {
SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered);
@ -349,6 +351,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.wParam = listType;
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
scn.position = firstPos;
scn.lParam = firstPos;
scn.text = selected;
NotifyParent(scn);
@ -392,7 +395,7 @@ int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
ac.lb->GetValue(item, selected, sizeof(selected));
if (buffer != NULL)
strcpy(buffer, selected);
return strlen(selected);
return static_cast<int>(strlen(selected));
}
}
if (buffer != NULL)
@ -759,6 +762,10 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
ac.lb->RegisterImage(wParam, reinterpret_cast<const char *>(lParam));
break;
case SCI_REGISTERRGBAIMAGE:
ac.lb->RegisterRGBAImage(wParam, sizeRGBAImage.x, sizeRGBAImage.y, reinterpret_cast<unsigned char *>(lParam));
break;
case SCI_CLEARREGISTEREDIMAGES:
ac.lb->ClearRegisteredImages();
break;

View File

@ -16,14 +16,51 @@
using namespace Scintilla;
#endif
Style::Style() {
aliasOfDefaultFont = true;
FontAlias::FontAlias() {
}
FontAlias::~FontAlias() {
SetID(0);
// ~Font will not release the actual font resource sine it is now 0
}
void FontAlias::MakeAlias(Font &fontOrigin) {
SetID(fontOrigin.GetID());
}
void FontAlias::ClearFont() {
SetID(0);
}
bool FontSpecification::EqualTo(const FontSpecification &other) const {
return bold == other.bold &&
italic == other.italic &&
size == other.size &&
characterSet == other.characterSet &&
fontName == other.fontName;
}
FontMeasurements::FontMeasurements() {
Clear();
}
void FontMeasurements::Clear() {
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
sizeZoomed = 2;
}
Style::Style() : FontSpecification() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false);
}
Style::Style(const Style &source) {
Style::Style(const Style &source) : FontSpecification(), FontMeasurements() {
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
0, 0, 0,
false, false, false, false, caseMixed, true, true, false);
@ -42,11 +79,6 @@ Style::Style(const Style &source) {
}
Style::~Style() {
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
const char *fontName_, int characterSet_,
bool bold_, bool italic_, bool eolFilled_,
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_;
back.desired = back_;
characterSet = characterSet_;
@ -87,79 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
aliasOfDefaultFont = false;
sizeZoomed = 2;
lineHeight = 2;
ascent = 1;
descent = 1;
externalLeading = 0;
aveCharWidth = 1;
spaceWidth = 1;
font.ClearFont();
FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
source.fore.desired,
source.back.desired,
source.size,
source.fontName,
source.characterSet,
source.bold,
source.italic,
source.eolFilled,
source.underline,
source.caseForce,
source.visible,
source.changeable,
source.hotspot);
}
bool Style::EquivalentFontTo(const Style *other) const {
if (bold != other->bold ||
italic != other->italic ||
size != other->size ||
characterSet != other->characterSet)
return false;
if (fontName == other->fontName)
return true;
if (!fontName)
return false;
if (!other->fontName)
return false;
return strcmp(fontName, other->fontName) == 0;
}
void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
if (aliasOfDefaultFont)
font.SetID(0);
else
font.Release();
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
aliasOfDefaultFont = defaultStyle &&
(EquivalentFontTo(defaultStyle) || !fontName);
if (aliasOfDefaultFont) {
font.SetID(defaultStyle->font.GetID());
} else if (fontName) {
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
} else {
font.SetID(0);
}
ascent = surface.Ascent(font);
descent = surface.Descent(font);
// Probably more typographically correct to include leading
// but that means more complex drawing as leading must be erased
//lineHeight = surface.ExternalLeading() + surface.Height();
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
void Style::Copy(Font &font_, const FontMeasurements &fm_) {
font.MakeAlias(font_);
#if PLAT_WX
font.SetAscent(fm_.ascent);
#endif
(FontMeasurements &)(*this) = fm_;
}

View File

@ -12,18 +12,54 @@
namespace Scintilla {
#endif
/**
*/
class Style {
public:
ColourPair fore;
ColourPair back;
bool aliasOfDefaultFont;
struct FontSpecification {
const char *fontName;
bool bold;
bool italic;
int size;
const char *fontName;
int characterSet;
int extraFontFlag;
FontSpecification() :
fontName(0),
bold(false),
italic(false),
size(10),
characterSet(0),
extraFontFlag(0) {
}
bool EqualTo(const FontSpecification &other) const;
};
// Just like Font but only has a copy of the FontID so should not delete it
class FontAlias : public Font {
// Private so FontAlias objects can not be copied
FontAlias(const FontAlias &);
FontAlias &operator=(const FontAlias &);
public:
FontAlias();
virtual ~FontAlias();
void MakeAlias(Font &fontOrigin);
void ClearFont();
};
struct FontMeasurements {
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
int sizeZoomed;
FontMeasurements();
void Clear();
};
/**
*/
class Style : public FontSpecification, public FontMeasurements {
public:
ColourPair fore;
ColourPair back;
bool eolFilled;
bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower};
@ -32,14 +68,7 @@ public:
bool changeable;
bool hotspot;
Font font;
int sizeZoomed;
unsigned int lineHeight;
unsigned int ascent;
unsigned int descent;
unsigned int externalLeading;
unsigned int aveCharWidth;
unsigned int spaceWidth;
FontAlias font;
Style();
Style(const Style &source);
@ -52,8 +81,7 @@ public:
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
bool EquivalentFontTo(const Style *other) const;
void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
void Copy(Font &font_, const FontMeasurements &fm_);
bool IsProtected() const { return !(changeable && visible);}
};

View File

@ -7,6 +7,9 @@
#include <string.h>
#include <vector>
#include <map>
#include "Platform.h"
#include "Scintilla.h"
@ -72,11 +75,66 @@ const char *FontNames::Save(const char *name) {
return names[max-1];
}
FontRealised::FontRealised(const FontSpecification &fs) {
frNext = NULL;
(FontSpecification &)(*this) = fs;
}
FontRealised::~FontRealised() {
font.Release();
delete frNext;
frNext = 0;
}
void FontRealised::Realise(Surface &surface, int zoomLevel) {
PLATFORM_ASSERT(fontName);
sizeZoomed = size + zoomLevel;
if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
sizeZoomed = 2;
int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
ascent = surface.Ascent(font);
descent = surface.Descent(font);
externalLeading = surface.ExternalLeading(font);
lineHeight = surface.Height(font);
aveCharWidth = surface.AverageCharWidth(font);
spaceWidth = surface.WidthChar(font, ' ');
if (frNext) {
frNext->Realise(surface, zoomLevel);
}
}
FontRealised *FontRealised::Find(const FontSpecification &fs) {
if (!fs.fontName)
return this;
FontRealised *fr = this;
while (fr) {
if (fr->EqualTo(fs))
return fr;
fr = fr->frNext;
}
return 0;
}
void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
FontRealised *fr = this;
while (fr) {
if (maxAscent < fr->ascent)
maxAscent = fr->ascent;
if (maxDescent < fr->descent)
maxDescent = fr->descent;
fr = fr->frNext;
}
}
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
frFirst = NULL;
Init(source.stylesSize);
for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
@ -150,14 +208,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset;
braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
braceHighlightIndicator = source.braceHighlightIndicator;
braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
braceBadLightIndicator = source.braceBadLightIndicator;
}
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
delete frFirst;
frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
@ -255,6 +320,10 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0;
braceHighlightIndicatorSet = false;
braceHighlightIndicator = 0;
braceBadLightIndicatorSet = false;
braceBadLightIndicator = 0;
}
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
@ -290,33 +359,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want);
}
void ViewStyle::CreateFont(const FontSpecification &fs) {
if (fs.fontName) {
for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
if (cur->EqualTo(fs))
return;
if (!cur->frNext) {
cur->frNext = new FontRealised(fs);
return;
}
}
frFirst = new FontRealised(fs);
}
}
void ViewStyle::Refresh(Surface &surface) {
delete frFirst;
frFirst = NULL;
selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight();
styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
maxAscent = styles[STYLE_DEFAULT].ascent;
maxDescent = styles[STYLE_DEFAULT].descent;
for (unsigned int i=0; i<stylesSize; i++) {
styles[i].extraFontFlag = extraFontFlag;
}
CreateFont(styles[STYLE_DEFAULT]);
for (unsigned int j=0; j<stylesSize; j++) {
CreateFont(styles[j]);
}
frFirst->Realise(surface, zoomLevel);
for (unsigned int k=0; k<stylesSize; k++) {
FontRealised *fr = frFirst->Find(styles[k]);
styles[k].Copy(fr->font, *fr);
}
maxAscent = 1;
maxDescent = 1;
frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
someStylesProtected = false;
someStylesForceCase = false;
for (unsigned int i=0; i<stylesSize; i++) {
if (i != STYLE_DEFAULT) {
styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
if (maxAscent < styles[i].ascent)
maxAscent = styles[i].ascent;
if (maxDescent < styles[i].descent)
maxDescent = styles[i].descent;
}
if (styles[i].IsProtected()) {
for (unsigned int l=0; l<stylesSize; l++) {
if (styles[l].IsProtected()) {
someStylesProtected = true;
}
if (styles[i].caseForce != Style::caseMixed) {
if (styles[l].caseForce != Style::caseMixed) {
someStylesForceCase = true;
}
}
maxAscent += extraAscent;
maxDescent += extraDescent;
lineHeight = maxAscent + maxDescent;
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@ -361,10 +456,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
ColourDesired(0xff,0xff,0xff),
Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
SC_CHARSET_DEFAULT,
false, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {

View File

@ -39,6 +39,20 @@ public:
const char *Save(const char *name);
};
class FontRealised : public FontSpecification, public FontMeasurements {
// Private so FontRealised objects can not be copied
FontRealised(const FontRealised &);
FontRealised &operator=(const FontRealised &);
public:
Font font;
FontRealised *frNext;
FontRealised(const FontSpecification &fs);
virtual ~FontRealised();
void Realise(Surface &surface, int zoomLevel);
FontRealised *Find(const FontSpecification &fs);
void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
};
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@ -48,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle {
public:
FontNames fontNames;
FontRealised *frFirst;
size_t stylesSize;
Style *styles;
LineMarker markers[MARKER_MAX + 1];
@ -114,11 +129,16 @@ public:
int marginStyleOffset;
int annotationVisible;
int annotationStyleOffset;
bool braceHighlightIndicatorSet;
int braceHighlightIndicator;
bool braceBadLightIndicatorSet;
int braceBadLightIndicator;
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void Init(size_t stylesSize_=64);
void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);

View File

@ -8,6 +8,13 @@
#include <string.h>
#include <stdlib.h>
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <vector>
#include <map>
#include "Platform.h"
#include "XPM.h"
@ -38,6 +45,10 @@ static size_t MeasureLength(const char *s) {
return i;
}
ColourDesired XPM::ColourDesiredFromCode(int ch) const {
return colourCodeTable[ch]->desired;
}
ColourAllocated XPM::ColourFromCode(int ch) const {
return colourCodeTable[ch]->allocated;
#ifdef SLOW
@ -200,6 +211,21 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
}
}
void XPM::PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const {
if (!data || !codes || !colours || !lines || (x<0) || (x >= width) || (y<0) || (y >= height)) {
colour = 0;
transparent = true;
return;
}
int code = lines[y+nColours+1][x];
transparent = code == codeTransparent;
if (transparent) {
colour = 0;
} else {
colour = ColourDesiredFromCode(code).AsLong();
}
}
const char **XPM::LinesFormFromTextForm(const char *textForm) {
// Build the lines form out of the text form
const char **linesForm = 0;
@ -261,14 +287,14 @@ void XPMSet::Clear() {
width = -1;
}
void XPMSet::Add(int id, const char *textForm) {
void XPMSet::Add(int ident, const char *textForm) {
// Invalidate cached dimensions
height = -1;
width = -1;
// Replace if this id already present
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
if (set[i]->GetId() == ident) {
set[i]->Init(textForm);
set[i]->CopyDesiredColours();
return;
@ -278,7 +304,7 @@ void XPMSet::Add(int id, const char *textForm) {
// Not present, so add to end
XPM *pxpm = new XPM(textForm);
if (pxpm) {
pxpm->SetId(id);
pxpm->SetId(ident);
pxpm->CopyDesiredColours();
if (len == maximum) {
maximum += 64;
@ -294,9 +320,9 @@ void XPMSet::Add(int id, const char *textForm) {
}
}
XPM *XPMSet::Get(int id) {
XPM *XPMSet::Get(int ident) {
for (int i = 0; i < len; i++) {
if (set[i]->GetId() == id) {
if (set[i]->GetId() == ident) {
return set[i];
}
}
@ -324,3 +350,110 @@ int XPMSet::GetWidth() {
}
return (width > 0) ? width : 0;
}
RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
height(height_), width(width_) {
if (pixels_) {
pixelBytes.assign(pixels_, pixels_ + CountBytes());
} else {
pixelBytes.resize(CountBytes());
}
}
RGBAImage::RGBAImage(const XPM &xpm) {
height = xpm.GetHeight();
width = xpm.GetWidth();
pixelBytes.resize(CountBytes());
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
ColourDesired colour;
bool transparent = false;
xpm.PixelAt(x, y, colour, transparent);
SetPixel(x, y, colour, transparent ? 0 : 255);
}
}
}
RGBAImage::~RGBAImage() {
}
int RGBAImage::CountBytes() const {
return width * height * 4;
}
const unsigned char *RGBAImage::Pixels() const {
return &pixelBytes[0];
}
void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
// RGBA
pixel[0] = colour.GetRed();
pixel[1] = colour.GetGreen();
pixel[2] = colour.GetBlue();
pixel[3] = alpha;
}
RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
}
RGBAImageSet::~RGBAImageSet() {
Clear();
}
/// Remove all images.
void RGBAImageSet::Clear() {
for (ImageMap::iterator it=images.begin(); it != images.end(); ++it) {
delete it->second;
it->second = 0;
}
images.clear();
height = -1;
width = -1;
}
/// Add an image.
void RGBAImageSet::Add(int ident, RGBAImage *image) {
ImageMap::iterator it=images.find(ident);
if (it == images.end()) {
images[ident] = image;
} else {
delete it->second;
it->second = image;
}
height = -1;
width = -1;
}
/// Get image by id.
RGBAImage *RGBAImageSet::Get(int ident) {
ImageMap::iterator it = images.find(ident);
if (it != images.end()) {
return it->second;
}
return NULL;
}
/// Give the largest height of the set.
int RGBAImageSet::GetHeight() const {
if (height < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (height < it->second->GetHeight()) {
height = it->second->GetHeight();
}
}
}
return (height > 0) ? height : 0;
}
/// Give the largest width of the set.
int RGBAImageSet::GetWidth() const {
if (width < 0) {
for (ImageMap::const_iterator it=images.begin(); it != images.end(); ++it) {
if (width < it->second->GetWidth()) {
width = it->second->GetWidth();
}
}
}
return (width > 0) ? width : 0;
}

View File

@ -24,6 +24,7 @@ class XPM {
char codeTransparent;
char *codes;
ColourPair *colours;
ColourDesired ColourDesiredFromCode(int ch) const;
ColourAllocated ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines;
@ -46,6 +47,7 @@ public:
int GetId() const { return pid; }
int GetHeight() const { return height; }
int GetWidth() const { return width; }
void PixelAt(int x, int y, ColourDesired &colour, bool &transparent) const;
static const char **LinesFormFromTextForm(const char *textForm);
};
@ -64,15 +66,59 @@ public:
/// Remove all XPMs.
void Clear();
/// Add a XPM.
void Add(int id, const char *textForm);
void Add(int ident, const char *textForm);
/// Get XPM by id.
XPM *Get(int id);
XPM *Get(int ident);
/// Give the largest height of the set.
int GetHeight();
/// Give the largest width of the set.
int GetWidth();
};
/**
* An translucent image stoed as a sequence of RGBA bytes.
*/
class RGBAImage {
// Private so RGBAImage objects can not be copied
RGBAImage(const RGBAImage &);
RGBAImage &operator=(const RGBAImage &);
int height;
int width;
std::vector<unsigned char> pixelBytes;
public:
RGBAImage(int width_, int height_, const unsigned char *pixels_);
RGBAImage(const XPM &xpm);
virtual ~RGBAImage();
int GetHeight() const { return height; }
int GetWidth() const { return width; }
int CountBytes() const;
const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
};
/**
* A collection of RGBAImage pixmaps indexed by integer id.
*/
class RGBAImageSet {
typedef std::map<int, RGBAImage*> ImageMap;
ImageMap images;
mutable int height; ///< Memorize largest height of the set.
mutable int width; ///< Memorize largest width of the set.
public:
RGBAImageSet();
~RGBAImageSet();
/// Remove all images.
void Clear();
/// Add an image.
void Add(int ident, RGBAImage *image);
/// Get image by id.
RGBAImage *Get(int ident);
/// Give the largest height of the set.
int GetHeight() const;
/// Give the largest width of the set.
int GetWidth() const;
};
#ifdef SCI_NAMESPACE
}
#endif

View File

@ -1 +1 @@
225
229

View File

@ -1173,12 +1173,20 @@ static void styleset_erlang(ScintillaObject *sci, gint ft_id)
static void styleset_latex_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_styleset(ft_id, 5);
new_styleset(ft_id, 13);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "command", &style_sets[ft_id].styling[1]);
get_keyfile_style(config, config_home, "tag", &style_sets[ft_id].styling[2]);
get_keyfile_style(config, config_home, "math", &style_sets[ft_id].styling[3]);
get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[4]);
get_keyfile_style(config, config_home, "tag2", &style_sets[ft_id].styling[5]);
get_keyfile_style(config, config_home, "math2", &style_sets[ft_id].styling[6]);
get_keyfile_style(config, config_home, "comment2", &style_sets[ft_id].styling[7]);
get_keyfile_style(config, config_home, "verbatim", &style_sets[ft_id].styling[8]);
get_keyfile_style(config, config_home, "shortcmd", &style_sets[ft_id].styling[9]);
get_keyfile_style(config, config_home, "special", &style_sets[ft_id].styling[10]);
get_keyfile_style(config, config_home, "cmdopt", &style_sets[ft_id].styling[11]);
get_keyfile_style(config, config_home, "error", &style_sets[ft_id].styling[12]);
style_sets[ft_id].keywords = g_new(gchar*, 2);
get_keyfile_keywords(config, config_home, "primary", ft_id, 0);
@ -1198,6 +1206,14 @@ static void styleset_latex(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_L_TAG, ft_id, 2);
set_sci_style(sci, SCE_L_MATH, ft_id, 3);
set_sci_style(sci, SCE_L_COMMENT, ft_id, 4);
set_sci_style(sci, SCE_L_TAG2, ft_id, 5);
set_sci_style(sci, SCE_L_MATH2, ft_id, 6);
set_sci_style(sci, SCE_L_COMMENT2, ft_id, 7);
set_sci_style(sci, SCE_L_VERBATIM, ft_id, 8);
set_sci_style(sci, SCE_L_SHORTCMD, ft_id, 9);
set_sci_style(sci, SCE_L_SPECIAL, ft_id, 10);
set_sci_style(sci, SCE_L_CMDOPT, ft_id, 11);
set_sci_style(sci, SCE_L_ERROR, ft_id, 12);
}
@ -1495,7 +1511,7 @@ static void styleset_java(ScintillaObject *sci, gint ft_id)
static void styleset_perl_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_styleset(ft_id, 35);
new_styleset(ft_id, 45);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "error", &style_sets[ft_id].styling[1]);
get_keyfile_style(config, config_home, "commentline", &style_sets[ft_id].styling[2]);
@ -1531,6 +1547,16 @@ static void styleset_perl_init(gint ft_id, GKeyFile *config, GKeyFile *config_ho
get_keyfile_style(config, config_home, "sub_prototype", &style_sets[ft_id].styling[32]);
get_keyfile_style(config, config_home, "format_ident", &style_sets[ft_id].styling[33]);
get_keyfile_style(config, config_home, "format", &style_sets[ft_id].styling[34]);
get_keyfile_style(config, config_home, "string_var", &style_sets[ft_id].styling[35]);
get_keyfile_style(config, config_home, "xlat", &style_sets[ft_id].styling[36]);
get_keyfile_style(config, config_home, "regex_var", &style_sets[ft_id].styling[37]);
get_keyfile_style(config, config_home, "regsubst_var", &style_sets[ft_id].styling[38]);
get_keyfile_style(config, config_home, "backticks_var", &style_sets[ft_id].styling[39]);
get_keyfile_style(config, config_home, "here_qq_var", &style_sets[ft_id].styling[40]);
get_keyfile_style(config, config_home, "here_qx_var", &style_sets[ft_id].styling[41]);
get_keyfile_style(config, config_home, "string_qq_var", &style_sets[ft_id].styling[42]);
get_keyfile_style(config, config_home, "string_qx_var", &style_sets[ft_id].styling[43]);
get_keyfile_style(config, config_home, "string_qr_var", &style_sets[ft_id].styling[44]);
style_sets[ft_id].keywords = g_new(gchar*, 2);
@ -1581,6 +1607,16 @@ static void styleset_perl(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_PL_SUB_PROTOTYPE, ft_id, 32);
set_sci_style(sci, SCE_PL_FORMAT_IDENT, ft_id, 33);
set_sci_style(sci, SCE_PL_FORMAT, ft_id, 34);
set_sci_style(sci, SCE_PL_STRING_VAR, ft_id, 35);
set_sci_style(sci, SCE_PL_XLAT, ft_id, 36);
set_sci_style(sci, SCE_PL_REGEX_VAR, ft_id, 37);
set_sci_style(sci, SCE_PL_REGSUBST_VAR, ft_id, 38);
set_sci_style(sci, SCE_PL_BACKTICKS_VAR, ft_id, 39);
set_sci_style(sci, SCE_PL_HERE_QQ_VAR, ft_id, 40);
set_sci_style(sci, SCE_PL_HERE_QX_VAR, ft_id, 41);
set_sci_style(sci, SCE_PL_STRING_QQ_VAR, ft_id, 42);
set_sci_style(sci, SCE_PL_STRING_QX_VAR, ft_id, 43);
set_sci_style(sci, SCE_PL_STRING_QR_VAR, ft_id, 44);
}
@ -3065,7 +3101,7 @@ static void styleset_js(ScintillaObject *sci, gint ft_id)
static void styleset_lua_init(gint ft_id, GKeyFile *config, GKeyFile *config_home)
{
new_styleset(ft_id, 20);
new_styleset(ft_id, 21);
get_keyfile_style(config, config_home, "default", &style_sets[ft_id].styling[0]);
get_keyfile_style(config, config_home, "comment", &style_sets[ft_id].styling[1]);
@ -3087,6 +3123,7 @@ static void styleset_lua_init(gint ft_id, GKeyFile *config, GKeyFile *config_hom
get_keyfile_style(config, config_home, "word6", &style_sets[ft_id].styling[17]);
get_keyfile_style(config, config_home, "word7", &style_sets[ft_id].styling[18]);
get_keyfile_style(config, config_home, "word8", &style_sets[ft_id].styling[19]);
get_keyfile_style(config, config_home, "label", &style_sets[ft_id].styling[20]);
style_sets[ft_id].keywords = g_new(gchar*, 9);
get_keyfile_keywords(config, config_home, "keywords", ft_id, 0);
@ -3135,6 +3172,7 @@ static void styleset_lua(ScintillaObject *sci, gint ft_id)
set_sci_style(sci, SCE_LUA_WORD6, ft_id, 17);
set_sci_style(sci, SCE_LUA_WORD7, ft_id, 18);
set_sci_style(sci, SCE_LUA_WORD8, ft_id, 19);
set_sci_style(sci, SCE_LUA_LABEL, ft_id, 20);
}
@ -3726,7 +3764,7 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
style == SCE_F_STRINGEOL);
case SCLEX_PERL:
return (/*style == SCE_PL_STRING ||*/ /* may want variable autocompletion "$(foo)" */
return (style == SCE_PL_STRING ||
style == SCE_PL_CHARACTER ||
style == SCE_PL_HERE_DELIM ||
style == SCE_PL_HERE_Q ||
@ -3738,7 +3776,9 @@ gboolean highlighting_is_string_style(gint lexer, gint style)
style == SCE_PL_STRING_QX ||
style == SCE_PL_STRING_QR ||
style == SCE_PL_STRING_QW ||
style == SCE_PL_POD_VERB);
style == SCE_PL_POD_VERB ||
style == SCE_PL_XLAT
/* we don't include any STRING_*_VAR for autocompletion */);
case SCLEX_R:
return (style == SCE_R_STRING);
@ -3882,7 +3922,8 @@ gboolean highlighting_is_comment_style(gint lexer, gint style)
return (style == SCE_PO_COMMENT);
case SCLEX_LATEX:
return (style == SCE_L_COMMENT);
return (style == SCE_L_COMMENT ||
style == SCE_L_COMMENT2);
case SCLEX_MAKEFILE:
return (style == SCE_MAKE_COMMENT);