diff options
| -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_;  } | 
