Chromium Code Reviews| Index: samplecode/SampleBevel.cpp |
| diff --git a/samplecode/SampleBevel.cpp b/samplecode/SampleBevel.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6a1839c5ad01027a809582c1dfaf67f5306760dc |
| --- /dev/null |
| +++ b/samplecode/SampleBevel.cpp |
| @@ -0,0 +1,289 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "SampleCode.h" |
| +#include "SkLightingShader.h" |
| +#include "SkNormalSource.h" |
|
robertphillips
2016/08/16 17:02:42
Do we need the next three includes ?
dvonbeck
2016/08/16 19:08:50
I do need that last one, the other 2 are from a pr
|
| +#include "SkPictureRecorder.h" |
| +#include "SkSurface.h" |
| +#include "sk_tool_utils.h" |
| + |
| + |
| +class BevelView : public SampleView { |
| +public: |
| + BevelView() |
|
robertphillips
2016/08/16 17:02:42
I don't know if you're getting any mileage out of
dvonbeck
2016/08/16 19:08:50
I also use them to keep track of the state of ligh
|
| + : fRedLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.6f, 0.45f, 0.3f), |
| + SkVector3::Make(0.0f, -5.0f, 1.0f))) |
| + , fBlueLight(SkLights::Light::MakeDirectional(SkColor3f::Make(0.3f, 0.45f, 0.6f), |
| + SkVector3::Make(0.0f, 5.0f, 1.0f))) { |
| + this->setBGColor(0xFF666868); // Slightly colorized gray for contrast |
| + |
| + // Lights |
| + SkLights::Builder builder; |
| + builder.add(fRedLight); |
| + builder.add(fBlueLight); |
| + builder.add(SkLights::Light::MakeAmbient(SkColor3f::Make(0.4f, 0.4f, 0.4f))); |
| + fLights = builder.finish(); |
| + |
| + fRect = SkRect::MakeIWH(kRectSize, kRectSize); |
| + |
| + // Controls |
| + |
| + int currY = kSliderHeight; |
| + |
|
robertphillips
2016/08/16 17:02:42
it is odd that you touch fCtrlRangeRects twice wit
dvonbeck
2016/08/16 19:08:50
True! I changed it
|
| + fCtrlRangeRects[0] = SkRect::MakeIWH(kCtrlRange + kSliderWidth, kSliderHeight); |
| + fWidthCtrlRect = SkRect::MakeIWH(kSliderWidth, kSliderHeight); |
| + fCtrlRangeRects[0].offset(0, SkIntToScalar(currY)); |
| + fWidthCtrlRect.offset(0.3*kCtrlRange, SkIntToScalar(currY)); |
| + fBevelWidth = 0.3*kBevelWidthMax; |
| + currY += 2 * kSliderHeight; |
| + |
| + fCtrlRangeRects[1] = SkRect::MakeIWH(kCtrlRange + kSliderWidth, kSliderHeight); |
| + fHeightCtrlRect = SkRect::MakeIWH(kSliderWidth, kSliderHeight); |
| + fCtrlRangeRects[1].offset(0, SkIntToScalar(currY)); |
| + fHeightCtrlRect.offset(0.3*kCtrlRange, SkIntToScalar(currY)); |
| + fBevelHeight = 0.3*kBevelHeightMax; |
| + currY += 2 * kSliderHeight; |
| + |
| + fCtrlRangeRects[2] = SkRect::MakeIWH(kCtrlRange + kSliderWidth, kSliderHeight); |
| + fTypeCtrlRect = SkRect::MakeIWH(kSliderWidth, kSliderHeight); |
| + fCtrlRangeRects[2].offset(0, SkIntToScalar(currY)); |
| + fTypeCtrlRect.offset((1.0f/6.0f)*kCtrlRange, SkIntToScalar(currY)); |
| + fBevelType = (SkNormalSource::BevelType) 0; |
| + currY += 2 * kSliderHeight; |
| + |
| + fSelectedRect = nullptr; |
| + } |
| + |
| +protected: |
| + bool onQuery(SkEvent *evt) override { |
| + if (SampleCode::TitleQ(*evt)) { |
| + SampleCode::TitleR(evt, "bevel"); |
| + return true; |
| + } |
| + |
| + return this->INHERITED::onQuery(evt); |
| + } |
| + |
| + enum Shape { |
| + kCircle_Shape, |
| + kRect_Shape, |
| + kLast_Shape = kRect_Shape |
| + }; |
| + void drawShape(enum Shape shape, SkCanvas* canvas) { |
| + canvas->save(); |
| + |
| + SkPaint paint; |
| + |
| + sk_sp<SkNormalSource> normalSource = SkNormalSource::MakeBevel(fBevelType, fBevelWidth, |
| + fBevelHeight); |
| + |
| + paint.setShader(SkLightingShader::Make(nullptr, std::move(normalSource), fLights)); |
| + paint.setAntiAlias(true); |
| + paint.setColor(0xFFDDDDDD); |
|
robertphillips
2016/08/16 17:02:42
missing ' ' here ?
dvonbeck
2016/08/16 19:08:50
Done.
|
| + switch(shape) { |
| + case kCircle_Shape: |
| + canvas->drawCircle(fRect.centerX(), fRect.centerY(), fRect.width()/2.0f, paint); |
| + break; |
| + case kRect_Shape: |
| + canvas->drawRect(fRect, paint); |
| + break; |
| + default: |
| + SkDEBUGFAIL("Invalid shape enum for drawShape"); |
| + } |
| + |
| + canvas->restore(); |
| + } |
| + |
| + void onDrawContent(SkCanvas *canvas) override { |
| + // Draw controls |
| + SkPaint ctrlRectPaint; |
| + ctrlRectPaint.setColor(0xFFF3F3F3); |
| + canvas->drawRect(fWidthCtrlRect, ctrlRectPaint); |
| + canvas->drawRect(fHeightCtrlRect, ctrlRectPaint); |
| + canvas->drawRect(fTypeCtrlRect, ctrlRectPaint); |
| + |
| + SkPaint ctrlRectRangePaint; |
| + ctrlRectRangePaint.setColor(0xFFFFFFFF); |
| + ctrlRectRangePaint.setStyle(SkPaint::kStroke_Style); |
| + ctrlRectRangePaint.setStrokeWidth(2.0f); |
| + |
|
robertphillips
2016/08/16 17:02:42
use kNumControls ?
dvonbeck
2016/08/16 19:08:50
Done.
|
| + #define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0])) |
| + for (size_t i = 0; i < ARRAY_LEN(fCtrlRangeRects); i++) { |
| + canvas->drawRect(fCtrlRangeRects[i], ctrlRectRangePaint); |
| + } |
| + |
| + // Draw labels |
| + constexpr SkScalar kTextSize = 12.0f; |
| + SkString widthLabel, heightLabel, typeLabel; |
| + SkPaint labelPaint; |
| + labelPaint.setTypeface(sk_tool_utils::create_portable_typeface("sans-serif", |
| + SkFontStyle())); |
| + labelPaint.setAntiAlias(true); |
| + labelPaint.setColor(0xFFFFFFFF); |
| + labelPaint.setTextSize(kTextSize); |
| + |
| + widthLabel.appendf("BevelWidth: %f", fBevelWidth); |
| + heightLabel.appendf("BevelHeight: %f", fBevelHeight); |
| + typeLabel.append("BevelType: "); |
| + |
| + switch (fBevelType) { |
| + case SkNormalSource::BevelType::kLinear: |
| + typeLabel.append("Linear"); |
| + break; |
| + case SkNormalSource::BevelType::kRoundedIn: |
| + typeLabel.append("RoundedIn"); |
| + break; |
| + case SkNormalSource::BevelType::kRoundedOut: |
| + typeLabel.append("RoundedOut"); |
| + break; |
| + } |
| + |
| + canvas->drawText(widthLabel.c_str(), widthLabel.size(), 0, |
| + fWidthCtrlRect.fTop - kTextSize/2.0f, labelPaint); |
| + canvas->drawText(heightLabel.c_str(), heightLabel.size(), 0, |
| + fHeightCtrlRect.fTop - kTextSize/2.0f, labelPaint); |
| + canvas->drawText(typeLabel.c_str(), typeLabel.size(), 0, |
| + fTypeCtrlRect.fTop - kTextSize/2.0f, labelPaint); |
| + |
| + // Draw shapes |
| + SkScalar xPos = kCtrlRange + 25; |
| + SkScalar yPos = fRect.height(); |
|
robertphillips
2016/08/16 17:02:42
for (auto shape : { kCircle_Shape, kRect_Shape })
dvonbeck
2016/08/16 19:08:50
Done.
|
| + for (int shapeInt = 0; shapeInt <= kLast_Shape; shapeInt++) { |
| + Shape shape = (Shape)shapeInt; |
| + |
| + canvas->save(); |
| + canvas->translate(xPos, yPos); |
| + this->drawShape(shape, canvas); |
| + canvas->restore(); |
| + |
| + xPos += 1.2f * fRect.width(); |
| + } |
| + } |
| + |
| + SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, unsigned modi) override { |
| + return new SkView::Click(this); |
| + } |
| + |
| + bool onClick(Click *click) override { |
| + SkScalar x = click->fCurr.fX; |
| + SkScalar y = click->fCurr.fY; |
| + |
| + SkScalar dx = x - click->fPrev.fX; |
| + SkScalar dy = y - click->fPrev.fY; |
| + |
| + // Control deselection |
| + if (Click::State::kUp_State == click->fState) { |
| + fSelectedRect = nullptr; |
| + return true; |
| + } |
| + |
| + // Control selection |
| + if (nullptr == fSelectedRect && Click::State::kDown_State == click->fState) { |
| + if (fWidthCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) { |
| + fSelectedRect = &fWidthCtrlRect; |
| + } else if (fHeightCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) { |
| + fSelectedRect = &fHeightCtrlRect; |
| + } else if (fTypeCtrlRect.contains(SkRect::MakeXYWH(x, y, 1, 1))) { |
| + fSelectedRect = &fTypeCtrlRect; |
| + } |
| + } |
| + |
| + // Control modification |
| + if (nullptr != fSelectedRect) { |
| + fSelectedRect->offsetTo(SkScalarPin(x, 0.0f, kCtrlRange), fSelectedRect->fTop); |
| + |
| + fBevelHeight = (fHeightCtrlRect.fLeft / kCtrlRange) * kBevelHeightMax; |
| + fBevelWidth = (fWidthCtrlRect.fLeft / kCtrlRange) * kBevelWidthMax; |
| + fBevelType = (SkNormalSource::BevelType)SkTMin( |
| + SkScalarFloorToInt(3.0f * fTypeCtrlRect.fLeft / kCtrlRange), |
| + 2); |
| + |
| + // Snap type controls to 3 positions |
| + fTypeCtrlRect.offsetTo(kCtrlRange * ( ((int)fBevelType)/3.0f + 1.0f/6.0f ), |
| + fTypeCtrlRect.fTop); |
| + |
| + // Ensuring width is non-zero |
| + fBevelWidth = SkMaxScalar(1.0f, fBevelWidth); |
| + |
| + this->inval(nullptr); |
| + return true; |
| + } |
| + |
| + // Moving light |
| + if (nullptr == fSelectedRect) { |
| + if (dx != 0 || dy != 0) { |
| + float recipX = 1.0f / kAppWidth; |
| + float recipY = 1.0f / kAppHeight; |
| + |
| + if (0 == click->fModifierKeys) { // No modifier |
| + fBlueLight = SkLights::Light::MakeDirectional(fBlueLight.color(), |
| + SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0f, |
| + (kAppHeight/2.0f - y) * recipY * -3.0f, |
| + 1.0f)); |
| + } else if (1 == click->fModifierKeys) { // Shift key |
| + fRedLight = SkLights::Light::MakeDirectional(fRedLight.color(), |
| + SkVector3::Make((kAppWidth/2.0f - x) * recipX * -3.0f, |
| + (kAppHeight/2.0f - y) * recipY * -3.0f, |
| + 1.0f)); |
| + } |
| + |
| + SkLights::Builder builder; |
| + builder.add(fRedLight); |
| + builder.add(fBlueLight); |
| + builder.add(SkLights::Light::MakeAmbient( |
| + SkColor3f::Make(0.4f, 0.4f, 0.4f))); |
| + fLights = builder.finish(); |
| + |
| + this->inval(nullptr); |
| + } |
| + return true; |
| + } |
| + |
| + return true; |
| + } |
| + |
| +private: |
| + static constexpr int kNumTestRects = 3; |
| + |
| + static const int kAppWidth = 400; |
| + static const int kAppHeight = 400; |
| + static const int kRectSize = 120; |
| + |
| + static const int kCtrlRange = 150; |
| + static const int kBevelWidthMax = 50; |
| + static const int kBevelHeightMax = 50; |
| + |
| + static const int kSliderHeight = 20; |
| + static const int kSliderWidth = 10; |
| + |
|
robertphillips
2016/08/16 17:02:42
What's this for ?
dvonbeck
2016/08/16 19:08:50
Oops, leftover from old code. Removed.
|
| + sk_sp<SkPicture> fPicture; |
| + |
|
robertphillips
2016/08/16 17:02:42
more descriptive name for 'fRect' ?
can this be c
dvonbeck
2016/08/16 19:08:50
Done.
|
| + SkRect fRect; |
| + sk_sp<SkLights> fLights; |
| + |
| + SkRect* fSelectedRect; |
| + SkRect fWidthCtrlRect; |
| + SkRect fHeightCtrlRect; |
| + SkRect fTypeCtrlRect; |
|
robertphillips
2016/08/16 17:02:42
Add kNumControls ?
dvonbeck
2016/08/16 19:08:50
Done.
|
| + SkRect fCtrlRangeRects[3]; |
| + |
| + SkScalar fBevelWidth; |
| + SkScalar fBevelHeight; |
| + SkNormalSource::BevelType fBevelType; |
| + |
| + SkLights::Light fRedLight; |
| + SkLights::Light fBlueLight; |
| + |
| + typedef SampleView INHERITED; |
| +}; |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +static SkView* MyFactory() { return new BevelView; } |
| +static SkViewRegister reg(MyFactory); |
| + |