diff options
-rw-r--r-- | gtk/PlatGTK.cxx | 223 | ||||
-rw-r--r-- | gtk/ScintillaGTK.cxx | 45 | ||||
-rw-r--r-- | include/Platform.h | 150 | ||||
-rw-r--r-- | src/CallTip.cxx | 16 | ||||
-rw-r--r-- | src/Document.cxx | 11 | ||||
-rw-r--r-- | src/DocumentAccessor.cxx | 8 | ||||
-rw-r--r-- | src/Editor.cxx | 216 | ||||
-rw-r--r-- | src/Editor.h | 10 | ||||
-rw-r--r-- | src/UniConversion.cxx | 4 | ||||
-rw-r--r-- | src/WindowAccessor.cxx | 8 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 131 |
11 files changed, 458 insertions, 364 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index c028a52a1..dd05e54a3 100644 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -30,14 +30,6 @@ static GdkFont *PFont(Font &f) { return reinterpret_cast<GdkFont *>(f.GetID()); } -static GdkDrawable *PDrawable(SurfaceID id) { - return reinterpret_cast<GdkDrawable *>(id); -} - -static GdkGC *PGC(void *gc) { - return reinterpret_cast<GdkGC *>(gc); -} - static GtkWidget *PWidget(WindowID id) { return reinterpret_cast<GtkWidget *>(id); } @@ -46,27 +38,12 @@ static GtkWidget *PWidget(Window &w) { return PWidget(w.GetID()); } -static GtkItemFactory *PMenu(MenuID id) { - return reinterpret_cast<GtkItemFactory *>(id); -} - Point Point::FromLong(long lpoint) { return Point( Platform::LowShortFromLong(lpoint), Platform::HighShortFromLong(lpoint)); } -static GdkColor ColourfromRGB(unsigned int red, unsigned int green, unsigned int blue) { - GdkColor co; - co.red = red * (65535 / 255); - co.green = green * (65535 / 255); - co.blue = blue * (65535 / 255); - // the pixel value indicates the index in the colourmap of the colour. - // it is simply a combination of the RGB values we set earlier - co.pixel = (gulong)(red * 65536 + green * 256 + blue); - return co; -} - Palette::Palette() { used = 0; allowRealization = false; @@ -127,6 +104,9 @@ void Palette::Allocate(Window &w) { allocatedLen = used; int iPal = 0; for (iPal = 0; iPal < used; iPal++) { + paletteNew[iPal].red = entries[iPal].desired.GetRed() * (65535 / 255); + paletteNew[iPal].green = entries[iPal].desired.GetGreen() * (65535 / 255); + paletteNew[iPal].blue = entries[iPal].desired.GetBlue() * (65535 / 255); paletteNew[iPal].pixel = entries[iPal].desired.AsLong(); } gdk_colormap_alloc_colors(gtk_widget_get_colormap(PWidget(w)), @@ -230,22 +210,73 @@ void Font::Release() { id = 0; } -Surface::Surface() : unicodeMode(false), drawable(0), gc(0), ppixmap(0), +class SurfaceImpl : public Surface { + bool unicodeMode; + GdkDrawable *drawable; + GdkGC *gc; + GdkPixmap *ppixmap; + int x; + int y; + bool inited; + bool createdGC; +public: + SurfaceImpl(); + virtual ~SurfaceImpl(); + + void Init(); + void Init(SurfaceID sid); + void InitPixMap(int width, int height, Surface *surface_); + + void Release(); + bool Initialised(); + void PenColour(ColourAllocated fore); + int LogPixelsY(); + int DeviceHeightFont(int points); + void MoveTo(int x_, int y_); + void LineTo(int x_, int y_); + void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); + void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void FillRectangle(PRectangle rc, ColourAllocated back); + void FillRectangle(PRectangle rc, Surface &surfacePattern); + void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Copy(PRectangle rc, Point from, Surface &surfaceSource); + + void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void MeasureWidths(Font &font_, const char *s, int len, int *positions); + int WidthText(Font &font_, const char *s, int len); + int WidthChar(Font &font_, char ch); + int Ascent(Font &font_); + int Descent(Font &font_); + int InternalLeading(Font &font_); + int ExternalLeading(Font &font_); + int Height(Font &font_); + int AverageCharWidth(Font &font_); + + int SetPalette(Palette *pal, bool inBackGround); + void SetClip(PRectangle rc); + void FlushCachedState(); + + void SetUnicodeMode(bool unicodeMode_); +}; + +SurfaceImpl::SurfaceImpl() : unicodeMode(false), drawable(0), gc(0), ppixmap(0), x(0), y(0), inited(false), createdGC(false) {} -Surface::~Surface() { +SurfaceImpl::~SurfaceImpl() { Release(); } -void Surface::Release() { +void SurfaceImpl::Release() { drawable = 0; if (createdGC) { createdGC = false; - gdk_gc_unref(PGC(gc)); + gdk_gc_unref(gc); } gc = 0; if (ppixmap) - gdk_pixmap_unref(PDrawable(ppixmap)); + gdk_pixmap_unref(ppixmap); ppixmap = 0; x = 0; y = 0; @@ -253,17 +284,17 @@ void Surface::Release() { createdGC = false; } -bool Surface::Initialised() { +bool SurfaceImpl::Initialised() { return inited; } -void Surface::Init() { +void SurfaceImpl::Init() { Release(); inited = true; } -void Surface::Init(SurfaceID sid) { - GdkDrawable *drawable_ = PDrawable(sid); +void SurfaceImpl::Init(SurfaceID sid) { + GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid); Release(); drawable = drawable_; gc = gdk_gc_new(drawable_); @@ -273,49 +304,49 @@ void Surface::Init(SurfaceID sid) { inited = true; } -void Surface::InitPixMap(int width, int height, Surface *surface_) { +void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) { Release(); if (height > 0 && width > 0) - ppixmap = gdk_pixmap_new(PDrawable(surface_->drawable), width, height, -1); + ppixmap = gdk_pixmap_new(static_cast<SurfaceImpl *>(surface_)->drawable, width, height, -1); drawable = ppixmap; - gc = gdk_gc_new(PDrawable(surface_->drawable)); + gc = gdk_gc_new(static_cast<SurfaceImpl *>(surface_)->drawable); //gdk_gc_set_line_attributes(gc, 1, // GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_BEVEL); createdGC = true; inited = true; } -void Surface::PenColour(ColourAllocated fore) { +void SurfaceImpl::PenColour(ColourAllocated fore) { if (gc) { GdkColor co; co.pixel = fore.AsLong(); - gdk_gc_set_foreground(PGC(gc), &co); + gdk_gc_set_foreground(gc, &co); } } -int Surface::LogPixelsY() { +int SurfaceImpl::LogPixelsY() { return 72; } -int Surface::DeviceHeightFont(int points) { +int SurfaceImpl::DeviceHeightFont(int points) { int logPix = LogPixelsY(); return (points * logPix + logPix / 2) / 72; } -void Surface::MoveTo(int x_, int y_) { +void SurfaceImpl::MoveTo(int x_, int y_) { x = x_; y = y_; } -void Surface::LineTo(int x_, int y_) { - gdk_draw_line(PDrawable(drawable), PGC(gc), +void SurfaceImpl::LineTo(int x_, int y_) { + gdk_draw_line(drawable, gc, x, y, x_, y_); x = x_; y = y_; } -void Surface::Polygon(Point *pts, int npts, ColourAllocated fore, +void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) { GdkPoint gpts[20]; if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) { @@ -324,39 +355,39 @@ void Surface::Polygon(Point *pts, int npts, ColourAllocated fore, gpts[i].y = pts[i].y; } PenColour(back); - gdk_draw_polygon(PDrawable(drawable), PGC(gc), 1, gpts, npts); + gdk_draw_polygon(drawable, gc, 1, gpts, npts); PenColour(fore); - gdk_draw_polygon(PDrawable(drawable), PGC(gc), 0, gpts, npts); + gdk_draw_polygon(drawable, gc, 0, gpts, npts); } } -void Surface::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) { if (gc && drawable) { PenColour(back); - gdk_draw_rectangle(PDrawable(drawable), PGC(gc), 1, + gdk_draw_rectangle(drawable, gc, 1, rc.left + 1, rc.top + 1, rc.right - rc.left - 2, rc.bottom - rc.top - 2); PenColour(fore); // The subtraction of 1 off the width and height here shouldn't be needed but // otherwise a different rectangle is drawn than would be done if the fill parameter == 1 - gdk_draw_rectangle(PDrawable(drawable), PGC(gc), 0, + gdk_draw_rectangle(drawable, gc, 0, rc.left, rc.top, rc.right - rc.left - 1, rc.bottom - rc.top - 1); } } -void Surface::FillRectangle(PRectangle rc, ColourAllocated back) { +void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) { PenColour(back); if (drawable) { - gdk_draw_rectangle(PDrawable(drawable), PGC(gc), 1, + gdk_draw_rectangle(drawable, gc, 1, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } } -void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) { - if (surfacePattern.drawable) { +void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { + if (static_cast<SurfaceImpl &>(surfacePattern).drawable) { // Tile pattern over rectangle // Currently assumes 8x8 pattern int widthPat = 8; @@ -365,9 +396,9 @@ void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) { int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; - gdk_draw_pixmap(PDrawable(drawable), - PGC(gc), - PDrawable(surfacePattern.drawable), + gdk_draw_pixmap(drawable, + gc, + static_cast<SurfaceImpl &>(surfacePattern).drawable, 0, 0, xTile, yTile, widthx, heighty); @@ -380,7 +411,7 @@ void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) { } } -void Surface::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { if (((rc.right - rc.left) > 4) && ((rc.bottom - rc.top) > 4)) { // Approximate a round rect with some cut off corners Point pts[] = { @@ -399,53 +430,53 @@ void Surface::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAlloca } } -void Surface::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(back); - gdk_draw_arc(PDrawable(drawable), PGC(gc), 1, + gdk_draw_arc(drawable, gc, 1, rc.left + 1, rc.top + 1, rc.right - rc.left - 2, rc.bottom - rc.top - 2, 0, 32767); // The subtraction of 1 here is similar to the case for RectangleDraw PenColour(fore); - gdk_draw_arc(PDrawable(drawable), PGC(gc), 0, + gdk_draw_arc(drawable, gc, 0, rc.left, rc.top, rc.right - rc.left - 1, rc.bottom - rc.top - 1, 0, 32767); } -void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) { - if (surfaceSource.drawable) { - gdk_draw_pixmap(PDrawable(drawable), - PGC(gc), - PDrawable(surfaceSource.drawable), +void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { + if (static_cast<SurfaceImpl &>(surfaceSource).drawable) { + gdk_draw_pixmap(drawable, + gc, + static_cast<SurfaceImpl &>(surfaceSource).drawable, from.x, from.y, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); } } -void Surface::DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, +void SurfaceImpl::DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { FillRectangle(rc, back); PenColour(fore); if (gc && drawable) - gdk_draw_text(PDrawable(drawable), PFont(font_), PGC(gc), rc.left, ybase, s, len); + gdk_draw_text(drawable, PFont(font_), gc, rc.left, ybase, s, len); } // On GTK+, exactly same as DrawText -void Surface::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, +void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { FillRectangle(rc, back); PenColour(fore); if (gc && drawable) - gdk_draw_text(PDrawable(drawable), PFont(font_), PGC(gc), rc.left, ybase, s, len); + gdk_draw_text(drawable, PFont(font_), gc, rc.left, ybase, s, len); } -void Surface::MeasureWidths(Font &font_, const char *s, int len, int *positions) { +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { int totalWidth = 0; for (int i = 0;i < len;i++) { - if (font_.id) { + if (font_.GetID()) { int width = gdk_char_width(PFont(font_), s[i]); totalWidth += width; } else { @@ -455,20 +486,24 @@ void Surface::MeasureWidths(Font &font_, const char *s, int len, int *positions) } } -int Surface::WidthText(Font &font_, const char *s, int len) { - if (font_.id) +int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { + if (font_.GetID()) return gdk_text_width(PFont(font_), s, len); else return 1; } -int Surface::WidthChar(Font &font_, char ch) { - if (font_.id) +int SurfaceImpl::WidthChar(Font &font_, char ch) { + if (font_.GetID()) return gdk_char_width(PFont(font_), ch); else return 1; } +Surface *Surface::Allocate() { + return new SurfaceImpl; +} + // Three possible strategies for determining ascent and descent of font: // 1) Call gdk_string_extents with string containing all letters, numbers and punctuation. // 2) Use the ascent and descent fields of GdkFont. @@ -484,8 +519,8 @@ const char largeSizeString[] = "ÂÃÅÄ `~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/12345678 const char sizeString[] = "`~!@#$%^&*()-_=+\\|[]{};:\"\'<,>.?/1234567890" "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -int Surface::Ascent(Font &font_) { - if (!font_.id) +int SurfaceImpl::Ascent(Font &font_) { + if (!font_.GetID()) return 1; #ifdef FAST_WAY return PFont(font_)->ascent; @@ -496,14 +531,14 @@ int Surface::Ascent(Font &font_) { gint ascent; gint descent; - gdk_string_extents(font_.id, sizeString, + gdk_string_extents(PFont(font_), sizeString, &lbearing, &rbearing, &width, &ascent, &descent); return ascent; #endif } -int Surface::Descent(Font &font_) { - if (!font_.id) +int SurfaceImpl::Descent(Font &font_) { + if (!font_.GetID()) return 1; #ifdef FAST_WAY return PFont(font_)->descent; @@ -514,43 +549,47 @@ int Surface::Descent(Font &font_) { gint ascent; gint descent; - gdk_string_extents(font_.id, sizeString, + gdk_string_extents(PFont(font_), sizeString, &lbearing, &rbearing, &width, &ascent, &descent); return descent; #endif } -int Surface::InternalLeading(Font &) { +int SurfaceImpl::InternalLeading(Font &) { return 0; } -int Surface::ExternalLeading(Font &) { +int SurfaceImpl::ExternalLeading(Font &) { return 0; } -int Surface::Height(Font &font_) { +int SurfaceImpl::Height(Font &font_) { return Ascent(font_) + Descent(font_); } -int Surface::AverageCharWidth(Font &font_) { - if (font_.id) +int SurfaceImpl::AverageCharWidth(Font &font_) { + if (font_.GetID()) return gdk_char_width(PFont(font_), 'n'); else return 1; } -int Surface::SetPalette(Palette *, bool) { +int SurfaceImpl::SetPalette(Palette *, bool) { // Handled in palette allocation for GTK so this does nothing return 0; } -void Surface::SetClip(PRectangle rc) { +void SurfaceImpl::SetClip(PRectangle rc) { GdkRectangle area = {rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top}; - gdk_gc_set_clip_rectangle(PGC(gc), &area); + gdk_gc_set_clip_rectangle(gc, &area); } -void Surface::FlushCachedState() {} +void SurfaceImpl::FlushCachedState() {} + +void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { + unicodeMode=unicodeMode_; +} Window::~Window() {} @@ -844,7 +883,7 @@ void Menu::Destroy() { } void Menu::Show(Point pt, Window &) { - gtk_item_factory_popup(PMenu(id), pt.x - 4, pt.y, 3, 0); + gtk_item_factory_popup(reinterpret_cast<GtkItemFactory *>(id), pt.x - 4, pt.y, 3, 0); } ColourDesired Platform::Chrome() { @@ -889,6 +928,10 @@ long Platform::SendScintilla( return scintilla_send_message(SCINTILLA(w), msg, wParam, lParam); } +bool Platform::IsDBCSLeadByte(int /*codePage*/, char /*ch*/) { + return false; +} + // These are utility functions not really tied to a platform int Platform::Minimum(int a, int b) { diff --git a/gtk/ScintillaGTK.cxx b/gtk/ScintillaGTK.cxx index b9668d9bf..118b84a7d 100644 --- a/gtk/ScintillaGTK.cxx +++ b/gtk/ScintillaGTK.cxx @@ -604,10 +604,13 @@ void ScintillaGTK::FullPaint() { //Platform::DebugPrintf("ScintillaGTK::FullPaint %0d,%0d %0d,%0d\n", // rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom); paintingAllText = true; - Surface sw; - sw.Init((PWidget(wMain))->window); - Paint(&sw, rcPaint); - sw.Release(); + Surface *sw = Surface::Allocate(); + if (sw) { + sw->Init((PWidget(wMain))->window); + Paint(sw, rcPaint); + sw->Release(); + delete sw; + } paintState = notPainting; } @@ -632,10 +635,13 @@ void ScintillaGTK::SyncPaint(PRectangle rc) { paintingAllText = rcPaint.Contains(rcText); //Platform::DebugPrintf("ScintillaGTK::SyncPaint %0d,%0d %0d,%0d\n", // rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom); - Surface sw; - sw.Init((PWidget(wMain))->window); - Paint(&sw, rc); - sw.Release(); + Surface *sw = Surface::Allocate(); + if (sw) { + sw->Init((PWidget(wMain))->window); + Paint(sw, rc); + sw->Release(); + delete sw; + } if (paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions FullPaint(); @@ -1385,10 +1391,13 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose, ScintillaGTK *sciThi PRectangle rcText = sciThis->GetTextRectangle(); sciThis->paintingAllText = sciThis->rcPaint.Contains(rcText); - Surface surfaceWindow; - surfaceWindow.Init((PWidget(sciThis->wMain))->window); - sciThis->Paint(&surfaceWindow, sciThis->rcPaint); - surfaceWindow.Release(); + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init((PWidget(sciThis->wMain))->window); + sciThis->Paint(surfaceWindow, sciThis->rcPaint); + surfaceWindow->Release(); + delete surfaceWindow; + } if (sciThis->paintState == paintAbandoned) { // Painting area was insufficient to cover new styling or brace highlight positions sciThis->FullPaint(); @@ -1514,11 +1523,13 @@ void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) { } gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) { - Surface surfaceWindow; - //surfaceWindow.Init((ct->wCallTip.GetID())->window); - surfaceWindow.Init(widget->window); - ctip->PaintCT(&surfaceWindow); - surfaceWindow.Release(); + Surface *surfaceWindow = Surface::Allocate(); + if (surfaceWindow) { + surfaceWindow->Init(widget->window); + ctip->PaintCT(surfaceWindow); + surfaceWindow->Release(); + delete surfaceWindow; + } return TRUE; } diff --git a/include/Platform.h b/include/Platform.h index eeb72c1ce..0beede070 100644 --- a/include/Platform.h +++ b/include/Platform.h @@ -42,11 +42,10 @@ // Underlying the implementation of the platform classes are platform specific types. // Sometimes these need to be passed around by client code so they are defined here -typedef void* FontID; -typedef void* SurfaceID; -typedef void* WindowID; -typedef void* MenuID; -typedef void* PaletteID; +typedef void *FontID; +typedef void *SurfaceID; +typedef void *WindowID; +typedef void *MenuID; /** * A geometric point class. @@ -104,7 +103,19 @@ public: }; /** - * A colour class. + * In some circumstances, including Win32 in paletted mode and GTK+, each colour + * must be allocated before use. The desired colours are held in the ColourDesired class, + * and after allocation the allocation entry is stored in the ColourAllocated class. In other + * circumstances, such as Win32 in true colour mode, the allocation process just copies + * the RGB values from the desired to the allocated class. + * As each desired colour requires allocation before it can be used, the ColourPair class + * holds both a ColourDesired and a ColourAllocated + * The Palette class is responsible for managing the palette of colours which contains a + * list of ColourPair objects and performs the allocation. + */ + +/** + * Holds a desired RGB colour. */ class ColourDesired { long co; @@ -142,6 +153,9 @@ public: } }; +/** + * Holds an allocated RGB colour which may be an approximation to the desired colour. + */ class ColourAllocated { long coAllocated; @@ -161,10 +175,7 @@ public: }; /** - * Colour pairs hold a desired colour and the colour that the graphics engine - * allocates to approximate the desired colour. - * To make palette management more automatic, ColourPairs could register at - * construction time with a palette management object. + * Colour pairs hold a desired colour and an allocated colour. */ struct ColourPair { ColourDesired desired; @@ -190,8 +201,6 @@ class Palette { int allocatedLen; #elif PLAT_WIN void *hpal; -#elif PLAT_WX - // wxPalette* pal; // **** Is this needed? #endif public: bool allowRealization; @@ -209,8 +218,6 @@ public: void WantFind(ColourPair &cp, bool want); void Allocate(Window &w); - - friend class Surface; }; /** @@ -243,84 +250,50 @@ public: */ class Surface { private: - bool unicodeMode; -#if PLAT_GTK - void *drawable; // GdkDrawable *drawable; - void *gc; // GdkGC *gc; - void *ppixmap; // GdkPixmap *ppixmap; - int x; - int y; - bool inited; - bool createdGC; -#elif PLAT_WIN - void *hdc; // HDC - bool hdcOwned; - void *pen; // HPEN - void *penOld; // HPEN - void *brush; // HBRUSH - void *brushOld; // HBRUSH - void *font; // HFONT - void *fontOld; // HFONT - void *bitmap; // HBITMAP - void *bitmapOld; // HBITMAP - void *paletteOld; // HPALETTE -#elif PLAT_WX - void *hdc; // wxDC* - bool hdcOwned; - void *bitmap; // wxBitmap* - int x; - int y; -#endif - // Private so Surface objects can not be copied Surface(const Surface &) {} Surface &operator=(const Surface &) { return *this; } -#if PLAT_WIN || PLAT_WX - void BrushColor(ColourAllocated back); - void SetFont(Font &font_); -#endif public: - Surface(); - ~Surface(); - - void Init(); - void Init(SurfaceID sid); - void InitPixMap(int width, int height, Surface *surface_); - - void Release(); - bool Initialised(); - void PenColour(ColourAllocated fore); - int LogPixelsY(); - int DeviceHeightFont(int points); - void MoveTo(int x_, int y_); - void LineTo(int x_, int y_); - void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); - void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void FillRectangle(PRectangle rc, ColourAllocated back); - void FillRectangle(PRectangle rc, Surface &surfacePattern); - void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); - void Copy(PRectangle rc, Point from, Surface &surfaceSource); - - void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); - void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); - void MeasureWidths(Font &font_, const char *s, int len, int *positions); - int WidthText(Font &font_, const char *s, int len); - int WidthChar(Font &font_, char ch); - int Ascent(Font &font_); - int Descent(Font &font_); - int InternalLeading(Font &font_); - int ExternalLeading(Font &font_); - int Height(Font &font_); - int AverageCharWidth(Font &font_); - - int SetPalette(Palette *pal, bool inBackGround); - void SetClip(PRectangle rc); - void FlushCachedState(); - - void SetUnicodeMode(bool unicodeMode_) { - unicodeMode=unicodeMode_; - } + Surface() {}; + virtual ~Surface() {}; + static Surface *Allocate(); + + virtual void Init()=0; + virtual void Init(SurfaceID sid)=0; + virtual void InitPixMap(int width, int height, Surface *surface_)=0; + + virtual void Release()=0; + virtual bool Initialised()=0; + virtual void PenColour(ColourAllocated fore)=0; + virtual int LogPixelsY()=0; + virtual int DeviceHeightFont(int points)=0; + virtual void MoveTo(int x_, int y_)=0; + virtual void LineTo(int x_, int y_)=0; + virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back)=0; + virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, ColourAllocated back)=0; + virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; + virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back)=0; + virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; + + virtual void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back)=0; + virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions)=0; + virtual int WidthText(Font &font_, const char *s, int len)=0; + virtual int WidthChar(Font &font_, char ch)=0; + virtual int Ascent(Font &font_)=0; + virtual int Descent(Font &font_)=0; + virtual int InternalLeading(Font &font_)=0; + virtual int ExternalLeading(Font &font_)=0; + virtual int Height(Font &font_)=0; + virtual int AverageCharWidth(Font &font_)=0; + + virtual int SetPalette(Palette *pal, bool inBackGround)=0; + virtual void SetClip(PRectangle rc)=0; + virtual void FlushCachedState()=0; + + virtual void SetUnicodeMode(bool unicodeMode_)=0; }; /** @@ -333,7 +306,6 @@ typedef void (*CallBackAction)(void*); * Does not own the window which will normally have a longer life than this object. */ class Window { - friend class ListBox; protected: WindowID id; public: diff --git a/src/CallTip.cxx b/src/CallTip.cxx index 006e2cb51..807b745f6 100644 --- a/src/CallTip.cxx +++ b/src/CallTip.cxx @@ -118,9 +118,11 @@ void CallTip::PaintCT(Surface *surfaceWindow) { PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, const char *faceName, int size) { - Surface surfaceMeasure; - surfaceMeasure.Init(); - int deviceHeight = surfaceMeasure.DeviceHeightFont(size); + Surface *surfaceMeasure=Surface::Allocate(); + if (!surfaceMeasure) + return PRectangle(); + surfaceMeasure->Init(); + int deviceHeight = surfaceMeasure->DeviceHeightFont(size); font.Create(faceName, SC_CHARSET_DEFAULT, deviceHeight, false, false); if (val) delete []val; @@ -139,16 +141,16 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, const char *defn, const char *newline; const char *look = val; while ((newline = strchr(look, '\n')) != NULL) { - int thisWidth = surfaceMeasure.WidthText(font, look, newline - look); + int thisWidth = surfaceMeasure->WidthText(font, look, newline - look); width = Platform::Maximum(width, thisWidth); look = newline + 1; numLines++; } - int lastWidth = surfaceMeasure.WidthText(font, look, strlen(look)); + int lastWidth = surfaceMeasure->WidthText(font, look, strlen(look)); width = Platform::Maximum(width, lastWidth) + 10; - int lineHeight = surfaceMeasure.Height(font); + int lineHeight = surfaceMeasure->Height(font); // Extra line for border and an empty line at top and bottom - int height = lineHeight * numLines - surfaceMeasure.InternalLeading(font) + 2 + 2; + int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2; return PRectangle(pt.x -5, pt.y + 1, pt.x + width - 5, pt.y + 1 + height); } diff --git a/src/Document.cxx b/src/Document.cxx index 213a72d6a..806f61f19 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -217,7 +217,6 @@ bool Document::IsCrLf(int pos) { return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); } -#if PLAT_WIN bool Document::IsDBCS(int pos) { if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { @@ -241,13 +240,6 @@ bool Document::IsDBCS(int pos) { } return false; } -#else -// PLAT_GTK or PLAT_WX -// TODO: support DBCS under GTK+ and WX -bool Document::IsDBCS(int) { - return false; -} -#endif int Document::LenChar(int pos) { if (IsCrLf(pos)) { @@ -300,7 +292,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { // Not between CR and LF -#if PLAT_WIN if (dbcsCodePage) { if (SC_CP_UTF8 == dbcsCodePage) { unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos)); @@ -327,7 +318,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { else atLeadByte = false; startLine++; - //Platform::DebugPrintf("DBCS %s\n", atlead ? "D" : "-"); } @@ -340,7 +330,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) { } } } -#endif return pos; } diff --git a/src/DocumentAccessor.cxx b/src/DocumentAccessor.cxx index e8930c23d..76530e1de 100644 --- a/src/DocumentAccessor.cxx +++ b/src/DocumentAccessor.cxx @@ -23,7 +23,6 @@ DocumentAccessor::~DocumentAccessor() { } -#if PLAT_WIN bool DocumentAccessor::InternalIsLeadByte(char ch) { if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the @@ -32,13 +31,6 @@ bool DocumentAccessor::InternalIsLeadByte(char ch) { else return Platform::IsDBCSLeadByte(codePage, ch); } -#else -// PLAT_GTK or PLAT_WX -// TODO: support DBCS under GTK+ and WX -bool DocumentAccessor::InternalIsLeadByte(char) { - return false; -} -#endif void DocumentAccessor::Fill(int position) { if (lenDoc == -1) diff --git a/src/Editor.cxx b/src/Editor.cxx index 941c05971..039306a41 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -82,6 +82,12 @@ Editor::Editor() { xCaretMargin = 50; horizontalScrollBarVisible = true; + pixmapLine = Surface::Allocate(); + pixmapSelMargin = Surface::Allocate(); + pixmapSelPattern = Surface::Allocate(); + pixmapIndentGuide = Surface::Allocate(); + pixmapIndentGuideHighlight = Surface::Allocate(); + currentPos = 0; anchor = 0; @@ -117,6 +123,11 @@ Editor::~Editor() { pdoc->Release(); pdoc = 0; DropGraphics(); + delete pixmapLine; + delete pixmapSelMargin; + delete pixmapSelPattern; + delete pixmapIndentGuide; + delete pixmapIndentGuideHighlight; } void Editor::Finalise() { @@ -124,10 +135,10 @@ void Editor::Finalise() { } void Editor::DropGraphics() { - pixmapLine.Release(); - pixmapSelMargin.Release(); - pixmapSelPattern.Release(); - pixmapIndentGuide.Release(); + pixmapLine->Release(); + pixmapSelMargin->Release(); + pixmapSelPattern->Release(); + pixmapIndentGuide->Release(); } void Editor::InvalidateStyleData() { @@ -148,12 +159,15 @@ void Editor::RefreshColourPalette(Palette &pal, bool want) { void Editor::RefreshStyleData() { if (!stylesValid) { stylesValid = true; - Surface surface; - surface.Init(); - vs.Refresh(surface); - RefreshColourPalette(palette, true); - palette.Allocate(wMain); - RefreshColourPalette(palette, false); + Surface *surface = Surface::Allocate(); + if (surface) { + surface->Init(); + vs.Refresh(*surface); + RefreshColourPalette(palette, true); + palette.Allocate(wMain); + RefreshColourPalette(palette, false); + delete surface; + } SetScrollBars(); } } @@ -221,18 +235,21 @@ Point Editor::LocationFromPosition(int pos) { int line = pdoc->LineFromPosition(pos); int lineVisible = cs.DisplayFromDoc(line); //Platform::DebugPrintf("line=%d\n", line); - Surface surface; - surface.Init(); - surface.SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); - pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? - unsigned int posLineStart = pdoc->LineStart(line); - LineLayout ll; - LayoutLine(line, &surface, vs, ll); - if ((pos - posLineStart) > LineLayout::maxLineLength) { - // very long line so put x at arbitrary large position - pt.x = ll.positions[LineLayout::maxLineLength] + vs.fixedColumnWidth - xOffset; - } else { - pt.x = ll.positions[pos - posLineStart] + vs.fixedColumnWidth - xOffset; + Surface *surface = Surface::Allocate(); + if (surface) { + surface->Init(); + surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); + pt.y = (lineVisible - topLine) * vs.lineHeight; // + half a lineheight? + unsigned int posLineStart = pdoc->LineStart(line); + LineLayout ll; + LayoutLine(line, surface, vs, ll); + if ((pos - posLineStart) > LineLayout::maxLineLength) { + // very long line so put x at arbitrary large position + pt.x = ll.positions[LineLayout::maxLineLength] + vs.fixedColumnWidth - xOffset; + } else { + pt.x = ll.positions[pos - posLineStart] + vs.fixedColumnWidth - xOffset; + } + delete surface; } return pt; } @@ -262,21 +279,25 @@ int Editor::PositionFromLocation(Point pt) { return 0; if (line >= pdoc->LinesTotal()) return pdoc->Length(); - Surface surface; - 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++) { - if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { - return i + posLineStart; + Surface *surface = Surface::Allocate(); + if (surface) { + 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++) { + if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { + delete surface; + return i + posLineStart; + } } + delete surface; + return ll.numCharsInLine + posLineStart; } - - return ll.numCharsInLine + posLineStart; + return 0; } // Like PositionFromLocation but INVALID_POSITION returned when not near any text. @@ -298,18 +319,22 @@ int Editor::PositionFromLocationClose(Point pt) { return INVALID_POSITION; if (line >= pdoc->LinesTotal()) return INVALID_POSITION; - Surface surface; - 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++) { - if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { - return i + posLineStart; + Surface *surface = Surface::Allocate(); + if (surface) { + 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++) { + if (pt.x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { + delete surface; + return i + posLineStart; + } } + delete surface; } return INVALID_POSITION; @@ -320,21 +345,26 @@ int Editor::PositionFromLineX(int line, int x) { if (line >= pdoc->LinesTotal()) return pdoc->Length(); //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); - Surface surface; - 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++) { - if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || - ll.chars[i] == '\r' || ll.chars[i] == '\n') { - return i + posLineStart; + Surface *surface = Surface::Allocate(); + if (surface) { + 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++) { + if (x < ((ll.positions[i] + ll.positions[i + 1]) / 2) || + ll.chars[i] == '\r' || ll.chars[i] == '\n') { + delete surface; + return i + posLineStart; + } } + + delete surface; + return ll.numCharsInLine + posLineStart; } - - return ll.numCharsInLine + posLineStart; + return 0; } void Editor::RedrawRect(PRectangle rc) { @@ -712,7 +742,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { Surface *surface; if (bufferedDraw) { - surface = &pixmapSelMargin; + surface = pixmapSelMargin; } else { surface = surfWindow; } @@ -736,7 +766,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { */ if (vs.ms[margin].mask & SC_MASK_FOLDERS) // Required because of special way brush is created for selection margin - surface->FillRectangle(rcSelMargin, pixmapSelPattern); + surface->FillRectangle(rcSelMargin, *pixmapSelPattern); else surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back.allocated); } else { @@ -874,7 +904,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back.allocated); if (bufferedDraw) { - surfWindow->Copy(rcMargin, Point(), pixmapSelMargin); + surfWindow->Copy(rcMargin, Point(), *pixmapSelMargin); } } @@ -1079,7 +1109,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); PRectangle rcCopyArea(xIG + xStart + 1, rcSegment.top, xIG + xStart + 2, rcSegment.bottom); surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == xIG) ? - pixmapIndentGuideHighlight : pixmapIndentGuide); + *pixmapIndentGuideHighlight : *pixmapIndentGuide); } } } @@ -1144,7 +1174,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis Point from(0, ((lineVisible & 1) && (vsDraw.lineHeight & 1)) ? 1 : 0); PRectangle rcCopyArea(startSpace + xStart + 1, rcSegment.top, startSpace + xStart + 2, rcSegment.bottom); surface->Copy(rcCopyArea, from, (ll.xHighlightGuide == ll.positions[cpos + startseg]) ? - pixmapIndentGuideHighlight : pixmapIndentGuide); + *pixmapIndentGuideHighlight : *pixmapIndentGuide); } } } else { @@ -1232,53 +1262,53 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", // rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); - if (!pixmapSelPattern.Initialised()) { - pixmapSelPattern.InitPixMap(8, 8, surfaceWindow); + if (!pixmapSelPattern->Initialised()) { + pixmapSelPattern->InitPixMap(8, 8, surfaceWindow); // This complex procedure is to reproduce the checker board dithered pattern used by windows // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half // way between the chrome colour and the chrome highlight colour making a nice transition // between the window chrome and the content area. And it works in low colour depths. PRectangle rcPattern(0, 0, 8, 8); if (vs.selbarlight.desired == ColourDesired(0xff, 0xff, 0xff)) { - pixmapSelPattern.FillRectangle(rcPattern, vs.selbar.allocated); - pixmapSelPattern.PenColour(vs.selbarlight.allocated); + pixmapSelPattern->FillRectangle(rcPattern, vs.selbar.allocated); + pixmapSelPattern->PenColour(vs.selbarlight.allocated); for (int stripe = 0; stripe < 8; stripe++) { - pixmapSelPattern.MoveTo(0, stripe * 2); - pixmapSelPattern.LineTo(8, stripe * 2 - 8); + pixmapSelPattern->MoveTo(0, stripe * 2); + pixmapSelPattern->LineTo(8, stripe * 2 - 8); } } else { // User has chosen an unusual chrome colour scheme so just use the highlight edge colour. - pixmapSelPattern.FillRectangle(rcPattern, vs.selbarlight.allocated); + pixmapSelPattern->FillRectangle(rcPattern, vs.selbarlight.allocated); } } - if (!pixmapIndentGuide.Initialised()) { + if (!pixmapIndentGuide->Initialised()) { // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line - pixmapIndentGuide.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); - pixmapIndentGuideHighlight.InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuide->InitPixMap(1, vs.lineHeight + 1, surfaceWindow); + pixmapIndentGuideHighlight->InitPixMap(1, vs.lineHeight + 1, surfaceWindow); PRectangle rcIG(0, 0, 1, vs.lineHeight); - pixmapIndentGuide.FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); - pixmapIndentGuide.PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); - pixmapIndentGuideHighlight.FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated); - pixmapIndentGuideHighlight.PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated); + pixmapIndentGuide->FillRectangle(rcIG, vs.styles[STYLE_INDENTGUIDE].back.allocated); + pixmapIndentGuide->PenColour(vs.styles[STYLE_INDENTGUIDE].fore.allocated); + pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated); + pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated); for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) { - pixmapIndentGuide.MoveTo(0, stripe); - pixmapIndentGuide.LineTo(2, stripe); - pixmapIndentGuideHighlight.MoveTo(0, stripe); - pixmapIndentGuideHighlight.LineTo(2, stripe); + pixmapIndentGuide->MoveTo(0, stripe); + pixmapIndentGuide->LineTo(2, stripe); + pixmapIndentGuideHighlight->MoveTo(0, stripe); + pixmapIndentGuideHighlight->LineTo(2, stripe); } } if (bufferedDraw) { - if (!pixmapLine.Initialised()) { - pixmapLine.InitPixMap(rcClient.Width(), rcClient.Height(), + if (!pixmapLine->Initialised()) { + pixmapLine->InitPixMap(rcClient.Width(), rcClient.Height(), surfaceWindow); - pixmapSelMargin.InitPixMap(vs.fixedColumnWidth, + pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, rcClient.Height(), surfaceWindow); } } surfaceWindow->SetPalette(&palette, true); - pixmapLine.SetPalette(&palette, !hasFocus); + pixmapLine->SetPalette(&palette, !hasFocus); //Platform::DebugPrintf("Paint: (%3d,%3d) ... (%3d,%3d)\n", // rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); @@ -1327,7 +1357,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { Surface *surface = surfaceWindow; if (bufferedDraw) { - surface = &pixmapLine; + surface = pixmapLine; } surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); @@ -1453,7 +1483,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { Point from(vs.fixedColumnWidth, 0); PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen, rcClient.right, yposScreen + vs.lineHeight); - surfaceWindow->Copy(rcCopyArea, from, pixmapLine); + surfaceWindow->Copy(rcCopyArea, from, *pixmapLine); } } @@ -1515,10 +1545,16 @@ long Editor::FormatRange(bool draw, RangeToFormat *pfr) { if (!pfr) return 0; - Surface *surface = new Surface(); + Surface *surface = Surface::Allocate(); + if (!surface) + return 0; surface->Init(pfr->hdc); surface->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); - Surface *surfaceMeasure = new Surface(); + Surface *surfaceMeasure = Surface::Allocate(); + if (!surfaceMeasure) { + delete surface; + return 0; + } surfaceMeasure->Init(pfr->hdcTarget); surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == pdoc->dbcsCodePage); diff --git a/src/Editor.h b/src/Editor.h index a51fd86f9..6f4f54e98 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -107,11 +107,11 @@ protected: // ScintillaBase subclass needs access to much of Editor int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret bool horizontalScrollBarVisible; - Surface pixmapLine; - Surface pixmapSelMargin; - Surface pixmapSelPattern; - Surface pixmapIndentGuide; - Surface pixmapIndentGuideHighlight; + Surface *pixmapLine; + Surface *pixmapSelMargin; + Surface *pixmapSelPattern; + Surface *pixmapIndentGuide; + Surface *pixmapIndentGuideHighlight; KeyMap kmap; diff --git a/src/UniConversion.cxx b/src/UniConversion.cxx index c3f960c62..15cad6382 100644 --- a/src/UniConversion.cxx +++ b/src/UniConversion.cxx @@ -52,9 +52,6 @@ unsigned int UCS2Length(const char *s, unsigned int len) { } unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen) { -#ifdef USE_API - return ::MultiByteToWideChar(CP_UTF8, 0, s, len, tbuf, tlen); -#else unsigned int ui=0; const unsigned char *us = reinterpret_cast<const unsigned char *>(s); unsigned int i=0; @@ -76,5 +73,4 @@ unsigned int UCS2FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsign ui++; } return ui; -#endif } diff --git a/src/WindowAccessor.cxx b/src/WindowAccessor.cxx index cd419572c..e02bf90e4 100644 --- a/src/WindowAccessor.cxx +++ b/src/WindowAccessor.cxx @@ -20,7 +20,6 @@ WindowAccessor::~WindowAccessor() { } -#if PLAT_WIN bool WindowAccessor::InternalIsLeadByte(char ch) { if (SC_CP_UTF8 == codePage) // For lexing, all characters >= 0x80 are treated the @@ -29,13 +28,6 @@ bool WindowAccessor::InternalIsLeadByte(char ch) { else return Platform::IsDBCSLeadByte(codePage, ch); } -#else -// PLAT_GTK or PLAT_WX -// TODO: support DBCS under GTK+ and WX -bool WindowAccessor::InternalIsLeadByte(char) { - return false; -} -#endif void WindowAccessor::Fill(int position) { if (lenDoc == -1) diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 6a6c38029..e8509f69d 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -235,7 +235,64 @@ void Font::Release() { id = 0; } -Surface::Surface() : +class SurfaceImpl : Surface { + bool unicodeMode; + void *hdc; // HDC + bool hdcOwned; + void *pen; // HPEN + void *penOld; // HPEN + void *brush; // HBRUSH + void *brushOld; // HBRUSH + void *font; // HFONT + void *fontOld; // HFONT + void *bitmap; // HBITMAP + void *bitmapOld; // HBITMAP + void *paletteOld; // HPALETTE + void BrushColor(ColourAllocated back); + void SetFont(Font &font_); +public: + Surface(); + ~Surface(); + + void Init(); + void Init(SurfaceID sid); + void InitPixMap(int width, int height, Surface *surface_); + + void Release(); + bool Initialised(); + void PenColour(ColourAllocated fore); + int LogPixelsY(); + int DeviceHeightFont(int points); + void MoveTo(int x_, int y_); + void LineTo(int x_, int y_); + void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); + void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void FillRectangle(PRectangle rc, ColourAllocated back); + void FillRectangle(PRectangle rc, Surface &surfacePattern); + void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); + void Copy(PRectangle rc, Point from, Surface &surfaceSource); + + void DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); + void MeasureWidths(Font &font_, const char *s, int len, int *positions); + int WidthText(Font &font_, const char *s, int len); + int WidthChar(Font &font_, char ch); + int Ascent(Font &font_); + int Descent(Font &font_); + int InternalLeading(Font &font_); + int ExternalLeading(Font &font_); + int Height(Font &font_); + int AverageCharWidth(Font &font_); + + int SetPalette(Palette *pal, bool inBackGround); + void SetClip(PRectangle rc); + void FlushCachedState(); + + void SetUnicodeMode(bool unicodeMode_); +}; + +SurfaceImpl::SurfaceImpl() : unicodeMode(false), hdc(0), hdcOwned(false), pen(0), penOld(0), @@ -245,11 +302,11 @@ Surface::Surface() : paletteOld(0) { } -Surface::~Surface() { +SurfaceImpl::~SurfaceImpl() { Release(); } -void Surface::Release() { +void SurfaceImpl::Release() { if (penOld) { ::SelectObject(reinterpret_cast<HDC>(hdc), penOld); ::DeleteObject(pen); @@ -287,24 +344,24 @@ void Surface::Release() { } } -bool Surface::Initialised() { +bool SurfaceImpl::Initialised() { return hdc != 0; } -void Surface::Init() { +void SurfaceImpl::Init() { Release(); hdc = ::CreateCompatibleDC(NULL); hdcOwned = true; ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } -void Surface::Init(SurfaceID sid) { +void SurfaceImpl::Init(SurfaceID sid) { Release(); hdc = sid; ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } -void Surface::InitPixMap(int width, int height, Surface *surface_) { +void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_) { Release(); hdc = ::CreateCompatibleDC(reinterpret_cast<HDC>(surface_->hdc)); hdcOwned = true; @@ -313,7 +370,7 @@ void Surface::InitPixMap(int width, int height, Surface *surface_) { ::SetTextAlign(reinterpret_cast<HDC>(hdc), TA_BASELINE); } -void Surface::PenColour(ColourAllocated fore) { +void SurfaceImpl::PenColour(ColourAllocated fore) { if (pen) { ::SelectObject(reinterpret_cast<HDC>(hdc), penOld); ::DeleteObject(pen); @@ -324,7 +381,7 @@ void Surface::PenColour(ColourAllocated fore) { penOld = static_cast<HPEN>(::SelectObject(reinterpret_cast<HDC>(hdc), pen)); } -void Surface::BrushColor(ColourAllocated back) { +void SurfaceImpl::BrushColor(ColourAllocated back) { if (brush) { ::SelectObject(reinterpret_cast<HDC>(hdc), brushOld); ::DeleteObject(brush); @@ -337,7 +394,7 @@ void Surface::BrushColor(ColourAllocated back) { brushOld = static_cast<HBRUSH>(::SelectObject(reinterpret_cast<HDC>(hdc), brush)); } -void Surface::SetFont(Font &font_) { +void SurfaceImpl::SetFont(Font &font_) { if (font_.GetID() != font) { if (fontOld) { ::SelectObject(reinterpret_cast<HDC>(hdc), font_.GetID()); @@ -348,35 +405,35 @@ void Surface::SetFont(Font &font_) { } } -int Surface::LogPixelsY() { +int SurfaceImpl::LogPixelsY() { return ::GetDeviceCaps(reinterpret_cast<HDC>(hdc), LOGPIXELSY); } -int Surface::DeviceHeightFont(int points) { +int SurfaceImpl::DeviceHeightFont(int points) { return ::MulDiv(points, LogPixelsY(), 72); } -void Surface::MoveTo(int x_, int y_) { +void SurfaceImpl::MoveTo(int x_, int y_) { ::MoveToEx(reinterpret_cast<HDC>(hdc), x_, y_, 0); } -void Surface::LineTo(int x_, int y_) { +void SurfaceImpl::LineTo(int x_, int y_) { ::LineTo(reinterpret_cast<HDC>(hdc), x_, y_); } -void Surface::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColor(back); ::Polygon(reinterpret_cast<HDC>(hdc), reinterpret_cast<POINT *>(pts), npts); } -void Surface::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColor(back); ::Rectangle(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.right, rc.bottom); } -void Surface::FillRectangle(PRectangle rc, ColourAllocated back) { +void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) { // Using ExtTextOut rather than a FillRect ensures that no dithering occurs. // There is no need to allocate a brush either. RECT rcw = RectFromPRectangle(rc); @@ -384,7 +441,7 @@ void Surface::FillRectangle(PRectangle rc, ColourAllocated back) { ::ExtTextOut(reinterpret_cast<HDC>(hdc), rc.left, rc.top, ETO_OPAQUE, &rcw, "", 0, NULL); } -void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) { +void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { HBRUSH br; if (surfacePattern.bitmap) br = ::CreatePatternBrush(reinterpret_cast<HBITMAP>(surfacePattern.bitmap)); @@ -395,7 +452,7 @@ void Surface::FillRectangle(PRectangle rc, Surface &surfacePattern) { ::DeleteObject(br); } -void Surface::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColor(back); ::RoundRect(reinterpret_cast<HDC>(hdc), @@ -404,13 +461,13 @@ void Surface::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAlloca 8, 8 ); } -void Surface::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { +void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColor(back); ::Ellipse(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.right, rc.bottom); } -void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) { +void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { ::BitBlt(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.Width(), rc.Height(), reinterpret_cast<HDC>(surfaceSource.hdc), from.x, from.y, SRCCOPY); @@ -418,7 +475,7 @@ void Surface::Copy(PRectangle rc, Point from, Surface &surfaceSource) { #define MAX_US_LEN 5000 -void Surface::DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, +void SurfaceImpl::DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { SetFont(font_); ::SetTextColor(reinterpret_cast<HDC>(hdc), fore.AsLong()); @@ -434,7 +491,7 @@ void Surface::DrawText(PRectangle rc, Font &font_, int ybase, const char *s, int } } -void Surface::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, +void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { SetFont(font_); ::SetTextColor(reinterpret_cast<HDC>(hdc), fore.AsLong()); @@ -450,7 +507,7 @@ void Surface::DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char } } -int Surface::WidthText(Font &font_, const char *s, int len) { +int SurfaceImpl::WidthText(Font &font_, const char *s, int len) { SetFont(font_); SIZE sz={0,0}; if (unicodeMode) { @@ -464,7 +521,7 @@ int Surface::WidthText(Font &font_, const char *s, int len) { return sz.cx; } -void Surface::MeasureWidths(Font &font_, const char *s, int len, int *positions) { +void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) { SetFont(font_); SIZE sz={0,0}; int fit = 0; @@ -515,56 +572,56 @@ void Surface::MeasureWidths(Font &font_, const char *s, int len, int *positions) } } -int Surface::WidthChar(Font &font_, char ch) { +int SurfaceImpl::WidthChar(Font &font_, char ch) { SetFont(font_); SIZE sz; ::GetTextExtentPoint32(reinterpret_cast<HDC>(hdc), &ch, 1, &sz); return sz.cx; } -int Surface::Ascent(Font &font_) { +int SurfaceImpl::Ascent(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmAscent; } -int Surface::Descent(Font &font_) { +int SurfaceImpl::Descent(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmDescent; } -int Surface::InternalLeading(Font &font_) { +int SurfaceImpl::InternalLeading(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmInternalLeading; } -int Surface::ExternalLeading(Font &font_) { +int SurfaceImpl::ExternalLeading(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmExternalLeading; } -int Surface::Height(Font &font_) { +int SurfaceImpl::Height(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmHeight; } -int Surface::AverageCharWidth(Font &font_) { +int SurfaceImpl::AverageCharWidth(Font &font_) { SetFont(font_); TEXTMETRIC tm; ::GetTextMetrics(reinterpret_cast<HDC>(hdc), &tm); return tm.tmAveCharWidth; } -int Surface::SetPalette(Palette *pal, bool inBackGround) { +int SurfaceImpl::SetPalette(Palette *pal, bool inBackGround) { if (paletteOld) { ::SelectPalette(reinterpret_cast<HDC>(hdc), reinterpret_cast<HPALETTE>(paletteOld),TRUE); @@ -580,16 +637,20 @@ int Surface::SetPalette(Palette *pal, bool inBackGround) { return changes; } -void Surface::SetClip(PRectangle rc) { +void SurfaceImpl::SetClip(PRectangle rc) { ::IntersectClipRect(reinterpret_cast<HDC>(hdc), rc.left, rc.top, rc.right, rc.bottom); } -void Surface::FlushCachedState() { +void SurfaceImpl::FlushCachedState() { pen = 0; brush = 0; font = 0; } +void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) { + unicodeMode=unicodeMode_; +} + Window::~Window() { } |