📄 agg_platform_support.cpp
字号:
//----------------------------------------------------------------------------// Anti-Grain Geometry (AGG) - Version 2.5// A high quality rendering engine for C++// Copyright (C) 2002-2006 Maxim Shemanarev// Copyright (C) 2004 Stephan Assmus (superstippi@gmx.de)// Contact: mcseem@antigrain.com// mcseemagg@yahoo.com// http://antigrain.com// // AGG is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.// // AGG is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with AGG; if not, write to the Free Software// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA.//----------------------------------------------------------------------------#include <new>#include <stdio.h>#include <Alert.h>#include <Application.h>#include <Bitmap.h>#include <Message.h>#include <MessageRunner.h>#include <Messenger.h>#include <Path.h>#include <Roster.h>#include <TranslationUtils.h>#include <View.h>#include <Window.h>#include <string.h>#include "platform/agg_platform_support.h"#include "util/agg_color_conv_rgb8.h"using std::nothrow;static voidattach_buffer_to_BBitmap(agg::rendering_buffer& buffer, BBitmap* bitmap, bool flipY){ uint8* bits = (uint8*)bitmap->Bits(); uint32 width = bitmap->Bounds().IntegerWidth() + 1; uint32 height = bitmap->Bounds().IntegerHeight() + 1; int32 bpr = bitmap->BytesPerRow(); if (flipY) {// XXX: why don't I have to do this?!?// bits += bpr * (height - 1); bpr = -bpr; } buffer.attach(bits, width, height, bpr);}static color_spacepix_format_to_color_space(agg::pix_format_e format){ color_space bitmapFormat = B_NO_COLOR_SPACE; switch (format) { case agg::pix_format_rgb555: bitmapFormat = B_RGB15; break; case agg::pix_format_rgb565: bitmapFormat = B_RGB16; break; case agg::pix_format_rgb24: case agg::pix_format_bgr24: bitmapFormat = B_RGB24; break; case agg::pix_format_rgba32: case agg::pix_format_argb32: case agg::pix_format_abgr32: case agg::pix_format_bgra32: bitmapFormat = B_RGBA32; break; } return bitmapFormat;}// #pragma mark -class AGGView : public BView { public: AGGView(BRect frame, agg::platform_support* agg, agg::pix_format_e format, bool flipY); virtual ~AGGView(); virtual void AttachedToWindow(); virtual void DetachedFromWindow(); virtual void MessageReceived(BMessage* message); virtual void Draw(BRect updateRect); virtual void FrameResized(float width, float height); virtual void KeyDown(const char* bytes, int32 numBytes); virtual void MouseDown(BPoint where); virtual void MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage); virtual void MouseUp(BPoint where); BBitmap* Bitmap() const; uint8 LastKeyDown() const; uint32 MouseButtons(); void Update(); void ForceRedraw(); unsigned GetKeyFlags(); private: BBitmap* fBitmap; agg::pix_format_e fFormat; bool fFlipY; agg::platform_support* fAGG; uint32 fMouseButtons; int32 fMouseX; int32 fMouseY; uint8 fLastKeyDown; bool fRedraw; BMessageRunner* fPulse; bigtime_t fLastPulse; bool fEnableTicks;};AGGView::AGGView(BRect frame, agg::platform_support* agg, agg::pix_format_e format, bool flipY) : BView(frame, "AGG View", B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW), fFormat(format), fFlipY(flipY), fAGG(agg), fMouseButtons(0), fMouseX(-1), fMouseY(-1), fLastKeyDown(0), fRedraw(true), fPulse(NULL), fLastPulse(0), fEnableTicks(true){ SetViewColor(B_TRANSPARENT_32_BIT); frame.OffsetTo(0.0, 0.0); fBitmap = new BBitmap(frame, 0, pix_format_to_color_space(fFormat)); if (fBitmap->IsValid()) { attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); } else { delete fBitmap; fBitmap = NULL; }}AGGView::~AGGView(){ delete fBitmap; delete fPulse;}voidAGGView::AttachedToWindow(){ BMessage message('tick'); BMessenger target(this, Looper()); delete fPulse;// BScreen screen;// TODO: calc screen retrace fPulse = new BMessageRunner(target, &message, 40000); // make sure we call this once fAGG->on_resize(Bounds().IntegerWidth() + 1, Bounds().IntegerHeight() + 1); MakeFocus();}voidAGGView::DetachedFromWindow(){ delete fPulse; fPulse = NULL;}voidAGGView::MessageReceived(BMessage* message){ bigtime_t now = system_time(); switch (message->what) { case 'tick': // drop messages that have piled up if (/*now - fLastPulse > 30000*/fEnableTicks) { fLastPulse = now; if (!fAGG->wait_mode()) fAGG->on_idle(); Window()->PostMessage('entk', this); fEnableTicks = false; } else {// printf("dropping tick message (%lld)\n", now - fLastPulse); } break; case 'entk': fEnableTicks = true; if (now - fLastPulse > 30000) { fLastPulse = now; if (!fAGG->wait_mode()) fAGG->on_idle(); } break; default: BView::MessageReceived(message); break; }}voidAGGView::Draw(BRect updateRect){ if (fBitmap) { if (fRedraw) { fAGG->on_draw(); fRedraw = false; } if (fFormat == agg::pix_format_bgra32) { DrawBitmap(fBitmap, updateRect, updateRect); } else { BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32); agg::rendering_buffer rbufSrc; attach_buffer_to_BBitmap(rbufSrc, fBitmap, false); agg::rendering_buffer rbufDst; attach_buffer_to_BBitmap(rbufDst, bitmap, false); switch(fFormat) { case agg::pix_format_rgb555: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_rgb555_to_bgra32()); break; case agg::pix_format_rgb565: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_rgb565_to_bgra32()); break; case agg::pix_format_rgb24: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_rgb24_to_bgra32()); break; case agg::pix_format_bgr24: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_bgr24_to_bgra32()); break; case agg::pix_format_rgba32: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_rgba32_to_bgra32()); break; case agg::pix_format_argb32: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_argb32_to_bgra32()); break; case agg::pix_format_abgr32: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_abgr32_to_bgra32()); break; case agg::pix_format_bgra32: agg::color_conv(&rbufDst, &rbufSrc, agg::color_conv_bgra32_to_bgra32()); break; } DrawBitmap(bitmap, updateRect, updateRect); delete bitmap; } } else { FillRect(updateRect); }}voidAGGView::FrameResized(float width, float height){ BRect r(0.0, 0.0, width, height); BBitmap* bitmap = new BBitmap(r, 0, pix_format_to_color_space(fFormat)); if (bitmap->IsValid()) { delete fBitmap; fBitmap = bitmap; attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); fAGG->trans_affine_resizing((int)width + 1, (int)height + 1); // pass the event on to AGG fAGG->on_resize((int)width + 1, (int)height + 1); fRedraw = true; Invalidate(); } else delete bitmap;}voidAGGView::KeyDown(const char* bytes, int32 numBytes){ if (bytes && numBytes > 0) { fLastKeyDown = bytes[0]; bool left = false; bool up = false; bool right = false; bool down = false; switch (fLastKeyDown) { case B_LEFT_ARROW: left = true; break; case B_UP_ARROW: up = true; break; case B_RIGHT_ARROW: right = true; break; case B_DOWN_ARROW: down = true; break; }/* case key_f2: fAGG->copy_window_to_img(agg::platform_support::max_images - 1);fAGG->save_img(agg::platform_support::max_images - 1, "screenshot");break;}*/ if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); }// fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); }}voidAGGView::MouseDown(BPoint where){ BMessage* currentMessage = Window()->CurrentMessage(); if (currentMessage) { if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK) fMouseButtons = B_PRIMARY_MOUSE_BUTTON; } else fMouseButtons = B_PRIMARY_MOUSE_BUTTON; fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { // left mouse button -> see if to handle in controls fAGG->m_ctrls.set_cur(fMouseX, fMouseY); if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } } else { fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); } } } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) { // right mouse button -> simple fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); } SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);}voidAGGView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage){ // workarround missed mouse up events // (if we react too slowly, app_server might have dropped events) BMessage* currentMessage = Window()->CurrentMessage(); int32 buttons = 0; if (currentMessage->FindInt32("buttons", &buttons) < B_OK) { buttons = 0; } if (!buttons) MouseUp(where); fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY, (GetKeyFlags() & agg::mouse_left) != 0)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } else { if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags()); } }}voidAGGView::MouseUp(BPoint where){ fMouseX = (int)where.x; fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; // pass the event on to AGG if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { fMouseButtons = 0; if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) { fAGG->on_ctrl_change(); fAGG->force_redraw(); } fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) { fMouseButtons = 0; fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); }}BBitmap*AGGView::Bitmap() const{ return fBitmap;}uint8AGGView::LastKeyDown() const{ return fLastKeyDown;}uint32AGGView::MouseButtons(){ uint32 buttons = 0; if (LockLooper()) { buttons = fMouseButtons; UnlockLooper(); } return buttons;}void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -