diff options
-rw-r--r-- | include/Scintilla.h | 6 | ||||
-rw-r--r-- | include/Scintilla.iface | 24 | ||||
-rw-r--r-- | src/Editor.cxx | 97 | ||||
-rw-r--r-- | src/Editor.h | 39 |
4 files changed, 98 insertions, 68 deletions
diff --git a/include/Scintilla.h b/include/Scintilla.h index 370aa6d50..fb099f9ec 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -436,6 +436,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SC_CURSORWAIT 3 #define SCI_SETCURSOR 2386 #define SCI_GETCURSOR 2387 +#define SCI_SETCONTROLCHARSYMBOL 2388 +#define SCI_GETCONTROLCHARSYMBOL 2389 #define SCI_WORDPARTLEFT 2390 #define SCI_WORDPARTLEFTEXTEND 2391 #define SCI_WORDPARTRIGHT 2392 @@ -532,7 +534,7 @@ struct TextToFind { #ifdef PLATFORM_H -// This structure is used in printing and requires some of the graphics types +// This structure is used in printing and requires some of the graphics types // from Platform.h. Not needed by most client code. struct RangeToFormat { @@ -549,7 +551,7 @@ struct NotifyHeader { // hwndFrom is really an environment specifc window handle or pointer // but most clients of Scintilla.h do not have this type visible. //WindowID hwndFrom; - void *hwndFrom; + void *hwndFrom; unsigned int idFrom; unsigned int code; }; diff --git a/include/Scintilla.iface b/include/Scintilla.iface index a1efb94e1..8e759c693 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -53,10 +53,10 @@ ## Client code should ignore definitions containing types it does not understand, except ## for possibly #defining the constants -## String arguments may contain NUL ('\0') characters where the calls provide a length -## argument and retrieve NUL characters. All retrieved strings except for those retrieved -## by GetLine also have a NUL appended but client code should calculate the size that -## will be returned rather than relying upon the NUL whenever possible. Allow for the +## String arguments may contain NUL ('\0') characters where the calls provide a length +## argument and retrieve NUL characters. All retrieved strings except for those retrieved +## by GetLine also have a NUL appended but client code should calculate the size that +## will be returned rather than relying upon the NUL whenever possible. Allow for the ## extra NUL character when allocating buffers. cat Basics @@ -144,7 +144,7 @@ set void SetViewWS=2021(int viewWS,) # Find the position from a point within the window. fun int PositionFromPoint=2022(int x, int y) -# Find the position from a point within the window but return +# Find the position from a point within the window but return # INVALID_POSITION if not close to text. fun int PositionFromPointClose=2023(int x, int y) @@ -761,14 +761,14 @@ set void SetCaretWidth=2188(int pixelWidth,) # Returns the width of the insert mode caret get int GetCaretWidth=2189(,) -# Sets the position that starts the target which is used for updating the +# Sets the position that starts the target which is used for updating the # document without affecting the scroll position. set void SetTargetStart=2190(position pos,) # Get the position that starts the target. get position GetTargetStart=2191(,) -# Sets the position that ends the target which is used for updating the +# Sets the position that ends the target which is used for updating the # document without affecting the scroll position. set void SetTargetEnd=2192(position pos,) @@ -782,7 +782,7 @@ fun int ReplaceTarget=2194(int length, string text) # Replace the target text with the argument text after \d processing. # Text is counted so it can contain nulls. -# Looks for \d where d is between 1 and 9 and replaces these with the strings +# Looks for \d where d is between 1 and 9 and replaces these with the strings # matched in the last search operation which were surrounded by \( and \). # Returns the length of the replacement text including any change # caused by processing the \d patterns. @@ -1168,6 +1168,12 @@ set void SetCursor=2386(int cursorType,) # Get cursor type get int GetCursor=2387(,) +# Change the way control characters are displayed: +# If symbol is < 32, keep the drawn way, else, use the given character +set void SetControlCharSymbol=2388(int symbol,) +# Get the way control characters are displayed +get int GetControlCharSymbol=2389(,) + # Move to the previous change in capitalistion fun void WordPartLeft=2390(,) # Move to the previous change in capitalistion extending selection to new caret position. @@ -1305,7 +1311,7 @@ val SCLEX_ASP=29 val SCLEX_PHP=30 val SCLEX_BAAN=31 -# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a +# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a # value assigned in sequence from SCLEX_AUTOMATIC+1. val SCLEX_AUTOMATIC=1000 # Lexical states for SCLEX_PYTHON diff --git a/src/Editor.cxx b/src/Editor.cxx index e852723b2..6c5ba7330 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -40,6 +40,7 @@ Editor::Editor() { printMagnification = 0; printColourMode = SC_PRINT_NORMAL; cursorMode = SC_CURSORNORMAL; + controlCharSymbol = 0; /* Draw the control characters */ hasFocus = false; hideSelection = false; @@ -87,7 +88,7 @@ Editor::Editor() { pixmapSelPattern = Surface::Allocate(); pixmapIndentGuide = Surface::Allocate(); pixmapIndentGuideHighlight = Surface::Allocate(); - + currentPos = 0; anchor = 0; @@ -284,7 +285,7 @@ int Editor::PositionFromLocation(Point pt) { surface->Init(); surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); unsigned int posLineStart = pdoc->LineStart(line); - + LineLayout ll; LayoutLine(line, surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { @@ -324,7 +325,7 @@ int Editor::PositionFromLocationClose(Point pt) { surface->Init(); surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); unsigned int posLineStart = pdoc->LineStart(line); - + LineLayout ll; LayoutLine(line, surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { @@ -350,7 +351,7 @@ int Editor::PositionFromLineX(int line, int x) { surface->Init(); surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); unsigned int posLineStart = pdoc->LineStart(line); - + LineLayout ll; LayoutLine(line, surface, vs, ll); for (int i = 0; i < ll.numCharsInLine; i++) { @@ -360,7 +361,7 @@ int Editor::PositionFromLineX(int line, int x) { return i + posLineStart; } } - + delete surface; return ll.numCharsInLine + posLineStart; } @@ -648,7 +649,7 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { // If we scroll the display, we use a minimum amount of xMargin. int offsetLeft = rcClient.left + xMargin; int offsetRight = rcClient.right - xMargin; - // If we are in XJUMPS mode, then when the margin is reached, the + // If we are in XJUMPS mode, then when the margin is reached, the // offset jumps so that it won't need to move agin for a while. if (!(caretPolicy & CARET_XJUMPS)) { rcClient.left = offsetLeft; @@ -779,10 +780,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { int line = cs.DocFromDisplay(visibleLine); int yposScreen = 0; - // Work out whether the top line is whitespace located after a + // Work out whether the top line is whitespace located after a // lessening of fold level which implies a 'fold tail' but which should not // be displayed until the last of a sequence of whitespace. - bool needWhiteClosure = false; + bool needWhiteClosure = false; int level = pdoc->GetLevel(line); if (level & SC_FOLDLEVELWHITEFLAG) { int lineBack = line; @@ -796,13 +797,13 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { needWhiteClosure = true; } } - + // Old code does not know about new markers needed to distinguish all cases - int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, + int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, SC_MARKNUM_FOLDEROPEN); - int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, + int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, SC_MARKNUM_FOLDER); - + while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) { // Decide which fold indicator should be displayed @@ -815,7 +816,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { if (cs.GetExpanded(line)) { if (levelNum == SC_FOLDLEVELBASE) marks |= 1 << SC_MARKNUM_FOLDEROPEN; - else + else marks |= 1 << folderOpenMid; } else { if (levelNum == SC_FOLDLEVELBASE) @@ -977,10 +978,14 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou if (ll.chars[charInLine] == '\t') { ll.positions[charInLine + 1] = ((((startsegx + 2) / tabWidth) + 1) * tabWidth) - startsegx; - } else { + } else if (controlCharSymbol < 32) { const char *ctrlChar = ControlCharacterString(ll.chars[charInLine]); // +3 For a blank on front and rounded edge each side: ll.positions[charInLine + 1] = surface->WidthText(ctrlCharsFont, ctrlChar, strlen(ctrlChar)) + 3; + } else { + char cc[2] = { controlCharSymbol, '\0' }; + surface->MeasureWidths(ctrlCharsFont, cc, 1, + ll.positions + startseg + 1); } lastSegItalics = false; } else { // Regular character @@ -1129,24 +1134,32 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis } else if (IsControlCharacter(ll.chars[i])) { // Manage control character display inIndentation = false; - const char *ctrlChar = ControlCharacterString(ll.chars[i]); - surface->FillRectangle(rcSegment, textBack); - int normalCharHeight = surface->Ascent(ctrlCharsFont) - - surface->InternalLeading(ctrlCharsFont); - PRectangle rcCChar = rcSegment; - rcCChar.left = rcCChar.left + 1; - rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; - rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; - PRectangle rcCentral = rcCChar; - rcCentral.top++; - rcCentral.bottom--; - surface->FillRectangle(rcCentral, textFore); - PRectangle rcChar = rcCChar; - rcChar.left++; - rcChar.right--; - surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), - textBack, textFore); + if (controlCharSymbol < 32) { + // Draw the character + const char *ctrlChar = ControlCharacterString(ll.chars[i]); + surface->FillRectangle(rcSegment, textBack); + int normalCharHeight = surface->Ascent(ctrlCharsFont) - + surface->InternalLeading(ctrlCharsFont); + PRectangle rcCChar = rcSegment; + rcCChar.left = rcCChar.left + 1; + rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; + rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; + PRectangle rcCentral = rcCChar; + rcCentral.top++; + rcCentral.bottom--; + surface->FillRectangle(rcCentral, textFore); + PRectangle rcChar = rcCChar; + rcChar.left++; + rcChar.right--; + surface->DrawTextClipped(rcChar, ctrlCharsFont, + rcSegment.top + vsDraw.maxAscent, ctrlChar, strlen(ctrlChar), + textBack, textFore); + } else { + char cc[2] = { controlCharSymbol, '\0' }; + surface->DrawTextNoClip(rcSegment, ctrlCharsFont, + rcSegment.top + vsDraw.maxAscent, + cc, 1, textBack, textFore); + } } else { // Manage normal display surface->DrawTextNoClip(rcSegment, textFont, @@ -1736,8 +1749,8 @@ void Editor::AddCharUTF(char *s, unsigned int len) { int byte = static_cast<unsigned char>(s[0]); if ((byte < 0xC0) || (1 == len)) { - // Handles UTF-8 characters between 0x01 and 0x7F and single byte - // characters when not in UTF-8 mode. + // Handles UTF-8 characters between 0x01 and 0x7F and single byte + // characters when not in UTF-8 mode. // Also treats \0 and naked trail bytes 0x80 to 0xBF as valid // characters representing themselves. } else { @@ -3277,7 +3290,7 @@ void Editor::Tick() { InvalidateCaret(); } } - if ((dwellDelay < SC_TIME_FOREVER) && + if ((dwellDelay < SC_TIME_FOREVER) && (ticksToDwell > 0) && (!HaveMouseCapture())) { ticksToDwell -= timer.tickSize; @@ -4110,16 +4123,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { dwellDelay = wParam; ticksToDwell = dwellDelay; break; - + case SCI_GETMOUSEDWELLTIME: return dwellDelay; - + case SCI_WORDSTARTPOSITION: return pdoc->ExtendWordSelect(wParam, -1); case SCI_WORDENDPOSITION: return pdoc->ExtendWordSelect(wParam, 1); - + case SCI_GETCOLUMN: return pdoc->GetColumn(wParam); @@ -4710,6 +4723,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { case SCI_GETCURSOR: return cursorMode; + case SCI_SETCONTROLCHARSYMBOL: + controlCharSymbol = wParam; + break; + + case SCI_GETCONTROLCHARSYMBOL: + return controlCharSymbol; + break; + case SCI_STARTRECORD: recordingMacro = true; return 0; diff --git a/src/Editor.h b/src/Editor.h index 2e419d9b2..9c42e28cb 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -15,7 +15,7 @@ public: bool active; bool on; int period; - + Caret(); }; @@ -27,7 +27,7 @@ public: int ticksToWait; enum {tickSize = 100}; int tickerID; - + Timer(); }; @@ -85,20 +85,21 @@ protected: // ScintillaBase subclass needs access to much of Editor /** Style resources may be expensive to allocate so are cached between uses. * When a style attribute is changed, this cache is flushed. */ - bool stylesValid; + bool stylesValid; ViewStyle vs; Palette palette; int printMagnification; int printColourMode; int cursorMode; + int controlCharSymbol; bool hasFocus; bool hideSelection; bool inOverstrike; int errorStatus; bool mouseDownCaptures; - + /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to * the screen. This avoids flashing but is about 30% slower. */ bool bufferedDraw; @@ -106,7 +107,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int xOffset; ///< Horizontal scrolled amount in pixels int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; - + Surface *pixmapLine; Surface *pixmapSelMargin; Surface *pixmapSelPattern; @@ -141,32 +142,32 @@ protected: // ScintillaBase subclass needs access to much of Editor int searchFlags; int topLine; int posTopLine; - + bool needUpdateUI; Position braces[2]; int bracesMatchStyle; int highlightGuideColumn; - + int theEdge; enum { notPainting, painting, paintAbandoned } paintState; PRectangle rcPaint; bool paintingAllText; - + int modEventMask; - + SelectionText drag; enum { selStream, selRectangle, selRectangleFixed } selType; int xStartSelect; int xEndSelect; bool primarySelection; - + int caretPolicy; int caretSlop; int visiblePolicy; int visibleSlop; - + int searchAnchor; bool recordingMacro; @@ -189,7 +190,7 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual PRectangle GetClientRectangle(); PRectangle GetTextRectangle(); - + int LinesOnScreen(); int LinesToScroll(); int MaxScrollPos(); @@ -200,13 +201,13 @@ protected: // ScintillaBase subclass needs access to much of Editor int PositionFromLineX(int line, int x); int LineFromLocation(Point pt); void SetTopLine(int topLineNew); - + void RedrawRect(PRectangle rc); void Redraw(); void RedrawSelMargin(); PRectangle RectangleFromRange(int start, int end); void InvalidateRange(int start, int end); - + int CurrentPosition(); bool SelectionEmpty(); int SelectionStart(int line=-1); @@ -231,7 +232,7 @@ protected: // ScintillaBase subclass needs access to much of Editor int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault); void PaintSelMargin(Surface *surface, PRectangle &rc); void LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayout &ll); - void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, + void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart, PRectangle rcLine, LineLayout &ll); void Paint(Surface *surfaceWindow, PRectangle rcArea); long FormatRange(bool draw, RangeToFormat *pfr); @@ -276,7 +277,7 @@ protected: // ScintillaBase subclass needs access to much of Editor bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); void NotifyNeedShown(int pos, int len); void NotifyDwelling(Point pt, bool state); - + void NotifyModifyAttempt(Document *document, void *userData); void NotifySavePoint(Document *document, void *userData, bool atSavePoint); void NotifyModified(Document *document, DocModification mh, void *userData); @@ -329,16 +330,16 @@ protected: // ScintillaBase subclass needs access to much of Editor void CheckForChangeOutsidePaint(Range r); int BraceMatch(int position, int maxReStyle); void SetBraceHighlight(Position pos0, Position pos1, int matchStyle); - + void SetDocPointer(Document *document); - + void Expand(int &line, bool doExpand); void ToggleContraction(int line); void EnsureLineVisible(int lineDoc, bool enforcePolicy); int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; - + public: // Public so scintilla_send_message can use it virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); |