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