diff options
author | Neil <nyamatongwe@gmail.com> | 2021-03-20 12:53:27 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2021-03-20 12:53:27 +1100 |
commit | 921df6efca5b385790a2806f8b8844becb36e773 (patch) | |
tree | d84a6c8801e83a972485c052559ab9997e8073d2 | |
parent | 2813306346e4087679915c2b30f1be4949f0228a (diff) | |
download | scintilla-mirror-921df6efca5b385790a2806f8b8844becb36e773.tar.gz |
Add AllocatePixMap method on Surface to create a pixmap surface.
-rw-r--r-- | cocoa/PlatCocoa.h | 2 | ||||
-rw-r--r-- | cocoa/PlatCocoa.mm | 52 | ||||
-rwxr-xr-x | gtk/PlatGTK.cxx | 53 | ||||
-rw-r--r-- | qt/ScintillaEditBase/PlatQt.cpp | 15 | ||||
-rw-r--r-- | qt/ScintillaEditBase/PlatQt.h | 17 | ||||
-rw-r--r-- | src/Platform.h | 1 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 67 |
7 files changed, 173 insertions, 34 deletions
diff --git a/cocoa/PlatCocoa.h b/cocoa/PlatCocoa.h index 040821cb8..f8a941f95 100644 --- a/cocoa/PlatCocoa.h +++ b/cocoa/PlatCocoa.h @@ -75,11 +75,13 @@ private: public: SurfaceImpl(); + SurfaceImpl(const SurfaceImpl *surface, int width, int height); ~SurfaceImpl() override; void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + std::unique_ptr<Surface> AllocatePixMap(int width, int height) override; CGContextRef GetContext() { return gc; } void SetMode(SurfaceMode mode) override; diff --git a/cocoa/PlatCocoa.mm b/cocoa/PlatCocoa.mm index b5e1da79b..4020c3f09 100644 --- a/cocoa/PlatCocoa.mm +++ b/cocoa/PlatCocoa.mm @@ -364,6 +364,54 @@ SurfaceImpl::SurfaceImpl() { Release(); } +SurfaceImpl::SurfaceImpl(const SurfaceImpl *surface, int width, int height) { + x = 0; + y = 0; + + textLayout.reset(new QuartzTextLayout()); + + // Create a new bitmap context, along with the RAM for the bitmap itself + bitmapWidth = width; + bitmapHeight = height; + + const int bitmapBytesPerRow = (width * BYTES_PER_PIXEL); + const int bitmapByteCount = (bitmapBytesPerRow * height); + + // Create an RGB color space. + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + if (colorSpace == NULL) + return; + + // Create the bitmap. + bitmapData.reset(new uint8_t[bitmapByteCount]); + // create the context + gc = CGBitmapContextCreate(bitmapData.get(), + width, + height, + BITS_PER_COMPONENT, + bitmapBytesPerRow, + colorSpace, + kCGImageAlphaPremultipliedLast); + + if (gc == NULL) { + // the context couldn't be created for some reason, + // and we have no use for the bitmap without the context + bitmapData.reset(); + } + + // the context retains the color space, so we can release it + CGColorSpaceRelease(colorSpace); + + if (gc && bitmapData) { + // "Erase" to white. + CGContextClearRect(gc, CGRectMake(0, 0, width, height)); + CGContextSetRGBFillColor(gc, 1.0, 1.0, 1.0, 1.0); + CGContextFillRect(gc, CGRectMake(0, 0, width, height)); + } + + mode = surface->mode; +} + //-------------------------------------------------------------------------------------------------- SurfaceImpl::~SurfaceImpl() { @@ -478,6 +526,10 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID } } +std::unique_ptr<Surface> SurfaceImpl::AllocatePixMap(int width, int height) { + return std::make_unique<SurfaceImpl>(this, width, height); +} + //-------------------------------------------------------------------------------------------------- void SurfaceImpl::SetMode(SurfaceMode mode_) { diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx index 495c0d790..8be8b6bf3 100755 --- a/gtk/PlatGTK.cxx +++ b/gtk/PlatGTK.cxx @@ -127,21 +127,22 @@ namespace Scintilla { // SurfaceID is a cairo_t* class SurfaceImpl : public Surface { SurfaceMode mode; - encodingType et; - cairo_t *context; - cairo_surface_t *psurf; - int x; - int y; - bool inited; - bool createdGC; - PangoContext *pcontext; - PangoLayout *layout; + encodingType et= singleByte; + cairo_t *context = nullptr; + cairo_surface_t *psurf = nullptr; + int x = 0; + int y = 0; + bool inited = false; + bool createdGC = false; + PangoContext *pcontext = nullptr; + PangoLayout *layout = nullptr; Converter conv; - int characterSet; + int characterSet = -1; void SetConverter(int characterSet_); void CairoRectangle(PRectangle rc); public: SurfaceImpl() noexcept; + SurfaceImpl(cairo_t *context_, int width, int height, SurfaceMode mode_) noexcept; // Deleted so SurfaceImpl objects can not be copied. SurfaceImpl(const SurfaceImpl&) = delete; SurfaceImpl(SurfaceImpl&&) = delete; @@ -152,6 +153,7 @@ public: void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + std::unique_ptr<Surface> AllocatePixMap(int width, int height) override; void SetMode(SurfaceMode mode_) override; @@ -289,11 +291,28 @@ void SurfaceImpl::CairoRectangle(PRectangle rc) { cairo_rectangle(context, rc.left, rc.top, rc.Width(), rc.Height()); } -SurfaceImpl::SurfaceImpl() noexcept : et(singleByte), - context(nullptr), - psurf(nullptr), - x(0), y(0), inited(false), createdGC(false), - pcontext(nullptr), layout(nullptr), characterSet(-1) { +SurfaceImpl::SurfaceImpl() noexcept { +} + +SurfaceImpl::SurfaceImpl(cairo_t *context_, int width, int height, SurfaceMode mode_) noexcept { + if (height > 0 && width > 0) { + cairo_surface_t *psurfContext = cairo_get_target(context_); + psurf = cairo_surface_create_similar( + psurfContext, + CAIRO_CONTENT_COLOR_ALPHA, width, height); + context = cairo_create(psurf); + pcontext = pango_cairo_create_context(context); + PLATFORM_ASSERT(pcontext); + layout = pango_layout_new(pcontext); + PLATFORM_ASSERT(layout); + cairo_rectangle(context, 0, 0, width, height); + cairo_set_source_rgb(context, 1.0, 0, 0); + cairo_fill(context); + cairo_set_line_width(context, 1); + createdGC = true; + inited = true; + mode = mode_; + } } SurfaceImpl::~SurfaceImpl() { @@ -406,6 +425,10 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID SetMode(surfImpl->mode); } +std::unique_ptr<Surface> SurfaceImpl::AllocatePixMap(int width, int height) { + return std::make_unique<SurfaceImpl>(context, width, height, mode); +} + void SurfaceImpl::SetMode(SurfaceMode mode_) { mode = mode_; if (mode.codePage == SC_CP_UTF8) { diff --git a/qt/ScintillaEditBase/PlatQt.cpp b/qt/ScintillaEditBase/PlatQt.cpp index 6503d9c19..d61abf7b2 100644 --- a/qt/ScintillaEditBase/PlatQt.cpp +++ b/qt/ScintillaEditBase/PlatQt.cpp @@ -157,6 +157,16 @@ SurfaceImpl::SurfaceImpl() : device(nullptr), painter(nullptr), deviceOwned(false), painterOwned(false), x(0), y(0), codecName(nullptr), codec(nullptr) {} + +SurfaceImpl::SurfaceImpl(int width, int height, SurfaceMode mode_) +{ + if (width < 1) width = 1; + if (height < 1) height = 1; + deviceOwned = true; + device = new QPixmap(width, height); + mode = mode_; +} + SurfaceImpl::~SurfaceImpl() { Clear(); @@ -203,6 +213,11 @@ void SurfaceImpl::InitPixMap(int width, mode = psurfOther->mode; } +std::unique_ptr<Surface> SurfaceImpl::AllocatePixMap(int width, int height) +{ + return std::make_unique<SurfaceImpl>(width, height, mode); +} + void SurfaceImpl::SetMode(SurfaceMode mode_) { mode = mode_; diff --git a/qt/ScintillaEditBase/PlatQt.h b/qt/ScintillaEditBase/PlatQt.h index 8f4d2c51d..1fc476129 100644 --- a/qt/ScintillaEditBase/PlatQt.h +++ b/qt/ScintillaEditBase/PlatQt.h @@ -73,25 +73,28 @@ constexpr PRectangle RectangleInset(PRectangle rc, XYPOSITION delta) noexcept { class SurfaceImpl : public Surface { private: - QPaintDevice *device; - QPainter *painter; - bool deviceOwned; - bool painterOwned; - float x, y; + QPaintDevice *device = nullptr; + QPainter *painter = nullptr; + bool deviceOwned = false; + bool painterOwned = false; + float x = 0; + float y = 0; SurfaceMode mode; - const char *codecName; - QTextCodec *codec; + const char *codecName = nullptr; + QTextCodec *codec = nullptr; void Clear(); public: SurfaceImpl(); + SurfaceImpl(int width, int height, SurfaceMode mode_); virtual ~SurfaceImpl(); void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface, WindowID wid) override; + std::unique_ptr<Surface> AllocatePixMap(int width, int height) override; void SetMode(SurfaceMode mode) override; diff --git a/src/Platform.h b/src/Platform.h index 3afa24c92..5fa139189 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -189,6 +189,7 @@ public: virtual void Init(WindowID wid)=0; virtual void Init(SurfaceID sid, WindowID wid)=0; virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; + virtual std::unique_ptr<Surface> AllocatePixMap(int width, int height)=0; virtual void SetMode(SurfaceMode mode)=0; diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 3d0db3316..7d8403b9d 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -465,6 +465,7 @@ class SurfaceGDI : public Surface { public: SurfaceGDI() noexcept; + SurfaceGDI(HDC hdcCompatible, int width, int height, SurfaceMode mode_, int logPixelsY_) noexcept; // Deleted so SurfaceGDI objects can not be copied. SurfaceGDI(const SurfaceGDI &) = delete; SurfaceGDI(SurfaceGDI &&) = delete; @@ -476,6 +477,7 @@ public: void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + std::unique_ptr<Surface> AllocatePixMap(int width, int height) override; void SetMode(SurfaceMode mode_) override; @@ -546,6 +548,16 @@ public: SurfaceGDI::SurfaceGDI() noexcept { } +SurfaceGDI::SurfaceGDI(HDC hdcCompatible, int width, int height, SurfaceMode mode_, int logPixelsY_) noexcept { + hdc = ::CreateCompatibleDC(hdc); + hdcOwned = true; + bitmap = ::CreateCompatibleBitmap(hdcCompatible, width, height); + bitmapOld = SelectBitmap(hdc, bitmap); + ::SetTextAlign(hdc, TA_BASELINE); + mode = mode_; + logPixelsY = logPixelsY_; +} + SurfaceGDI::~SurfaceGDI() noexcept { Clear(); } @@ -624,6 +636,10 @@ void SurfaceGDI::InitPixMap(int width, int height, Surface *surface_, WindowID w logPixelsY = DpiForWindow(wid); } +std::unique_ptr<Surface> SurfaceGDI::AllocatePixMap(int width, int height) { + return std::make_unique<SurfaceGDI>(hdc, width, height, mode, logPixelsY); +} + void SurfaceGDI::SetMode(SurfaceMode mode_) { mode = mode_; } @@ -1402,23 +1418,24 @@ class BlobInline; class SurfaceD2D : public Surface { SurfaceMode mode; - int x, y; + int x = 0; + int y = 0; - int codePageText; + int codePageText = 0; - ID2D1RenderTarget *pRenderTarget; - ID2D1BitmapRenderTarget *pBitmapRenderTarget; - bool ownRenderTarget; - int clipsActive; + ID2D1RenderTarget *pRenderTarget = nullptr; + ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr; + bool ownRenderTarget = false; + int clipsActive = 0; - IDWriteTextFormat *pTextFormat; - FLOAT yAscent; - FLOAT yDescent; - FLOAT yInternalLeading; + IDWriteTextFormat *pTextFormat = nullptr; + FLOAT yAscent = 2; + FLOAT yDescent = 1; + FLOAT yInternalLeading = 0; - ID2D1SolidColorBrush *pBrush; + ID2D1SolidColorBrush *pBrush = nullptr; - int logPixelsY; + int logPixelsY = USER_DEFAULT_SCREEN_DPI; void Clear() noexcept; void SetFont(const Font *font_) noexcept; @@ -1426,6 +1443,7 @@ class SurfaceD2D : public Surface { public: SurfaceD2D() noexcept; + SurfaceD2D(ID2D1RenderTarget *pRenderTargetCompatible, int width, int height, SurfaceMode mode_, int logPixelsY_) noexcept; // Deleted so SurfaceD2D objects can not be copied. SurfaceD2D(const SurfaceD2D &) = delete; SurfaceD2D(SurfaceD2D &&) = delete; @@ -1437,6 +1455,7 @@ public: void Init(WindowID wid) override; void Init(SurfaceID sid, WindowID wid) override; void InitPixMap(int width, int height, Surface *surface_, WindowID wid) override; + std::unique_ptr<Surface> AllocatePixMap(int width, int height) override; void SetMode(SurfaceMode mode_) override; @@ -1529,6 +1548,26 @@ SurfaceD2D::SurfaceD2D() noexcept : logPixelsY = USER_DEFAULT_SCREEN_DPI; } +SurfaceD2D::SurfaceD2D(ID2D1RenderTarget *pRenderTargetCompatible, int width, int height, SurfaceMode mode_, int logPixelsY_) noexcept { + const D2D1_SIZE_F desiredSize = D2D1::SizeF(static_cast<float>(width), static_cast<float>(height)); + D2D1_PIXEL_FORMAT desiredFormat; +#ifdef __MINGW32__ + desiredFormat.format = DXGI_FORMAT_UNKNOWN; +#else + desiredFormat = pRenderTargetCompatible->GetPixelFormat(); +#endif + desiredFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE; + const HRESULT hr = pRenderTargetCompatible->CreateCompatibleRenderTarget( + &desiredSize, nullptr, &desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE, &pBitmapRenderTarget); + if (SUCCEEDED(hr)) { + pRenderTarget = pBitmapRenderTarget; + pRenderTarget->BeginDraw(); + ownRenderTarget = true; + } + mode = mode_; + logPixelsY = logPixelsY_; +} + SurfaceD2D::~SurfaceD2D() { Clear(); } @@ -1605,6 +1644,10 @@ void SurfaceD2D::InitPixMap(int width, int height, Surface *surface_, WindowID w mode = psurfOther->mode; } +std::unique_ptr<Surface> SurfaceD2D::AllocatePixMap(int width, int height) { + return std::make_unique<SurfaceD2D>(pRenderTarget, width, height, mode, logPixelsY); +} + void SurfaceD2D::SetMode(SurfaceMode mode_) { mode = mode_; } |