📄 platwx.cpp
字号:
// Scintilla source code edit control// PlatWX.cxx - implementation of platform facilities on wxWidgets// Copyright 1998-1999 by Neil Hodgson <neilh@scintilla.org>// Robin Dunn <robin@aldunn.com>// The License.txt file describes the conditions under which this software may be distributed.#include <ctype.h>#include <wx/wx.h>#include <wx/encconv.h>#include <wx/listctrl.h>#include <wx/mstream.h>#include <wx/image.h>#include <wx/imaglist.h>#include <wx/tokenzr.h>#include "Platform.h"#include "PlatWX.h"#include "wx/wxscintilla.h"Point Point::FromLong(long lpoint) { return Point(lpoint & 0xFFFF, lpoint >> 16);}wxRect wxRectFromPRectangle(PRectangle prc) { wxRect r(prc.left, prc.top, prc.Width(), prc.Height()); return r;}PRectangle PRectangleFromwxRect(wxRect rc) { return PRectangle(rc.GetLeft(), rc.GetTop(), rc.GetRight()+1, rc.GetBottom()+1);}wxColour wxColourFromCA(const ColourAllocated& ca) { ColourDesired cd(ca.AsLong()); return wxColour((unsigned char)cd.GetRed(), (unsigned char)cd.GetGreen(), (unsigned char)cd.GetBlue());}//----------------------------------------------------------------------Palette::Palette() { used = 0; allowRealization = false; size = 100; entries = new ColourPair[size];}Palette::~Palette() { Release(); delete []entries; entries = 0;}void Palette::Release() { used = 0; delete []entries; size = 100; entries = new ColourPair[size];}// This method either adds a colour to the list of wanted colours (want==true)// or retrieves the allocated colour back to the ColourPair.// This is one method to make it easier to keep the code for wanting and retrieving in sync.void Palette::WantFind(ColourPair &cp, bool want) { if (want) { for (int i=0; i < used; i++) { if (entries[i].desired == cp.desired) return; } if (used >= size) { int sizeNew = size * 2; ColourPair *entriesNew = new ColourPair[sizeNew]; for (int j=0; j<size; j++) { entriesNew[j] = entries[j]; } delete []entries; entries = entriesNew; size = sizeNew; } entries[used].desired = cp.desired; entries[used].allocated.Set(cp.desired.AsLong()); used++; } else { for (int i=0; i < used; i++) { if (entries[i].desired == cp.desired) { cp.allocated = entries[i].allocated; return; } } cp.allocated.Set(cp.desired.AsLong()); }}void Palette::Allocate(Window &) { if (allowRealization) {//? TODO ... }}//----------------------------------------------------------------------Font::Font() { id = 0; ascent = 0;}Font::~Font() {}void Font::Create (const char *faceName, int characterSet, int size, bool bold, bool italic, bool extraFontFlag) { Release(); // The minus one is done because since Scintilla uses SC_SHARSET_DEFAULT // internally and we need to have wxFONENCODING_DEFAULT == SC_SHARSET_DEFAULT // so we adjust the encoding before passing it to Scintilla. See also // wxScintilla::StyleSetCharacterSet wxFontEncoding encoding = (wxFontEncoding)(characterSet-1); wxFontEncodingArray ea = wxEncodingConverter::GetPlatformEquivalents(encoding); if (ea.GetCount()) encoding = ea[0]; wxFont* font = new wxFont (size, wxDEFAULT, italic ? wxITALIC : wxNORMAL, bold ? wxBOLD : wxNORMAL, false, sci2wx(faceName), encoding); font->SetNoAntiAliasing (!extraFontFlag); id = font;}void Font::Release() { if (id) delete (wxFont*)id; id = 0;}//----------------------------------------------------------------------class SurfaceImpl : public Surface {private: wxDC* hdc; bool hdcOwned; wxBitmap* bitmap; int x; int y; bool unicodeMode;public: SurfaceImpl(); ~SurfaceImpl(); virtual void Init(WindowID wid); virtual void Init(SurfaceID sid, WindowID wid); virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid); virtual void Release(); virtual bool Initialised(); virtual void PenColour(ColourAllocated fore); virtual int LogPixelsY(); virtual int DeviceHeightFont(int points); virtual void MoveTo(int x_, int y_); virtual void LineTo(int x_, int y_); virtual void Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back); virtual void RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back); virtual void FillRectangle(PRectangle rc, ColourAllocated back); virtual void FillRectangle(PRectangle rc, Surface &surfacePattern); virtual void RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back); virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, ColourAllocated outline, int alphaOutline, int flags); virtual void Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back); virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource); virtual void DrawTextNoClip(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); virtual void DrawTextClipped(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back); virtual void DrawTextTransparent(PRectangle rc, Font &font_, int ybase, const char *s, int len, ColourAllocated fore); virtual void MeasureWidths(Font &font_, const char *s, int len, int *positions); virtual int WidthText(Font &font_, const char *s, int len); virtual int WidthChar(Font &font_, char ch); virtual int Ascent(Font &font_); virtual int Descent(Font &font_); virtual int InternalLeading(Font &font_); virtual int ExternalLeading(Font &font_); virtual int Height(Font &font_); virtual int AverageCharWidth(Font &font_); virtual int SetPalette(Palette *pal, bool inBackGround); virtual void SetClip(PRectangle rc); virtual void FlushCachedState(); virtual void SetUnicodeMode(bool unicodeMode_); virtual void SetDBCSMode(int codePage); void BrushColour(ColourAllocated back); void SetFont(Font &font_);};SurfaceImpl::SurfaceImpl() : hdc(0), hdcOwned(0), bitmap(0), x(0), y(0), unicodeMode(0){}SurfaceImpl::~SurfaceImpl() { Release();}void SurfaceImpl::Init(WindowID wid) {#if 0 Release(); hdc = new wxMemoryDC(); hdcOwned = true;#else // On Mac and GTK the DC is not really valid until it has a bitmap // selected into it. So instead of just creating the DC with no bitmap, // go ahead and give it one. InitPixMap(1,1,NULL,wid);#endif}void SurfaceImpl::Init(SurfaceID hdc_, WindowID) { Release(); hdc = (wxDC*)hdc_;}void SurfaceImpl::InitPixMap(int width, int height, Surface *WXUNUSED(surface_), WindowID) { Release(); hdc = new wxMemoryDC(); hdcOwned = true; if (width < 1) width = 1; if (height < 1) height = 1; bitmap = new wxBitmap(width, height); ((wxMemoryDC*)hdc)->SelectObject(*bitmap);}void SurfaceImpl::Release() { if (bitmap) { ((wxMemoryDC*)hdc)->SelectObject(wxNullBitmap); delete bitmap; bitmap = 0; } if (hdcOwned) { delete hdc; hdc = 0; hdcOwned = false; }}bool SurfaceImpl::Initialised() { return hdc != 0;}void SurfaceImpl::PenColour(ColourAllocated fore) { hdc->SetPen(wxPen(wxColourFromCA(fore), 1, wxSOLID));}void SurfaceImpl::BrushColour(ColourAllocated back) { hdc->SetBrush(wxBrush(wxColourFromCA(back), wxSOLID));}void SurfaceImpl::SetFont(Font &font_) { if (font_.GetID()) { hdc->SetFont(*((wxFont*)font_.GetID())); }}int SurfaceImpl::LogPixelsY() { return hdc->GetPPI().y;}int SurfaceImpl::DeviceHeightFont(int points) { return points;}void SurfaceImpl::MoveTo(int x_, int y_) { x = x_; y = y_;}void SurfaceImpl::LineTo(int x_, int y_) { hdc->DrawLine(x,y, x_,y_); x = x_; y = y_;}void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColour(back); hdc->DrawPolygon(npts, (wxPoint*)pts);}void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColour(back); hdc->DrawRectangle(wxRectFromPRectangle(rc));}void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) { BrushColour(back); hdc->SetPen(*wxTRANSPARENT_PEN); hdc->DrawRectangle(wxRectFromPRectangle(rc));}void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) { wxBrush br; if (((SurfaceImpl&)surfacePattern).bitmap) br = wxBrush(*((SurfaceImpl&)surfacePattern).bitmap); else // Something is wrong so display in red br = wxBrush(*wxRED, wxSOLID); hdc->SetPen(*wxTRANSPARENT_PEN); hdc->SetBrush(br); hdc->DrawRectangle(wxRectFromPRectangle(rc));}void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColour(back); hdc->DrawRoundedRectangle(wxRectFromPRectangle(rc), 4);}void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill, ColourAllocated outline, int alphaOutline, int flags) {//? TODO ...}void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) { PenColour(fore); BrushColour(back); hdc->DrawEllipse(wxRectFromPRectangle(rc));}void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) { wxRect r = wxRectFromPRectangle(rc); hdc->Blit(r.x, r.y, r.width, r.height, ((SurfaceImpl&)surfaceSource).hdc, from.x, from.y, wxCOPY);}void SurfaceImpl::DrawTextNoClip(PRectangle rc, Font &font, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { SetFont(font); hdc->SetTextForeground(wxColourFromCA(fore)); hdc->SetTextBackground(wxColourFromCA(back)); FillRectangle(rc, back); // ybase is where the baseline should be, but wxWin uses the upper left // corner, so I need to calculate the real position for the text... hdc->DrawText(sci2wx(s, len), rc.left, ybase - font.ascent);}void SurfaceImpl::DrawTextClipped(PRectangle rc, Font &font, int ybase, const char *s, int len, ColourAllocated fore, ColourAllocated back) { SetFont(font); hdc->SetTextForeground(wxColourFromCA(fore)); hdc->SetTextBackground(wxColourFromCA(back)); FillRectangle(rc, back); hdc->SetClippingRegion(wxRectFromPRectangle(rc)); // see comments above hdc->DrawText(sci2wx(s, len), rc.left, ybase - font.ascent); hdc->DestroyClippingRegion();}void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font, int ybase, const char *s, int len, ColourAllocated fore) { SetFont(font); hdc->SetTextForeground(wxColourFromCA(fore)); hdc->SetBackgroundMode(wxTRANSPARENT); // ybase is where the baseline should be, but wxWin uses the upper left // corner, so I need to calculate the real position for the text... hdc->DrawText(sci2wx(s, len), rc.left, ybase - font.ascent); hdc->SetBackgroundMode(wxSOLID);}void SurfaceImpl::MeasureWidths(Font &font, const char *s, int len, int *positions) { wxString str = sci2wx(s, len); SetFont(font);#if !wxCHECK_VERSION(2, 5, 0)#ifndef __WXMAC__ // Calculate the position of each character based on the widths of // the previous characters int* tpos = new int[len+1]; int totalWidth = 0; size_t i; for (i=0; i<str.Length(); i++) { int w, h; hdc->GetTextExtent(str[i], &w, &h); totalWidth += w; tpos[i] = totalWidth; }#else // Instead of a running total, remeasure from the begining of the // text for each character's position. This is because with AA fonts // on OS X widths can be fractions of pixels wide when more than one // are drawn together, so the sum of all character widths is not necessarily // (and probably not) the same as the whole string width. int* tpos = new int[len+1]; size_t i; for (i=0; i<str.Length(); i++) { int w, h; hdc->GetTextExtent(str.Left(i+1), &w, &h); tpos[i] = w; }#endif#else wxArrayInt tpos; hdc->GetPartialTextExtents(str, tpos);#endif#if wxUSE_UNICODE // Map the widths for UCS-2 characters back to the UTF-8 input string // NOTE: I don't think this is right for when sizeof(wxChar) > 2, ie wxGTK2 // so figure it out and fix it! int j = 0; size_t ui = 0; while ((int)j < len) { unsigned char uch = (unsigned char)s[j]; positions[j++] = tpos[ui]; if (uch >= 0x80) { if (uch < (0x80 + 0x40 + 0x20)) { positions[j++] = tpos[ui]; } else { positions[j++] = tpos[ui]; positions[j++] = tpos[ui]; } } ui++; }#else // If not unicode then just use the widths we have#if !wxCHECK_VERSION(2, 5, 0) memcpy(positions, tpos, len * sizeof(*tpos));#else#if wxUSE_STL std::copy(tpos.begin(), tpos.end(), positions);#else memcpy(positions, tpos.begin(), len * sizeof(int));#endif#endif#endif#if !wxCHECK_VERSION(2, 5, 0) delete [] tpos;#endif}int SurfaceImpl::WidthText(Font &font, const char *s, int len) { SetFont(font); int w; int h; hdc->GetTextExtent(sci2wx(s, len), &w, &h); return w;}int SurfaceImpl::WidthChar(Font &font, char ch) { SetFont(font); int w;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -