| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #ifndef EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | |
| 6 #define EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | |
| 7 | |
| 8 #include "embedders/openglui/common/graphics_handler.h" | |
| 9 #include "embedders/openglui/common/log.h" | |
| 10 #include "embedders/openglui/common/opengl.h" | |
| 11 #include "embedders/openglui/common/support.h" | |
| 12 | |
| 13 typedef struct CanvasState { | |
| 14 SkPaint paint_; | |
| 15 float globalAlpha_; | |
| 16 float miterLimit_; | |
| 17 ColorRGBA fillColor_; | |
| 18 ColorRGBA strokeColor_; | |
| 19 ColorRGBA shadowColor_; | |
| 20 float shadowBlur_; | |
| 21 float shadowOffsetX_; | |
| 22 float shadowOffsetY_; | |
| 23 float* lineDash_; | |
| 24 int lineDashCount_; | |
| 25 int lineDashOffset_; | |
| 26 SkShader* fillShader_; | |
| 27 SkShader* strokeShader_; | |
| 28 | |
| 29 SkPath* path_; | |
| 30 SkCanvas* canvas_; | |
| 31 CanvasState* next_; // For stack. | |
| 32 | |
| 33 CanvasState(SkCanvas* canvas) | |
| 34 : paint_(), | |
| 35 globalAlpha_(1.0), | |
| 36 miterLimit_(10), | |
| 37 fillColor_(ColorRGBA(255, 0, 0, 255)), | |
| 38 strokeColor_(fillColor_), | |
| 39 shadowColor_(ColorRGBA(0, 0, 0, 0)), | |
| 40 shadowBlur_(0.0), | |
| 41 shadowOffsetX_(0.0), | |
| 42 shadowOffsetY_(0.0), | |
| 43 lineDash_(NULL), | |
| 44 lineDashCount_(0), | |
| 45 lineDashOffset_(0), | |
| 46 fillShader_(NULL), | |
| 47 strokeShader_(NULL), | |
| 48 path_(new SkPath()), | |
| 49 canvas_(canvas), | |
| 50 next_(NULL) { | |
| 51 paint_.setStrokeCap(SkPaint::kButt_Cap); | |
| 52 paint_.setStrokeJoin(SkPaint::kMiter_Join); | |
| 53 paint_.setStrokeWidth(1); | |
| 54 paint_.setTextAlign(SkPaint::kLeft_Align); | |
| 55 paint_.setAntiAlias(true); | |
| 56 paint_.setStyle(SkPaint::kStroke_Style); | |
| 57 setFont("Helvetica", 10); | |
| 58 } | |
| 59 | |
| 60 CanvasState(const CanvasState& state) | |
| 61 : paint_(state.paint_), | |
| 62 globalAlpha_(state.globalAlpha_), | |
| 63 miterLimit_(state.miterLimit_), | |
| 64 fillColor_(state.fillColor_), | |
| 65 strokeColor_(state.strokeColor_), | |
| 66 shadowColor_(state.shadowColor_), | |
| 67 shadowBlur_(state.shadowBlur_), | |
| 68 shadowOffsetX_(state.shadowOffsetX_), | |
| 69 shadowOffsetY_(state.shadowOffsetY_), | |
| 70 lineDash_(NULL), | |
| 71 lineDashCount_(state.lineDashCount_), | |
| 72 lineDashOffset_(state.lineDashOffset_), | |
| 73 fillShader_(state.fillShader_), | |
| 74 strokeShader_(state.strokeShader_), | |
| 75 path_(new SkPath()), | |
| 76 canvas_(state.canvas_), | |
| 77 next_(NULL) { | |
| 78 setLineDash(state.lineDash_, lineDashCount_); | |
| 79 if (fillShader_ != NULL) fillShader_->ref(); | |
| 80 if (strokeShader_ != NULL) strokeShader_->ref(); | |
| 81 } | |
| 82 | |
| 83 ~CanvasState() { | |
| 84 if (fillShader_ != NULL) fillShader_->unref(); | |
| 85 if (strokeShader_ != NULL) strokeShader_->unref(); | |
| 86 delete path_; | |
| 87 delete[] lineDash_; | |
| 88 } | |
| 89 | |
| 90 static ColorRGBA GetColor(const char* color); | |
| 91 | |
| 92 inline CanvasState* Save() { | |
| 93 canvas_->save(); // For clip and transform. | |
| 94 CanvasState *new_state = new CanvasState(*this); | |
| 95 new_state->next_ = this; | |
| 96 // If the old state has a non-empty path, use its | |
| 97 // last point as the new states first point. | |
| 98 int np = path_->countPoints(); | |
| 99 if (np > 0) { | |
| 100 new_state->path_->moveTo(path_->getPoint(np-1)); | |
| 101 } | |
| 102 return new_state; | |
| 103 } | |
| 104 | |
| 105 CanvasState* Restore(); | |
| 106 | |
| 107 inline float Radians2Degrees(float angle) { | |
| 108 return 180.0 * angle / M_PI; | |
| 109 } | |
| 110 | |
| 111 inline void setGlobalAlpha(float alpha) { | |
| 112 globalAlpha_ = alpha; | |
| 113 } | |
| 114 | |
| 115 inline void setFillColor(const char* color) { | |
| 116 if (fillShader_ != NULL) { | |
| 117 fillShader_->unref(); | |
| 118 fillShader_ = NULL; | |
| 119 } | |
| 120 fillColor_ = GetColor(color); | |
| 121 } | |
| 122 | |
| 123 inline void setStrokeColor(const char* color) { | |
| 124 if (strokeShader_ != NULL) { | |
| 125 strokeShader_->unref(); | |
| 126 strokeShader_ = NULL; | |
| 127 } | |
| 128 strokeColor_ = GetColor(color); | |
| 129 } | |
| 130 | |
| 131 const char* setFont(const char*name, float size = -1); | |
| 132 void setLineCap(const char* lc); | |
| 133 void setLineJoin(const char* lj); | |
| 134 | |
| 135 inline void setMiterLimit(float limit) { | |
| 136 miterLimit_ = limit; | |
| 137 } | |
| 138 | |
| 139 const char* setTextAlign(const char* align); | |
| 140 const char* setTextBaseline(const char* baseline); | |
| 141 const char* setTextDirection(const char* direction); | |
| 142 | |
| 143 inline void FillText(const char* text, float x, float y, float maxWidth) { | |
| 144 setFillMode(); | |
| 145 canvas_->drawText(text, strlen(text), x, y, paint_); | |
| 146 } | |
| 147 | |
| 148 inline void StrokeText(const char* text, float x, float y, float maxWidth) { | |
| 149 setStrokeMode(); | |
| 150 canvas_->drawText(text, strlen(text), x, y, paint_); | |
| 151 } | |
| 152 | |
| 153 inline float MeasureText(const char *text) { | |
| 154 // TODO(gram): make sure this is not supposed to be affected | |
| 155 // by the canvas transform. | |
| 156 return paint_.measureText(text, strlen(text)); | |
| 157 } | |
| 158 | |
| 159 inline void setLineWidth(float w) { | |
| 160 paint_.setStrokeWidth(w); | |
| 161 } | |
| 162 | |
| 163 void setMode(SkPaint::Style style, ColorRGBA color, SkShader* shader); | |
| 164 | |
| 165 inline void setLineDashEffect() { | |
| 166 if (lineDashCount_ > 0) { | |
| 167 SkDashPathEffect* dashPathEffect = | |
| 168 new SkDashPathEffect(lineDash_, lineDashCount_, lineDashOffset_); | |
| 169 paint_.setPathEffect(dashPathEffect)->unref(); | |
| 170 } else { | |
| 171 paint_.setPathEffect(NULL); | |
| 172 } | |
| 173 } | |
| 174 | |
| 175 inline void setLineDash(float* dashes, int len) { | |
| 176 if (len == 0) { | |
| 177 lineDashCount_ = 0; | |
| 178 delete[] lineDash_; | |
| 179 lineDash_ = NULL; | |
| 180 } else { | |
| 181 lineDash_ = new float[lineDashCount_ = len]; | |
| 182 for (int i = 0; i < len; i++) { | |
| 183 lineDash_[i] = dashes[i]; | |
| 184 } | |
| 185 } | |
| 186 setLineDashEffect(); | |
| 187 } | |
| 188 | |
| 189 inline void setLineDashOffset(int offset) { | |
| 190 if (offset != lineDashOffset_) { | |
| 191 lineDashOffset_ = offset; | |
| 192 setLineDashEffect(); | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 inline void setShadowColor(const char* color) { | |
| 197 shadowColor_ = GetColor(color); | |
| 198 } | |
| 199 | |
| 200 inline void setShadowBlur(float blur) { | |
| 201 shadowBlur_ = blur; | |
| 202 } | |
| 203 | |
| 204 inline void setShadowOffsetX(float ox) { | |
| 205 shadowOffsetX_ = ox; | |
| 206 } | |
| 207 | |
| 208 inline void setShadowOffsetY(float oy) { | |
| 209 shadowOffsetY_ = oy; | |
| 210 } | |
| 211 | |
| 212 inline void setFillMode() { | |
| 213 setMode(SkPaint::kFill_Style, fillColor_, fillShader_); | |
| 214 } | |
| 215 | |
| 216 inline void setStrokeMode() { | |
| 217 setMode(SkPaint::kStroke_Style, strokeColor_, strokeShader_); | |
| 218 } | |
| 219 | |
| 220 inline void FillRect(float left, float top, | |
| 221 float width, float height) { | |
| 222 // Does not affect the path. | |
| 223 setFillMode(); | |
| 224 canvas_->drawRectCoords(left, top, left + width, top + height, paint_); | |
| 225 } | |
| 226 | |
| 227 inline void StrokeRect(float left, float top, | |
| 228 float width, float height) { | |
| 229 // Does not affect the path. | |
| 230 setStrokeMode(); | |
| 231 canvas_->drawRectCoords(left, top, left + width, top + height, paint_); | |
| 232 } | |
| 233 | |
| 234 inline void BeginPath() { | |
| 235 path_->rewind(); | |
| 236 } | |
| 237 | |
| 238 inline void Fill() { | |
| 239 setFillMode(); | |
| 240 canvas_->drawPath(*path_, paint_); | |
| 241 } | |
| 242 | |
| 243 inline void Stroke() { | |
| 244 setStrokeMode(); | |
| 245 canvas_->drawPath(*path_, paint_); | |
| 246 } | |
| 247 | |
| 248 inline void ClosePath() { | |
| 249 path_->close(); | |
| 250 } | |
| 251 | |
| 252 inline void MoveTo(float x, float y) { | |
| 253 path_->moveTo(x, y); | |
| 254 } | |
| 255 | |
| 256 inline void LineTo(float x, float y) { | |
| 257 path_->lineTo(x, y); | |
| 258 } | |
| 259 | |
| 260 void Arc(float x, float y, float radius, float startAngle, float endAngle, | |
| 261 bool antiClockwise); | |
| 262 | |
| 263 inline void QuadraticCurveTo(float cpx, float cpy, float x, float y) { | |
| 264 path_->quadTo(cpx, cpy, x, y); | |
| 265 } | |
| 266 | |
| 267 inline void BezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, | |
| 268 float x, float y) { | |
| 269 path_->cubicTo(cp1x, cp1y, cp2x, cp2y, x, y); | |
| 270 } | |
| 271 | |
| 272 inline void ArcTo(float x1, float y1, float x2, float y2, float radius) { | |
| 273 path_->arcTo(x1, y1, x2, y2, radius); | |
| 274 } | |
| 275 | |
| 276 inline void Rect(float x, float y, float w, float h) { | |
| 277 // TODO(gram): Should we draw this directly? If so, what happens with the | |
| 278 // path? | |
| 279 path_->addRect(x, y, x + w, y + h); | |
| 280 } | |
| 281 | |
| 282 void setGlobalCompositeOperation(const char* op); | |
| 283 | |
| 284 void DrawImage(const SkBitmap& bm, | |
| 285 int sx, int sy, int sw, int sh, | |
| 286 int dx, int dy, int dw, int dh); | |
| 287 | |
| 288 inline void Clip() { | |
| 289 canvas_->clipPath(*path_); | |
| 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); | |
| 309 } CanvasState; | |
| 310 | |
| 311 #endif // EMBEDDERS_OPENGLUI_COMMON_CANVAS_STATE_H_ | |
| 312 | |
| OLD | NEW |