| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | 5 #ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ |
| 6 #define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | 6 #define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ |
| 7 | 7 |
| 8 #include "embedders/openglui/common/graphics_handler.h" | 8 #include "embedders/openglui/common/graphics_handler.h" |
| 9 #include "embedders/openglui/common/log.h" | 9 #include "embedders/openglui/common/log.h" |
| 10 #include "embedders/openglui/common/opengl.h" | 10 #include "embedders/openglui/common/opengl.h" |
| 11 #include "embedders/openglui/common/support.h" | 11 #include "embedders/openglui/common/support.h" |
| 12 | 12 |
| 13 typedef struct CanvasState { | 13 typedef struct CanvasState { |
| 14 SkPaint paint_; | 14 SkPaint paint_; |
| 15 float globalAlpha_; | 15 float globalAlpha_; |
| 16 float miterLimit_; | 16 float miterLimit_; |
| 17 ColorRGBA fillColor_; | 17 ColorRGBA fillColor_; |
| 18 ColorRGBA strokeColor_; | 18 ColorRGBA strokeColor_; |
| 19 ColorRGBA shadowColor_; | 19 ColorRGBA shadowColor_; |
| 20 float shadowBlur_; | 20 float shadowBlur_; |
| 21 float shadowOffsetX_; | 21 float shadowOffsetX_; |
| 22 float shadowOffsetY_; | 22 float shadowOffsetY_; |
| 23 float* lineDash_; | 23 float* lineDash_; |
| 24 int lineDashCount_; | 24 int lineDashCount_; |
| 25 int lineDashOffset_; | 25 int lineDashOffset_; |
| 26 SkShader* fillShader_; |
| 27 SkShader* strokeShader_; |
| 26 | 28 |
| 27 SkPath* path_; | 29 SkPath* path_; |
| 28 SkCanvas* canvas_; | 30 SkCanvas* canvas_; |
| 29 CanvasState* next_; // For stack. | 31 CanvasState* next_; // For stack. |
| 30 | 32 |
| 31 CanvasState(SkCanvas* canvas) | 33 CanvasState(SkCanvas* canvas) |
| 32 : paint_(), | 34 : paint_(), |
| 33 globalAlpha_(1.0), | 35 globalAlpha_(1.0), |
| 34 miterLimit_(10), | 36 miterLimit_(10), |
| 35 fillColor_(ColorRGBA(255, 0, 0, 255)), | 37 fillColor_(ColorRGBA(255, 0, 0, 255)), |
| 36 strokeColor_(fillColor_), | 38 strokeColor_(fillColor_), |
| 37 shadowColor_(ColorRGBA(0, 0, 0, 0)), | 39 shadowColor_(ColorRGBA(0, 0, 0, 0)), |
| 38 shadowBlur_(0.0), | 40 shadowBlur_(0.0), |
| 39 shadowOffsetX_(0.0), | 41 shadowOffsetX_(0.0), |
| 40 shadowOffsetY_(0.0), | 42 shadowOffsetY_(0.0), |
| 41 lineDash_(NULL), | 43 lineDash_(NULL), |
| 42 lineDashCount_(0), | 44 lineDashCount_(0), |
| 43 lineDashOffset_(0), | 45 lineDashOffset_(0), |
| 46 fillShader_(NULL), |
| 47 strokeShader_(NULL), |
| 44 path_(new SkPath()), | 48 path_(new SkPath()), |
| 45 canvas_(canvas), | 49 canvas_(canvas), |
| 46 next_(NULL) { | 50 next_(NULL) { |
| 47 paint_.setStrokeCap(SkPaint::kButt_Cap); | 51 paint_.setStrokeCap(SkPaint::kButt_Cap); |
| 48 paint_.setStrokeJoin(SkPaint::kMiter_Join); | 52 paint_.setStrokeJoin(SkPaint::kMiter_Join); |
| 49 paint_.setStrokeWidth(1); | 53 paint_.setStrokeWidth(1); |
| 50 paint_.setTextAlign(SkPaint::kLeft_Align); | 54 paint_.setTextAlign(SkPaint::kLeft_Align); |
| 51 paint_.setAntiAlias(true); | 55 paint_.setAntiAlias(true); |
| 52 paint_.setStyle(SkPaint::kStroke_Style); | 56 paint_.setStyle(SkPaint::kStroke_Style); |
| 53 setFont("Helvetica", 10); | 57 setFont("Helvetica", 10); |
| 54 } | 58 } |
| 55 | 59 |
| 56 CanvasState(const CanvasState& state) | 60 CanvasState(const CanvasState& state) |
| 57 : paint_(state.paint_), | 61 : paint_(state.paint_), |
| 58 globalAlpha_(state.globalAlpha_), | 62 globalAlpha_(state.globalAlpha_), |
| 59 miterLimit_(state.miterLimit_), | 63 miterLimit_(state.miterLimit_), |
| 60 fillColor_(state.fillColor_), | 64 fillColor_(state.fillColor_), |
| 61 strokeColor_(state.strokeColor_), | 65 strokeColor_(state.strokeColor_), |
| 62 shadowColor_(state.shadowColor_), | 66 shadowColor_(state.shadowColor_), |
| 63 shadowBlur_(state.shadowBlur_), | 67 shadowBlur_(state.shadowBlur_), |
| 64 shadowOffsetX_(state.shadowOffsetX_), | 68 shadowOffsetX_(state.shadowOffsetX_), |
| 65 shadowOffsetY_(state.shadowOffsetY_), | 69 shadowOffsetY_(state.shadowOffsetY_), |
| 66 lineDash_(NULL), | 70 lineDash_(NULL), |
| 67 lineDashCount_(state.lineDashCount_), | 71 lineDashCount_(state.lineDashCount_), |
| 68 lineDashOffset_(state.lineDashOffset_), | 72 lineDashOffset_(state.lineDashOffset_), |
| 73 fillShader_(state.fillShader_), |
| 74 strokeShader_(state.strokeShader_), |
| 69 path_(new SkPath()), | 75 path_(new SkPath()), |
| 70 canvas_(state.canvas_), | 76 canvas_(state.canvas_), |
| 71 next_(NULL) { | 77 next_(NULL) { |
| 72 setLineDash(state.lineDash_, lineDashCount_); | 78 setLineDash(state.lineDash_, lineDashCount_); |
| 79 if (fillShader_ != NULL) fillShader_->ref(); |
| 80 if (strokeShader_ != NULL) strokeShader_->ref(); |
| 73 } | 81 } |
| 74 | 82 |
| 75 ~CanvasState() { | 83 ~CanvasState() { |
| 84 if (fillShader_ != NULL) fillShader_->unref(); |
| 85 if (strokeShader_ != NULL) strokeShader_->unref(); |
| 76 delete path_; | 86 delete path_; |
| 77 delete[] lineDash_; | 87 delete[] lineDash_; |
| 78 } | 88 } |
| 79 | 89 |
| 80 static ColorRGBA GetColor(const char* color); | 90 static ColorRGBA GetColor(const char* color); |
| 81 | 91 |
| 82 inline CanvasState* Save() { | 92 inline CanvasState* Save() { |
| 83 canvas_->save(); // For clip and transform. | 93 canvas_->save(); // For clip and transform. |
| 84 CanvasState *new_state = new CanvasState(*this); | 94 CanvasState *new_state = new CanvasState(*this); |
| 85 new_state->next_ = this; | 95 new_state->next_ = this; |
| 86 // If the old state has a non-empty path, use its | 96 // If the old state has a non-empty path, use its |
| 87 // last point as the new states first point. | 97 // last point as the new states first point. |
| 88 int np = path_->countPoints(); | 98 int np = path_->countPoints(); |
| 89 if (np > 0) { | 99 if (np > 0) { |
| 90 new_state->path_->moveTo(path_->getPoint(np-1)); | 100 new_state->path_->moveTo(path_->getPoint(np-1)); |
| 91 } | 101 } |
| 92 return new_state; | 102 return new_state; |
| 93 } | 103 } |
| 94 | 104 |
| 95 inline CanvasState* Restore() { | 105 CanvasState* Restore(); |
| 96 if (next_ != NULL) { | |
| 97 // If the state we are popping has a non-empty path, | |
| 98 // apply the state's transform to the path, then | |
| 99 // add the path to the previous state's path. | |
| 100 if (path_->countPoints() > 0) { | |
| 101 path_->transform(canvas_->getTotalMatrix()); | |
| 102 next_->path_->addPath(*path_); | |
| 103 } | |
| 104 canvas_->restore(); | |
| 105 return next_; | |
| 106 } | |
| 107 canvas_->restore(); | |
| 108 return next_; // TODO(gram): Should we assert/throw? | |
| 109 } | |
| 110 | 106 |
| 111 inline float Radians2Degrees(float angle) { | 107 inline float Radians2Degrees(float angle) { |
| 112 return 180.0 * angle / M_PI; | 108 return 180.0 * angle / M_PI; |
| 113 } | 109 } |
| 114 | 110 |
| 115 inline void setGlobalAlpha(float alpha) { | 111 inline void setGlobalAlpha(float alpha) { |
| 116 globalAlpha_ = alpha; | 112 globalAlpha_ = alpha; |
| 117 } | 113 } |
| 118 | 114 |
| 119 inline void setFillColor(const char* color) { | 115 inline void setFillColor(const char* color) { |
| 116 if (fillShader_ != NULL) { |
| 117 fillShader_->unref(); |
| 118 fillShader_ = NULL; |
| 119 } |
| 120 fillColor_ = GetColor(color); | 120 fillColor_ = GetColor(color); |
| 121 } | 121 } |
| 122 | 122 |
| 123 inline void setStrokeColor(const char* color) { | 123 inline void setStrokeColor(const char* color) { |
| 124 if (strokeShader_ != NULL) { |
| 125 strokeShader_->unref(); |
| 126 strokeShader_ = NULL; |
| 127 } |
| 124 strokeColor_ = GetColor(color); | 128 strokeColor_ = GetColor(color); |
| 125 } | 129 } |
| 126 | 130 |
| 127 const char* setFont(const char*name, float size = -1); | 131 const char* setFont(const char*name, float size = -1); |
| 128 void setLineCap(const char* lc); | 132 void setLineCap(const char* lc); |
| 129 void setLineJoin(const char* lj); | 133 void setLineJoin(const char* lj); |
| 130 | 134 |
| 131 inline void setMiterLimit(float limit) { | 135 inline void setMiterLimit(float limit) { |
| 132 miterLimit_ = limit; | 136 miterLimit_ = limit; |
| 133 } | 137 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 149 inline float MeasureText(const char *text) { | 153 inline float MeasureText(const char *text) { |
| 150 // TODO(gram): make sure this is not supposed to be affected | 154 // TODO(gram): make sure this is not supposed to be affected |
| 151 // by the canvas transform. | 155 // by the canvas transform. |
| 152 return paint_.measureText(text, strlen(text)); | 156 return paint_.measureText(text, strlen(text)); |
| 153 } | 157 } |
| 154 | 158 |
| 155 inline void setLineWidth(float w) { | 159 inline void setLineWidth(float w) { |
| 156 paint_.setStrokeWidth(w); | 160 paint_.setStrokeWidth(w); |
| 157 } | 161 } |
| 158 | 162 |
| 159 inline void setMode(SkPaint::Style style, ColorRGBA color) { | 163 void setMode(SkPaint::Style style, ColorRGBA color, SkShader* shader); |
| 160 paint_.setStyle(style); | |
| 161 paint_.setColor(color.v); | |
| 162 uint8_t alpha = static_cast<uint8_t>( | |
| 163 globalAlpha_ * static_cast<float>(color.alpha())); | |
| 164 paint_.setAlpha(alpha); | |
| 165 bool drawShadow = (shadowOffsetX_ != 0 || | |
| 166 shadowOffsetY_ != 0 || | |
| 167 shadowBlur_ != 0) && | |
| 168 shadowColor_.alpha() > 0; | |
| 169 if (drawShadow) { | |
| 170 // TODO(gram): should we mult shadowColor by globalAlpha? | |
| 171 paint_.setLooper(new SkBlurDrawLooper(SkFloatToScalar(shadowBlur_), | |
| 172 SkFloatToScalar(shadowOffsetX_), | |
| 173 SkFloatToScalar(shadowOffsetY_), | |
| 174 shadowColor_.v))->unref(); | |
| 175 } else { | |
| 176 paint_.setLooper(NULL); | |
| 177 } | |
| 178 } | |
| 179 | 164 |
| 180 inline void setLineDashEffect() { | 165 inline void setLineDashEffect() { |
| 181 if (lineDashCount_ > 0) { | 166 if (lineDashCount_ > 0) { |
| 182 SkDashPathEffect* dashPathEffect = | 167 SkDashPathEffect* dashPathEffect = |
| 183 new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_); | 168 new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_); |
| 184 paint_.setPathEffect(dashPathEffect)->unref(); | 169 paint_.setPathEffect(dashPathEffect)->unref(); |
| 185 } else { | 170 } else { |
| 186 paint_.setPathEffect(NULL); | 171 paint_.setPathEffect(NULL); |
| 187 } | 172 } |
| 188 } | 173 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 218 | 203 |
| 219 inline void setShadowOffsetX(float ox) { | 204 inline void setShadowOffsetX(float ox) { |
| 220 shadowOffsetX_ = ox; | 205 shadowOffsetX_ = ox; |
| 221 } | 206 } |
| 222 | 207 |
| 223 inline void setShadowOffsetY(float oy) { | 208 inline void setShadowOffsetY(float oy) { |
| 224 shadowOffsetY_ = oy; | 209 shadowOffsetY_ = oy; |
| 225 } | 210 } |
| 226 | 211 |
| 227 inline void setFillMode() { | 212 inline void setFillMode() { |
| 228 setMode(SkPaint::kFill_Style, fillColor_); | 213 setMode(SkPaint::kFill_Style, fillColor_, fillShader_); |
| 229 } | 214 } |
| 230 | 215 |
| 231 inline void setStrokeMode() { | 216 inline void setStrokeMode() { |
| 232 setMode(SkPaint::kStroke_Style, strokeColor_); | 217 setMode(SkPaint::kStroke_Style, strokeColor_, strokeShader_); |
| 233 } | 218 } |
| 234 | 219 |
| 235 inline void FillRect(float left, float top, | 220 inline void FillRect(float left, float top, |
| 236 float width, float height) { | 221 float width, float height) { |
| 237 // Does not affect the path. | 222 // Does not affect the path. |
| 238 setFillMode(); | 223 setFillMode(); |
| 239 canvas_->drawRectCoords(left, top, left + width, top + height, paint_); | 224 canvas_->drawRectCoords(left, top, left + width, top + height, paint_); |
| 240 } | 225 } |
| 241 | 226 |
| 242 inline void StrokeRect(float left, float top, | 227 inline void StrokeRect(float left, float top, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 | 281 |
| 297 void setGlobalCompositeOperation(const char* op); | 282 void setGlobalCompositeOperation(const char* op); |
| 298 | 283 |
| 299 void DrawImage(const SkBitmap& bm, | 284 void DrawImage(const SkBitmap& bm, |
| 300 int sx, int sy, int sw, int sh, | 285 int sx, int sy, int sw, int sh, |
| 301 int dx, int dy, int dw, int dh); | 286 int dx, int dy, int dw, int dh); |
| 302 | 287 |
| 303 inline void Clip() { | 288 inline void Clip() { |
| 304 canvas_->clipPath(*path_); | 289 canvas_->clipPath(*path_); |
| 305 } | 290 } |
| 291 |
| 292 void SetFillGradient(bool is_radial, double x0, double y0, double r0, |
| 293 double x1, double y1, double r1, |
| 294 int stops, float* positions, char** colors); |
| 295 |
| 296 void SetStrokeGradient(bool is_radial, double x0, double y0, double r0, |
| 297 double x1, double y1, double r1, |
| 298 int stops, float* positions, char** colors); |
| 299 |
| 300 private: |
| 301 SkShader* CreateRadialGradient( |
| 302 double x0, double y0, double r0, |
| 303 double x1, double y1, double r1, |
| 304 int stops, float* positions, char** colors); |
| 305 |
| 306 SkShader* CreateLinearGradient( |
| 307 double x0, double y0, double x1, double y1, |
| 308 int stops, float* positions, char** colors); |
| 306 } CanvasState; | 309 } CanvasState; |
| 307 | 310 |
| 308 #endif // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | 311 #endif // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ |
| 309 | 312 |
| OLD | NEW |