Move zoomer into SampleApp

git-svn-id: http://skia.googlecode.com/svn/trunk@1002 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Scroggo 2011-03-24 18:35:50 +00:00
parent 7f5875d334
commit 0f185c2709
5 changed files with 163 additions and 161 deletions

View File

@ -22,7 +22,6 @@
class SkBitmap;
class SkEvent;
class SkTypeface;
struct SkUnixWindow {
Display* fDisplay;
@ -43,10 +42,6 @@ public:
bool attachGL();
void detachGL();
void presentGL();
void updatePointer(int x, int y);
void toggleZoomer();
bool zoomIn();
bool zoomOut();
//static bool PostEvent(SkEvent* evt, SkEventSinkID, SkMSec delay);
@ -65,12 +60,6 @@ private:
SkUnixWindow fUnixWindow;
void doPaint();
// Latest position of the mouse.
int fMouseX, fMouseY;
int fScale;
// Used by the text showing position and color values.
SkTypeface* fTypeface;
bool fShowZoomer;
typedef SkWindow INHERITED;
};

View File

@ -12,6 +12,7 @@
#include "SampleCode.h"
#include "GrContext.h"
#include "SkTouchGesture.h"
#include "SkTypeface.h"
#define USE_ARROWS_FOR_ZOOM true
//#define DEFAULT_TO_GPU
@ -268,6 +269,14 @@ private:
bool fScale;
bool fRequestGrabImage;
// The following are for the 'fatbits' drawing
// Latest position of the mouse.
int fMouseX, fMouseY;
int fFatBitsScale;
// Used by the text showing position and color values.
SkTypeface* fTypeface;
bool fShowZoomer;
LCDTextDrawFilter::Mode fLCDMode;
int fScrollTestX, fScrollTestY;
@ -279,6 +288,11 @@ private:
void updateTitle();
bool nextSample();
void toggleZoomer();
bool zoomIn();
bool zoomOut();
void updatePointer(int x, int y);
void postAnimatingEvent() {
if (fAnimating) {
SkEvent* evt = new SkEvent(ANIMATING_EVENTTYPE);
@ -292,6 +306,38 @@ private:
typedef SkOSWindow INHERITED;
};
bool SampleWindow::zoomIn()
{
// Arbitrarily decided
if (fFatBitsScale == 25) return false;
fFatBitsScale++;
this->inval(NULL);
return true;
}
bool SampleWindow::zoomOut()
{
if (fFatBitsScale == 1) return false;
fFatBitsScale--;
this->inval(NULL);
return true;
}
void SampleWindow::toggleZoomer()
{
fShowZoomer = !fShowZoomer;
this->inval(NULL);
}
void SampleWindow::updatePointer(int x, int y)
{
fMouseX = x;
fMouseY = y;
if (fShowZoomer) {
this->inval(NULL);
}
}
bool SampleWindow::make3DReady() {
#if defined(SK_SUPPORT_GL)
@ -345,6 +391,11 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
fLCDMode = LCDTextDrawFilter::kNeutral_Mode;
fScrollTestX = fScrollTestY = 0;
fMouseX = fMouseY = 0;
fFatBitsScale = 1;
fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
fShowZoomer = false;
fZoomLevel = 0;
fZoomScale = SK_Scalar1;
@ -374,6 +425,7 @@ SampleWindow::~SampleWindow() {
if (NULL != fGrContext) {
fGrContext->unref();
}
fTypeface->unref();
}
static SkBitmap capture_bitmap(SkCanvas* canvas) {
@ -401,6 +453,26 @@ static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
return false;
}
static void drawText(SkCanvas* canvas, SkString string, SkScalar left, SkScalar top, SkPaint& paint)
{
SkColor desiredColor = paint.getColor();
paint.setColor(SK_ColorWHITE);
const char* c_str = string.c_str();
size_t size = string.size();
SkRect bounds;
paint.measureText(c_str, size, &bounds);
bounds.offset(left, top);
SkScalar inset = SkIntToScalar(-2);
bounds.inset(inset, inset);
canvas->drawRect(bounds, paint);
if (desiredColor != SK_ColorBLACK) {
paint.setColor(SK_ColorBLACK);
canvas->drawText(c_str, size, left + SK_Scalar1, top + SK_Scalar1, paint);
}
paint.setColor(desiredColor);
canvas->drawText(c_str, size, left, top, paint);
}
#define XCLIP_N 8
#define YCLIP_N 8
@ -473,6 +545,87 @@ void SampleWindow::draw(SkCanvas* canvas) {
} else {
this->INHERITED::draw(canvas);
}
if (fShowZoomer) {
int count = canvas->save();
canvas->resetMatrix();
// Ensure the mouse position is on screen.
int width = this->width();
int height = this->height();
if (fMouseX >= width) fMouseX = width - 1;
else if (fMouseX < 0) fMouseX = 0;
if (fMouseY >= height) fMouseY = height - 1;
else if (fMouseY < 0) fMouseY = 0;
SkBitmap bitmap = capture_bitmap(canvas);
// Find the size of the zoomed in view, forced to be odd, so the examined pixel is in the middle.
int zoomedWidth = (width >> 2) | 1;
int zoomedHeight = (height >> 2) | 1;
SkIRect src;
src.set(0, 0, zoomedWidth / fFatBitsScale, zoomedHeight / fFatBitsScale);
src.offset(fMouseX - (src.width()>>1), fMouseY - (src.height()>>1));
SkRect dest;
dest.set(0, 0, SkIntToScalar(zoomedWidth), SkIntToScalar(zoomedHeight));
dest.offset(SkIntToScalar(width - zoomedWidth), SkIntToScalar(height - zoomedHeight));
SkPaint paint;
// Clear the background behind our zoomed in view
paint.setColor(SK_ColorWHITE);
canvas->drawRect(dest, paint);
canvas->drawBitmapRect(bitmap, &src, dest);
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStroke_Style);
// Draw a border around the pixel in the middle
SkRect originalPixel;
originalPixel.set(SkIntToScalar(fMouseX), SkIntToScalar(fMouseY), SkIntToScalar(fMouseX + 1), SkIntToScalar(fMouseY + 1));
SkMatrix matrix;
SkRect scalarSrc;
scalarSrc.set(src);
SkColor color = bitmap.getColor(fMouseX, fMouseY);
if (matrix.setRectToRect(scalarSrc, dest, SkMatrix::kFill_ScaleToFit)) {
SkRect pixel;
matrix.mapRect(&pixel, originalPixel);
// TODO Perhaps measure the values and make the outline white if it's "dark"
if (color == SK_ColorBLACK) {
paint.setColor(SK_ColorWHITE);
}
canvas->drawRect(pixel, paint);
}
paint.setColor(SK_ColorBLACK);
// Draw a border around the destination rectangle
canvas->drawRect(dest, paint);
paint.setStyle(SkPaint::kStrokeAndFill_Style);
// Identify the pixel and its color on screen
paint.setTypeface(fTypeface);
paint.setAntiAlias(true);
SkScalar lineHeight = paint.getFontMetrics(NULL);
SkString string;
string.appendf("(%i, %i)", fMouseX, fMouseY);
SkScalar left = dest.fLeft + SkIntToScalar(3);
SkScalar i = SK_Scalar1;
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Alpha
i += SK_Scalar1;
string.reset();
string.appendf("A: %X", SkColorGetA(color));
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Red
i += SK_Scalar1;
string.reset();
string.appendf("R: %X", SkColorGetR(color));
paint.setColor(SK_ColorRED);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Green
i += SK_Scalar1;
string.reset();
string.appendf("G: %X", SkColorGetG(color));
paint.setColor(SK_ColorGREEN);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Blue
i += SK_Scalar1;
string.reset();
string.appendf("B: %X", SkColorGetB(color));
paint.setColor(SK_ColorBLUE);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
canvas->restoreToCount(count);
}
}
void SampleWindow::onDraw(SkCanvas* canvas) {
@ -825,8 +978,6 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
this->updateTitle();
this->inval(NULL);
break;
#ifdef SK_BUILD_FOR_UNIX
// These methods have not been written for other platforms yet.
case 'i':
this->zoomIn();
break;
@ -836,7 +987,6 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
case 'z':
this->toggleZoomer();
break;
#endif
default:
break;
}
@ -912,6 +1062,9 @@ bool SampleWindow::onHandleKey(SkKey key) {
static const char gGestureClickType[] = "GestureClickType";
bool SampleWindow::onDispatchClick(int x, int y, Click::State state) {
if (Click::kMoved_State == state) {
updatePointer(x, y);
}
int w = SkScalarRound(this->width());
int h = SkScalarRound(this->height());

View File

@ -125,6 +125,7 @@ SkOSWindow::SkOSWindow(void* hWnd) : fHWND(hWnd), fAGLCtx(NULL)
{ kEventClassKeyboard, kEventRawKeyUp },
{ kEventClassMouse, kEventMouseDown },
{ kEventClassMouse, kEventMouseDragged },
{ kEventClassMouse, kEventMouseMoved },
{ kEventClassMouse, kEventMouseUp },
{ kEventClassTextInput, kEventTextInputUnicodeForKeyEvent },
{ kEventClassWindow, kEventWindowBoundsChanged },
@ -334,6 +335,8 @@ pascal OSStatus SkOSWindow::EventHandler( EventHandlerCallRef inHandler, EventRe
result = noErr;
}
break;
case kEventMouseMoved:
// fall through
case kEventMouseDragged:
(void)win->handleClick(pt.h, pt.v, Click::kMoved_State);
// result = noErr;

View File

@ -9,20 +9,14 @@
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkEvent.h"
#include "SkTypeface.h"
SkOSWindow::SkOSWindow(void* unused)
{
fUnixWindow.fDisplay = NULL;
fMouseX = fMouseY = 0;
fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
fShowZoomer = false;
fScale = 4;
}
SkOSWindow::~SkOSWindow()
{
fTypeface->unref();
}
void SkOSWindow::setUnixWindow(Display* dsp, Window win, size_t screenNumber, GC gc)
@ -48,29 +42,6 @@ void SkOSWindow::presentGL()
}
bool SkOSWindow::zoomIn()
{
// Arbitrarily decided
if (fScale == 25) return false;
fScale++;
inval(NULL);
return true;
}
bool SkOSWindow::zoomOut()
{
if (fScale == 1) return false;
fScale--;
inval(NULL);
return true;
}
void SkOSWindow::toggleZoomer()
{
fShowZoomer = !fShowZoomer;
inval(NULL);
}
void SkOSWindow::onSetTitle(const char title[])
{
if (!fUnixWindow.fDisplay) return;
@ -117,33 +88,6 @@ static bool convertBitmapToXImage(XImage& image, const SkBitmap& bitmap)
return XInitImage(&image);
}
void SkOSWindow::updatePointer(int x, int y)
{
fMouseX = x;
fMouseY = y;
inval(NULL);
}
static void drawText(SkCanvas& canvas, SkString string, SkScalar left, SkScalar top, SkPaint& paint)
{
SkColor desiredColor = paint.getColor();
paint.setColor(SK_ColorWHITE);
const char* c_str = string.c_str();
size_t size = string.size();
SkRect bounds;
paint.measureText(c_str, size, &bounds);
bounds.offset(left, top);
SkScalar inset = SkIntToScalar(-2);
bounds.inset(inset, inset);
canvas.drawRect(bounds, paint);
if (desiredColor != SK_ColorBLACK) {
paint.setColor(SK_ColorBLACK);
canvas.drawText(c_str, size, left + SK_Scalar1, top + SK_Scalar1, paint);
}
paint.setColor(desiredColor);
canvas.drawText(c_str, size, left, top, paint);
}
void SkOSWindow::doPaint() {
if (!fUnixWindow.fDisplay) return;
// Draw the bitmap to the screen.
@ -151,94 +95,10 @@ void SkOSWindow::doPaint() {
int width = bitmap.width();
int height = bitmap.height();
if (!fShowZoomer) {
XImage image;
if (!convertBitmapToXImage(image, bitmap)) return;
XImage image;
if (!convertBitmapToXImage(image, bitmap)) return;
XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, 0, 0, width, height);
} else {
// Ensure the mouse position is on screen.
if (fMouseX >= width) fMouseX = width - 1;
else if (fMouseX < 0) fMouseX = 0;
if (fMouseY >= height) fMouseY = height - 1;
else if (fMouseY < 0) fMouseY = 0;
// zoomedBitmap will show the original bitmap, plus a zoomed in view (fat bits).
SkBitmap zoomedBitmap;
bitmap.copyTo(&zoomedBitmap, bitmap.getConfig());
SkCanvas canvas(zoomedBitmap);
// Find the size of the zoomed in view, forced to be odd, so the examined pixel is in the middle.
int zoomedWidth = (width >> 2) | 1;
int zoomedHeight = (height >> 2) | 1;
SkIRect src;
src.set(0, 0, zoomedWidth / fScale, zoomedHeight / fScale);
src.offset(fMouseX - (src.width()>>1), fMouseY - (src.height()>>1));
SkRect dest;
dest.set(0, 0, SkIntToScalar(zoomedWidth), SkIntToScalar(zoomedHeight));
dest.offset(SkIntToScalar(width - zoomedWidth), SkIntToScalar(height - zoomedHeight));
SkPaint paint;
// Clear the background behind our zoomed in view
paint.setColor(SK_ColorWHITE);
canvas.drawRect(dest, paint);
canvas.drawBitmapRect(bitmap, &src, dest);
paint.setColor(SK_ColorBLACK);
paint.setStyle(SkPaint::kStroke_Style);
// Draw a border around the pixel in the middle
SkRect originalPixel;
originalPixel.set(SkIntToScalar(fMouseX), SkIntToScalar(fMouseY), SkIntToScalar(fMouseX + 1), SkIntToScalar(fMouseY + 1));
SkMatrix matrix;
SkRect scalarSrc;
scalarSrc.set(src);
SkColor color = bitmap.getColor(fMouseX, fMouseY);
if (matrix.setRectToRect(scalarSrc, dest, SkMatrix::kFill_ScaleToFit)) {
SkRect pixel;
matrix.mapRect(&pixel, originalPixel);
// TODO Perhaps measure the values and make the outline white if it's "dark"
if (color == SK_ColorBLACK) {
paint.setColor(SK_ColorWHITE);
}
canvas.drawRect(pixel, paint);
}
paint.setColor(SK_ColorBLACK);
// Draw a border around the destination rectangle
canvas.drawRect(dest, paint);
paint.setStyle(SkPaint::kStrokeAndFill_Style);
// Identify the pixel and its color on screen
paint.setTypeface(fTypeface);
paint.setAntiAlias(true);
SkScalar lineHeight = paint.getFontMetrics(NULL);
SkString string;
string.appendf("(%i, %i)", fMouseX, fMouseY);
SkScalar left = dest.fLeft + SkIntToScalar(3);
SkScalar i = SK_Scalar1;
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Alpha
i += SK_Scalar1;
string.reset();
string.appendf("A: %X", SkColorGetA(color));
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Red
i += SK_Scalar1;
string.reset();
string.appendf("R: %X", SkColorGetR(color));
paint.setColor(SK_ColorRED);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Green
i += SK_Scalar1;
string.reset();
string.appendf("G: %X", SkColorGetG(color));
paint.setColor(SK_ColorGREEN);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Blue
i += SK_Scalar1;
string.reset();
string.appendf("B: %X", SkColorGetB(color));
paint.setColor(SK_ColorBLUE);
drawText(canvas, string, left, SkScalarMulAdd(lineHeight, i, dest.fTop), paint);
// Finally, put our bitmap on the screen
XImage zoomedImage;
convertBitmapToXImage(zoomedImage, zoomedBitmap);
XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &zoomedImage, 0, 0, 0, 0, width, height);
}
XPutImage(fUnixWindow.fDisplay, fUnixWindow.fWin, fUnixWindow.fGc, &image, 0, 0, 0, 0, width, height);
}
bool SkOSWindow::onHandleChar(SkUnichar)

View File

@ -96,10 +96,7 @@ int main(){
window->handleClick(evt.xbutton.x, evt.xbutton.y, SkView::Click::kUp_State);
break;
case MotionNotify:
// FIXME: 272 corresponds to the left mouse button, but should be a constant.
if (evt.xmotion.state == 272)
window->handleClick(evt.xmotion.x, evt.xmotion.y, SkView::Click::kMoved_State);
window->updatePointer(evt.xmotion.x, evt.xmotion.y);
window->handleClick(evt.xmotion.x, evt.xmotion.y, SkView::Click::kMoved_State);
break;
case KeyPress:
{