OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 { | 265 { |
266 SkPaint paint; | 266 SkPaint paint; |
267 int fillcolorNotTransparent = m_state->m_fillColor & 0xFF000000; | 267 int fillcolorNotTransparent = m_state->m_fillColor & 0xFF000000; |
268 if (fillcolorNotTransparent) { | 268 if (fillcolorNotTransparent) { |
269 setupPaintForFilling(&paint); | 269 setupPaintForFilling(&paint); |
270 canvas()->drawRect(rect, paint); | 270 canvas()->drawRect(rect, paint); |
271 } | 271 } |
272 | 272 |
273 if (m_state->m_strokeStyle != WebCore::NoStroke && | 273 if (m_state->m_strokeStyle != WebCore::NoStroke && |
274 (m_state->m_strokeColor & 0xFF000000)) { | 274 (m_state->m_strokeColor & 0xFF000000)) { |
275 if (fillcolorNotTransparent) { | 275 // We do a fill of four rects to simulate the stroke of a border. |
276 // This call is expensive so don't call it unnecessarily. | 276 SkColor oldFillColor = m_state->m_fillColor; |
277 paint.reset(); | 277 if (oldFillColor != m_state->m_strokeColor) |
278 } | 278 setFillColor(m_state->m_strokeColor); |
279 setupPaintForStroking(&paint, &rect, 0); | 279 setupPaintForFilling(&paint); |
280 canvas()->drawRect(rect, paint); | 280 SkRect topBorder = { rect.fLeft, rect.fTop, rect.width(), 1}; |
| 281 canvas()->drawRect(topBorder, paint); |
| 282 SkRect bottomBorder = { rect.fLeft, rect.fBottom - 1, rect.width(), 1 }; |
| 283 canvas()->drawRect(bottomBorder, paint); |
| 284 SkRect leftBorder = { rect.fLeft, rect.fTop + 1, 1, rect.height() - 2 }; |
| 285 canvas()->drawRect(leftBorder, paint); |
| 286 SkRect rightBorder = { rect.fRight - 1, rect.fTop + 1, 1, rect.height()
- 2 }; |
| 287 canvas()->drawRect(rightBorder, paint); |
| 288 if (oldFillColor != m_state->m_strokeColor) |
| 289 setFillColor(oldFillColor); |
281 } | 290 } |
282 } | 291 } |
283 | 292 |
284 void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const | 293 void PlatformContextSkia::setupPaintCommon(SkPaint* paint) const |
285 { | 294 { |
286 #ifdef SK_DEBUGx | 295 #ifdef SK_DEBUGx |
287 { | 296 { |
288 SkPaint defaultPaint; | 297 SkPaint defaultPaint; |
289 SkASSERT(*paint == defaultPaint); | 298 SkASSERT(*paint == defaultPaint); |
290 } | 299 } |
(...skipping 13 matching lines...) Expand all Loading... |
304 { | 313 { |
305 setupPaintCommon(paint); | 314 setupPaintCommon(paint); |
306 paint->setColor(m_state->applyAlpha(m_state->m_fillColor)); | 315 paint->setColor(m_state->applyAlpha(m_state->m_fillColor)); |
307 } | 316 } |
308 | 317 |
309 float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
nt length) const | 318 float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, i
nt length) const |
310 { | 319 { |
311 setupPaintCommon(paint); | 320 setupPaintCommon(paint); |
312 float width = m_state->m_strokeThickness; | 321 float width = m_state->m_strokeThickness; |
313 | 322 |
314 // This allows dashing and dotting to work properly for hairline strokes. | |
315 if (width == 0) | |
316 width = 1; | |
317 | |
318 paint->setColor(m_state->applyAlpha(m_state->m_strokeColor)); | 323 paint->setColor(m_state->applyAlpha(m_state->m_strokeColor)); |
319 paint->setStyle(SkPaint::kStroke_Style); | 324 paint->setStyle(SkPaint::kStroke_Style); |
320 paint->setStrokeWidth(SkFloatToScalar(width)); | 325 paint->setStrokeWidth(SkFloatToScalar(width)); |
321 paint->setStrokeCap(m_state->m_lineCap); | 326 paint->setStrokeCap(m_state->m_lineCap); |
322 paint->setStrokeJoin(m_state->m_lineJoin); | 327 paint->setStrokeJoin(m_state->m_lineJoin); |
323 paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit)); | 328 paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit)); |
324 | 329 |
325 if (rect != 0 && (static_cast<int>(roundf(width)) & 1)) | |
326 rect->inset(-SK_ScalarHalf, -SK_ScalarHalf); | |
327 | |
328 if (m_state->m_dash) | 330 if (m_state->m_dash) |
329 paint->setPathEffect(m_state->m_dash); | 331 paint->setPathEffect(m_state->m_dash); |
330 else { | 332 else { |
331 switch (m_state->m_strokeStyle) { | 333 switch (m_state->m_strokeStyle) { |
332 case WebCore::NoStroke: | 334 case WebCore::NoStroke: |
333 case WebCore::SolidStroke: | 335 case WebCore::SolidStroke: |
334 break; | 336 break; |
335 case WebCore::DashedStroke: | 337 case WebCore::DashedStroke: |
336 width = m_state->m_dashRatio * width; | 338 width = m_state->m_dashRatio * width; |
337 // Fall through. | 339 // Fall through. |
338 case WebCore::DottedStroke: | 340 case WebCore::DottedStroke: |
339 SkScalar dashLength; | 341 SkScalar dashLength; |
340 if (length) { | 342 if (length) { |
341 // Determine about how many dashes or dots we should have. | 343 // Determine about how many dashes or dots we should have. |
342 int numDashes = length / roundf(width); | 344 float roundedWidth = roundf(width); |
| 345 int numDashes = roundedWidth ? (length / roundedWidth) : length; |
343 if (!(numDashes & 1)) | 346 if (!(numDashes & 1)) |
344 numDashes++; // Make it odd so we end on a dash/dot. | 347 numDashes++; // Make it odd so we end on a dash/dot. |
345 // Use the number of dashes to determine the length of a | 348 // Use the number of dashes to determine the length of a |
346 // dash/dot, which will be approximately width | 349 // dash/dot, which will be approximately width |
347 dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(nu
mDashes)); | 350 dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(nu
mDashes)); |
348 } else | 351 } else |
349 dashLength = SkFloatToScalar(width); | 352 dashLength = SkFloatToScalar(width); |
350 SkScalar intervals[2] = { dashLength, dashLength }; | 353 SkScalar intervals[2] = { dashLength, dashLength }; |
351 paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref()
; | 354 paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref()
; |
352 } | 355 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 #if defined(__linux__) || PLATFORM(WIN_OS) | 519 #if defined(__linux__) || PLATFORM(WIN_OS) |
517 void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, con
st SkBitmap& imageBuffer) | 520 void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, con
st SkBitmap& imageBuffer) |
518 { | 521 { |
519 // NOTE: this assumes the image mask contains opaque black for the portions
that are to be shown, as such we | 522 // NOTE: this assumes the image mask contains opaque black for the portions
that are to be shown, as such we |
520 // only look at the alpha when compositing. I'm not 100% sure this is what W
ebKit expects for image clipping. | 523 // only look at the alpha when compositing. I'm not 100% sure this is what W
ebKit expects for image clipping. |
521 SkPaint paint; | 524 SkPaint paint; |
522 paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); | 525 paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); |
523 m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar
(rect.y()), &paint); | 526 m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar
(rect.y()), &paint); |
524 } | 527 } |
525 #endif | 528 #endif |
OLD | NEW |