Changeset 13748 in webkit


Ignore:
Timestamp:
Apr 9, 2006 4:38:06 PM (18 years ago)
Author:
darin
Message:

LayoutTests:

Reviewed by Anders.

  • fast/canvas/canvas-before-css-expected.checksum: Added.
  • fast/canvas/canvas-before-css-expected.png: Added.
  • fast/canvas/canvas-before-css-expected.txt: Added.
  • fast/canvas/canvas-before-css.html: Added.
  • fast/canvas/image-object-in-canvas.html: Test had a bug where it used <canvas> without a </canvas> tag. Changed test to include a </canvas> tag.
  • fast/canvas/patternfill-repeat-expected.txt: Updated for name change from RenderCanvasImage to RenderHTMLCanvas.
  • fast/canvas/image-object-in-canvas-expected.txt: Ditto.
  • fast/canvas/fillrect_gradient-expected.txt: Ditto.
  • fast/canvas/quadraticCurveTo-expected.txt: Ditto.

WebCore:

Reviewed by Anders.

Test: fast/canvas/canvas-before-css.html

This patch makes us match the canvas documentation in Hixie's Web Applications
draft as far as when the canvas is created and recreated and how it's sized.
It also gets rid of the compositeOperation attribute of the canvas element.
We can add that back if we need it. Anders points out that this specifically
changes behavior for canvas elements where the size is set in CSS and not with
width and height attributes. The CSS size now determines how big a box the canvas
is rendered into, but has no effect on the size of the canvas's buffer.

  • html/CanvasRenderingContext2D.h: Added overloads of drawImage that take HTMLCanvasElement, which is no longer derived from HTMLImageElement.
  • html/CanvasRenderingContext2D.cpp: (WebCore::imageSize): Renamed from imageOrCanvasSize. Now used for images only, because canvas is no longer derived from image. (WebCore::CanvasRenderingContext2D::drawImage): Split the implementation of this for image sources from the implementation for canvas sources. (WebCore::CanvasRenderingContext2D::willDraw): Changed to call a new willDraw function on the canvas element. (WebCore::CanvasRenderingContext2D::drawingContext): Changed to call drawingContext on the canvas element rather than the renderer.
  • html/HTMLCanvasElement.h: Changed HTMLCanvasElement to derive from HTMLElement instead of HTMLImageElement. Added width, height, setWidth, setHeight, willDraw, paint, drawingContext, createDrawingContext, and reset functions. Added m_size, m_createdDrawingContext, m_data, and m_drawingContext data members. Removed mapToEntry, attach, detach, and isURLAttribute functins.
  • html/HTMLCanvasElement.cpp: (WebCore::HTMLCanvasElement::HTMLCanvasElement): Added initializers for new m_size, m_createdDrawingContext, m_data, and m_drawingContext data members. (WebCore::HTMLCanvasElement::~HTMLCanvasElement): Free m_data and m_drawingContext. (WebCore::HTMLCanvasElement::parseMappedAttribute): Got rid of special case for srcAttr, which is no longer needed since we aren't deriving from HTMLImageElement. Added code that triggers a reset when either width or height is set. (WebCore::HTMLCanvasElement::createRenderer): Added code to set the intrinsic width and height of the renderer to the size of the element. (WebCore::HTMLCanvasElement::setHeight): Added. Sets the height attribute. (WebCore::HTMLCanvasElement::setWidth): Added. Sets the width attribute. (WebCore::HTMLCanvasElement::willDraw): Added. Tells the renderer to repaint. Also has FIXME mentioning we could dirty only the part that has changed in the future. (WebCore::HTMLCanvasElement::reset): Added. Sets the size of the canvas and discards the old buffer, which is an indirect way of resetting the buffer to transparent black. (WebCore::HTMLCanvasElement::paint): Added. Draws the canvas image into the graphics context that's passed in. (WebCore::HTMLCanvasElement::createDrawingContext): Added. Allocates a buffer for the bits, then creates a bitmap context for drawing into the buffer. (WebCore::HTMLCanvasElement::drawingContext): Added. Calls createDrawingContext if needed, then returns the current drawing context. (WebCore::HTMLCanvasElement::createPlatformImage): Changed to always call CGContextFlush and to create the image from the context in this class.
  • rendering/RenderHTMLCanvas.h: Remove almost all of the contents of this file. Removed ~RenderHTMLCanvas, setNeedsImageUpdate, element, updateDrawnImage, drawingContext, createDrawingContext, and drawnImage functions and _drawingContext, _drawingContextData, _drawnImage, and _needsImageUpdate booleans. Changed RenderHTMLCanvas to derive from RenderReplaced instead of RenderImage.
  • rendering/RenderHTMLCanvas.cpp: (WebCore::RenderHTMLCanvas::RenderHTMLCanvas): Changed to only initialize RenderReplaced. (WebCore::RenderHTMLCanvas::renderName): Moved this in here, since there's no good reason to have this virtual function inlined. (WebCore::RenderHTMLCanvas::paint): Changed implementation to use HTMLCanvasElement::paint instead ofcalling CGContextDrawImage directly. (WebCore::RenderHTMLCanvas::layout): Removed the code that detects changes in width and causes the drawing context to be recreated; instead, if the width and height changes we scale when we paint the canvas.
  • bindings/js/JSCanvasRenderingContext2DBase.cpp: (WebCore::JSCanvasRenderingContext2DBaseProtoFunc::callAsFunction): Separated out handling for <canvas> vs. <img> elements in drawRect, since HTMLCanvasElement is no longer derived from HTMLImageElement.
Location:
trunk
Files:
4 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r13746 r13748  
     12006-04-09  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Anders.
     4
     5        - test changes for http://bugzilla.opendarwin.org/show_bug.cgi?id=4884
     6          Canvas element breaks when RenderObject creation is deferred by external CSS
     7
     8        * fast/canvas/canvas-before-css-expected.checksum: Added.
     9        * fast/canvas/canvas-before-css-expected.png: Added.
     10        * fast/canvas/canvas-before-css-expected.txt: Added.
     11        * fast/canvas/canvas-before-css.html: Added.
     12
     13        * fast/canvas/image-object-in-canvas.html: Test had a bug where it used <canvas>
     14        without a </canvas> tag. Changed test to include a </canvas> tag.
     15
     16        * fast/canvas/patternfill-repeat-expected.txt: Updated for name change from
     17        RenderCanvasImage to RenderHTMLCanvas.
     18        * fast/canvas/image-object-in-canvas-expected.txt: Ditto.
     19        * fast/canvas/fillrect_gradient-expected.txt: Ditto.
     20        * fast/canvas/quadraticCurveTo-expected.txt: Ditto.
     21
    1222006-04-09  Rob Buis  <buis@kde.org>
    223
     
    3556        * fast/js/string-capitalization-expected.txt: Added.
    3657        * fast/js/string-capitalization.html: Added.
     58
     592006-04-07  Darin Adler  <darin@apple.com>
     60
     61        Reviewed by Hyatt.
     62
     63        - test for http://bugzilla.opendarwin.org/show_bug.cgi?id=8134
     64          REGRESSION: dragging down from the middle of a text field does not select to end of field
     65
     66        * fast/forms/input-text-drag-down-expected.checksum: Added.
     67        * fast/forms/input-text-drag-down-expected.png: Added.
     68        * fast/forms/input-text-drag-down-expected.txt: Added.
     69        * fast/forms/input-text-drag-down.html: Added.
    3770
    38712006-04-07  Darin Adler  <darin@apple.com>
  • trunk/LayoutTests/fast/canvas/fillrect_gradient-expected.txt

    r13231 r13748  
    66      RenderText {TEXT} at (0,0) size 722x18
    77        text run at (0,0) width 722: "The canvas below should show a gradient, starting at green at the top and fading to white at the bottom of the rect. "
    8       RenderCanvasImage {CANVAS} at (0,18) size 150x150
     8      RenderHTMLCanvas {CANVAS} at (0,18) size 150x150
    99      RenderText {TEXT} at (0,0) size 0x0
    1010      RenderText {TEXT} at (0,0) size 0x0
  • trunk/LayoutTests/fast/canvas/image-object-in-canvas-expected.txt

    r13231 r13748  
    99          text run at (0,18) width 354: "should appear scaled, normal and finally tiled in a circle."
    1010      RenderBlock {DIV} at (0,52) size 784x154
    11         RenderCanvasImage {CANVAS} at (0,0) size 150x150
     11        RenderHTMLCanvas {CANVAS} at (0,0) size 150x150
    1212        RenderText {TEXT} at (150,136) size 117x18
    1313          text run at (150,136) width 117: "Using drawImage."
    1414      RenderBlock {DIV} at (0,206) size 784x154
    15         RenderCanvasImage {CANVAS} at (0,0) size 150x150
     15        RenderHTMLCanvas {CANVAS} at (0,0) size 150x150
    1616        RenderText {TEXT} at (150,136) size 180x18
    1717          text run at (150,136) width 180: "Using drawImageFromRect."
    1818      RenderBlock {DIV} at (0,360) size 784x154
    19         RenderCanvasImage {CANVAS} at (0,0) size 150x150
     19        RenderHTMLCanvas {CANVAS} at (0,0) size 150x150
    2020        RenderText {TEXT} at (150,136) size 129x18
    2121          text run at (150,136) width 129: "Using ImagePattern."
  • trunk/LayoutTests/fast/canvas/image-object-in-canvas.html

    r13231 r13748  
    4747<body onload="runTests();">
    4848<p>This tests that the Image JavaScript object works as expected when used in a canvas. If the test is successful, the Apple logo should appear scaled, normal and finally tiled in a circle.</p>
    49 <div><canvas id="canvas1" width="150" height="150"/>Using drawImage.</div>
    50 <div><canvas id="canvas2" width="150" height="150"/>Using drawImageFromRect.</div>
    51 <div><canvas id="canvas3" width="150" height="150"/>Using ImagePattern.</div>
     49<div><canvas id="canvas1" width="150" height="150"></canvas>Using drawImage.</div>
     50<div><canvas id="canvas2" width="150" height="150"></canvas>Using drawImageFromRect.</div>
     51<div><canvas id="canvas3" width="150" height="150"></canvas>Using ImagePattern.</div>
    5252
    5353<pre id="console">
  • trunk/LayoutTests/fast/canvas/patternfill-repeat-expected.txt

    r13384 r13748  
    1111          text run at (0,54) width 220: "one Apple image in top left corner."
    1212      RenderBlock {P} at (0,88) size 784x340
    13         RenderCanvasImage {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
     13        RenderHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
  • trunk/LayoutTests/fast/canvas/quadraticCurveTo-expected.txt

    r13231 r13748  
    88          text run at (0,0) width 416: "This test case should produce a sine-wave stroked with 1px black."
    99    RenderBlock (anonymous) at (0,50) size 800x364
    10       RenderCanvasImage {CANVAS} at (0,0) size 480x360
     10      RenderHTMLCanvas {CANVAS} at (0,0) size 480x360
  • trunk/WebCore/ChangeLog

    r13747 r13748  
     12006-04-09  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Anders.
     4
     5        - fix http://bugzilla.opendarwin.org/show_bug.cgi?id=4884
     6          Canvas element breaks when RenderObject creation is deferred by external CSS
     7
     8        Test: fast/canvas/canvas-before-css.html
     9
     10        This patch makes us match the canvas documentation in Hixie's Web Applications
     11        draft as far as when the canvas is created and recreated and how it's sized.
     12        It also gets rid of the compositeOperation attribute of the canvas element.
     13        We can add that back if we need it. Anders points out that this specifically
     14        changes behavior for canvas elements where the size is set in CSS and not with
     15        width and height attributes. The CSS size now determines how big a box the canvas
     16        is rendered into, but has no effect on the size of the canvas's buffer.
     17
     18        * html/CanvasRenderingContext2D.h: Added overloads of drawImage that take
     19        HTMLCanvasElement, which is no longer derived from HTMLImageElement.
     20        * html/CanvasRenderingContext2D.cpp:
     21        (WebCore::imageSize): Renamed from imageOrCanvasSize. Now used for images only,
     22        because canvas is no longer derived from image.
     23        (WebCore::CanvasRenderingContext2D::drawImage): Split the implementation of this
     24        for image sources from the implementation for canvas sources.
     25        (WebCore::CanvasRenderingContext2D::willDraw): Changed to call a new willDraw
     26        function on the canvas element.
     27        (WebCore::CanvasRenderingContext2D::drawingContext): Changed to call drawingContext
     28        on the canvas element rather than the renderer.
     29
     30        * html/HTMLCanvasElement.h: Changed HTMLCanvasElement to derive from HTMLElement
     31        instead of HTMLImageElement. Added width, height, setWidth, setHeight, willDraw,
     32        paint, drawingContext, createDrawingContext, and reset functions. Added m_size,
     33        m_createdDrawingContext, m_data, and m_drawingContext data members. Removed
     34        mapToEntry, attach, detach, and isURLAttribute functins.
     35
     36        * html/HTMLCanvasElement.cpp:
     37        (WebCore::HTMLCanvasElement::HTMLCanvasElement): Added initializers for new m_size,
     38        m_createdDrawingContext, m_data, and m_drawingContext data members.
     39        (WebCore::HTMLCanvasElement::~HTMLCanvasElement): Free m_data and m_drawingContext.
     40        (WebCore::HTMLCanvasElement::parseMappedAttribute): Got rid of special case for
     41        srcAttr, which is no longer needed since we aren't deriving from HTMLImageElement.
     42        Added code that triggers a reset when either width or height is set.
     43        (WebCore::HTMLCanvasElement::createRenderer): Added code to set the intrinsic
     44        width and height of the renderer to the size of the element.
     45        (WebCore::HTMLCanvasElement::setHeight): Added. Sets the height attribute.
     46        (WebCore::HTMLCanvasElement::setWidth): Added. Sets the width attribute.
     47        (WebCore::HTMLCanvasElement::willDraw): Added. Tells the renderer to repaint.
     48        Also has FIXME mentioning we could dirty only the part that has changed in the future.
     49        (WebCore::HTMLCanvasElement::reset): Added. Sets the size of the canvas and discards
     50        the old buffer, which is an indirect way of resetting the buffer to transparent black.
     51        (WebCore::HTMLCanvasElement::paint): Added. Draws the canvas image into the graphics
     52        context that's passed in.
     53        (WebCore::HTMLCanvasElement::createDrawingContext): Added. Allocates a buffer for
     54        the bits, then creates a bitmap context for drawing into the buffer.
     55        (WebCore::HTMLCanvasElement::drawingContext): Added. Calls createDrawingContext if
     56        needed, then returns the current drawing context.
     57        (WebCore::HTMLCanvasElement::createPlatformImage): Changed to always call CGContextFlush
     58        and to create the image from the context in this class.
     59
     60        * rendering/RenderHTMLCanvas.h: Remove almost all of the contents of this file.
     61        Removed ~RenderHTMLCanvas, setNeedsImageUpdate, element, updateDrawnImage, drawingContext,
     62        createDrawingContext, and drawnImage functions and _drawingContext, _drawingContextData,
     63        _drawnImage, and _needsImageUpdate booleans. Changed RenderHTMLCanvas to derive from
     64        RenderReplaced instead of RenderImage.
     65
     66        * rendering/RenderHTMLCanvas.cpp:
     67        (WebCore::RenderHTMLCanvas::RenderHTMLCanvas): Changed to only initialize RenderReplaced.
     68        (WebCore::RenderHTMLCanvas::renderName): Moved this in here, since there's no good reason
     69        to have this virtual function inlined.
     70        (WebCore::RenderHTMLCanvas::paint): Changed implementation to use HTMLCanvasElement::paint
     71        instead ofcalling CGContextDrawImage directly.
     72        (WebCore::RenderHTMLCanvas::layout): Removed the code that detects changes in width and
     73        causes the drawing context to be recreated; instead, if the width and height changes we
     74        scale when we paint the canvas.
     75
     76        * bindings/js/JSCanvasRenderingContext2DBase.cpp:
     77        (WebCore::JSCanvasRenderingContext2DBaseProtoFunc::callAsFunction):
     78        Separated out handling for <canvas> vs. <img> elements in drawRect, since
     79        HTMLCanvasElement is no longer derived from HTMLImageElement.
     80
    1812006-04-09  Rob Buis  <buis@kde.org>
    282
  • trunk/WebCore/bindings/js/JSCanvasRenderingContext2DBase.cpp

    r13424 r13748  
    1818 */
    1919
    20 // This file needs to be touched every once in a while.
    21 
    2220#include "config.h"
    2321#include "JSCanvasRenderingContext2DBase.h"
     
    2725#include "CanvasRenderingContext2D.h"
    2826#include "CanvasStyle.h"
     27#include "HTMLCanvasElement.h"
    2928#include "JSCanvasGradient.h"
    3029#include "JSCanvasPattern.h"
     
    179178        case JSCanvasRenderingContext2DBase::DrawImage: {
    180179            // DrawImage has three variants:
    181             // drawImage(img, dx, dy)
    182             // drawImage(img, dx, dy, dw, dh)
    183             // drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
    184             // composite operation is specified with globalCompositeOperation
    185             // img parameter can be a JavaScript Image, <img>, or a <canvas>
     180            //     drawImage(img, dx, dy)
     181            //     drawImage(img, dx, dy, dw, dh)
     182            //     drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
     183            // Composite operation is specified with globalCompositeOperation.
     184            // The img parameter can be a <img> or <canvas> element.
    186185            JSObject* o = static_cast<JSObject*>(args[0]);
    187186            if (!o->isObject())
    188187                return throwError(exec, TypeError);
    189             if (!(o->inherits(&JSHTMLElement::img_info) || o->inherits(&JSHTMLElement::canvas_info)))
    190                 return throwError(exec, TypeError);
    191             HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
    192             switch (args.size()) {
    193                 case 3:
    194                     context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec));
    195                     break;
    196                 case 5:
    197                     context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec),
    198                         args[3]->toNumber(exec), args[4]->toNumber(exec));
    199                     break;
    200                 case 9:
    201                     context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec),
    202                         args[3]->toNumber(exec), args[4]->toNumber(exec),
    203                         args[5]->toNumber(exec), args[6]->toNumber(exec),
    204                         args[7]->toNumber(exec), args[8]->toNumber(exec));
    205                     break;
    206                 default:
    207                     return throwError(exec, SyntaxError);
    208             }
    209             break;
     188            if (o->inherits(&JSHTMLElement::img_info)) {
     189                HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
     190                switch (args.size()) {
     191                    case 3:
     192                        context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec));
     193                        break;
     194                    case 5:
     195                        context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec),
     196                            args[3]->toNumber(exec), args[4]->toNumber(exec));
     197                        break;
     198                    case 9:
     199                        context->drawImage(imgElt, args[1]->toNumber(exec), args[2]->toNumber(exec),
     200                            args[3]->toNumber(exec), args[4]->toNumber(exec),
     201                            args[5]->toNumber(exec), args[6]->toNumber(exec),
     202                            args[7]->toNumber(exec), args[8]->toNumber(exec));
     203                        break;
     204                    default:
     205                        return throwError(exec, SyntaxError);
     206                }
     207                break;
     208            }
     209            if (o->inherits(&JSHTMLElement::canvas_info)) {
     210                HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
     211                switch (args.size()) {
     212                    case 3:
     213                        context->drawImage(canvas, args[1]->toNumber(exec), args[2]->toNumber(exec));
     214                        break;
     215                    case 5:
     216                        context->drawImage(canvas, args[1]->toNumber(exec), args[2]->toNumber(exec),
     217                            args[3]->toNumber(exec), args[4]->toNumber(exec));
     218                        break;
     219                    case 9:
     220                        context->drawImage(canvas, args[1]->toNumber(exec), args[2]->toNumber(exec),
     221                            args[3]->toNumber(exec), args[4]->toNumber(exec),
     222                            args[5]->toNumber(exec), args[6]->toNumber(exec),
     223                            args[7]->toNumber(exec), args[8]->toNumber(exec));
     224                        break;
     225                    default:
     226                        return throwError(exec, SyntaxError);
     227                }
     228                break;
     229            }
     230            return throwError(exec, TypeError);
    210231        }
    211232        case JSCanvasRenderingContext2DBase::DrawImageFromRect: {
  • trunk/WebCore/html/CanvasRenderingContext2D.cpp

    r13440 r13748  
    771771
    772772// FIXME: This only exists because canvas is a subclass of image.
    773 static IntSize imageOrCanvasSize(HTMLImageElement* image)
    774 {
    775     if (image->hasLocalName(canvasTag))
    776         return static_cast<HTMLCanvasElement*>(image)->size();
     773static IntSize imageSize(HTMLImageElement* image)
     774{
    777775    if (CachedImage* cachedImage = image->cachedImage())
    778776        return cachedImage->imageSize();
     
    784782    if (!image)
    785783        return;
    786     IntSize size = imageOrCanvasSize(image);
     784    IntSize size = imageSize(image);
    787785    drawImage(image, 0, 0, size.width(), size.height(), x, y, size.width(), size.height());
    788786}
     
    792790    if (!image)
    793791        return;
    794     IntSize size = imageOrCanvasSize(image);
     792    IntSize size = imageSize(image);
    795793    drawImage(image, 0, 0, size.width(), size.height(), x, y, width, height);
    796794}
     
    809807        return;
    810808
     809    CachedImage* cachedImage = image->cachedImage();
     810    if (!cachedImage)
     811        return;
     812
    811813    FloatRect destRect = FloatRect(dx, dy, dw, dh);
    812 
    813     if (!image->hasLocalName(canvasTag)) {
    814         CachedImage* cachedImage = image->cachedImage();
    815         if (!cachedImage)
    816             return;
    817 
    818         willDraw(destRect);
    819         cachedImage->image()->drawInRect(destRect, FloatRect(sx, sy, sw, sh),
    820             Image::compositeOperatorFromString(state().m_globalComposite), c);
    821         return;
    822     }
    823 
    824     CGImageRef platformImage = static_cast<HTMLCanvasElement*>(image)->createPlatformImage();
     814    willDraw(destRect);
     815    cachedImage->image()->drawInRect(destRect, FloatRect(sx, sy, sw, sh),
     816        Image::compositeOperatorFromString(state().m_globalComposite), c);
     817#endif
     818}
     819
     820void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, float x, float y)
     821{
     822    if (!canvas)
     823        return;
     824    drawImage(canvas, 0, 0, canvas->width(), canvas->height(), x, y, canvas->width(), canvas->height());
     825}
     826
     827void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas, float x, float y, float width, float height)
     828{
     829    if (!canvas)
     830        return;
     831    drawImage(canvas, 0, 0, canvas->width(), canvas->height(), x, y, width, height);
     832}
     833
     834void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* canvas,
     835    float sx, float sy, float sw, float sh,
     836    float dx, float dy, float dw, float dh)
     837{
     838    if (!canvas)
     839        return;
     840
     841    // FIXME: Do this through platform-independent GraphicsContext API.
     842#if __APPLE__
     843    CGContextRef c = drawingContext();
     844    if (!c)
     845        return;
     846
     847    CGImageRef platformImage = canvas->createPlatformImage();
    825848    if (!platformImage)
    826849        return;
    827850
     851    FloatRect destRect = FloatRect(dx, dy, dw, dh);
    828852    willDraw(destRect);
    829853
     
    872896        return;
    873897
    874     // FIXME: Do this through platform-independent GraphicsContext API.
    875 #if __APPLE__
    876     CGContextRef c = drawingContext();
    877     if (!c)
    878         return;
    879 
    880     FloatRect destRect = FloatRect(dx, dy, dw, dh);
    881 
    882     // FIXME: Does not support using a canvas as a source image.
    883898    CachedImage* cachedImage = image->cachedImage();
    884899    if (!cachedImage)
    885900        return;
    886901
     902    // FIXME: Do this through platform-independent GraphicsContext API.
     903    FloatRect destRect = FloatRect(dx, dy, dw, dh);
    887904    willDraw(destRect);
    888 
     905#if __APPLE__
     906    CGContextRef c = drawingContext();
     907    if (!c)
     908        return;
    889909    cachedImage->image()->drawInRect(destRect, FloatRect(sx, sy, sw, sh),
    890910        Image::compositeOperatorFromString(compositeOperation), c);
     
    917937}
    918938
    919 void CanvasRenderingContext2D::willDraw(const FloatRect&)
     939void CanvasRenderingContext2D::willDraw(const FloatRect& r)
    920940{
    921941    if (!m_canvas)
    922942        return;
    923     RenderHTMLCanvas* renderer = static_cast<RenderHTMLCanvas*>(m_canvas->renderer());
    924     if (renderer)
    925         renderer->setNeedsImageUpdate();
     943    m_canvas->willDraw(r);
    926944}
    927945
     
    932950    if (!m_canvas)
    933951        return 0;
    934     RenderHTMLCanvas* renderer = static_cast<RenderHTMLCanvas*>(m_canvas->renderer());
    935     if (!renderer)
    936         return 0;
    937     return renderer->drawingContext();
     952    return m_canvas->drawingContext();
    938953}
    939954
  • trunk/WebCore/html/CanvasRenderingContext2D.h

    r13393 r13748  
    143143        void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh,
    144144            float dx, float dy, float dw, float dh);
     145        void drawImage(HTMLCanvasElement*, float x, float y);
     146        void drawImage(HTMLCanvasElement*, float x, float y, float width, float height);
     147        void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh,
     148            float dx, float dy, float dw, float dh);
    145149
    146150        void drawImageFromRect(HTMLImageElement*, float sx, float sy, float sw, float sh,
  • trunk/WebCore/html/HTMLCanvasElement.cpp

    r13397 r13748  
    3131#include "CanvasRenderingContext2D.h"
    3232#include "CanvasStyle.h"
     33#include "GraphicsContext.h"
    3334#include "HTMLNames.h"
    3435#include "RenderHTMLCanvas.h"
     
    3839using namespace HTMLNames;
    3940
    40 HTMLCanvasElement::HTMLCanvasElement(Document *doc)
    41     : HTMLImageElement(canvasTag, doc), m_2DContext(0)
     41// These value come from the specification.
     42const int defaultWidth = 300;
     43const int defaultHeight = 150;
     44
     45HTMLCanvasElement::HTMLCanvasElement(Document* doc)
     46    : HTMLElement(canvasTag, doc), m_size(defaultWidth, defaultHeight)
     47    , m_createdDrawingContext(false), m_data(0)
     48#if __APPLE__
     49    , m_drawingContext(0)
     50#endif
    4251{
    4352}
     
    4756    if (m_2DContext)
    4857        m_2DContext->detachCanvas();
    49 }
    50 
    51 bool HTMLCanvasElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
    52 {
    53     if (attrName != srcAttr) // Ignore the src attribute
    54         return HTMLImageElement::mapToEntry(attrName, result);
    55     return false;
    56 }
    57 
    58 void HTMLCanvasElement::parseMappedAttribute(MappedAttribute *attr)
    59 {
    60     if (attr->name() != srcAttr) // Canvas ignores the src attribute
    61         HTMLImageElement::parseMappedAttribute(attr);
    62 }
    63 
    64 RenderObject *HTMLCanvasElement::createRenderer(RenderArena *arena, RenderStyle *style)
    65 {
     58    fastFree(m_data);
    6659#if __APPLE__
    67     return new (arena) RenderHTMLCanvas(this);
    68 #else
    69     return 0;
     60    CGContextRelease(m_drawingContext);
    7061#endif
    7162}
    7263
    73 void HTMLCanvasElement::attach()
     64void HTMLCanvasElement::parseMappedAttribute(MappedAttribute* attr)
    7465{
    75     // Don't want to call image's attach().
    76     HTMLElement::attach();
     66    const QualifiedName& attrName = attr->name();
     67    if (attrName == widthAttr || attrName == heightAttr)
     68        reset();
     69    HTMLElement::parseMappedAttribute(attr);
    7770}
    7871
    79 void HTMLCanvasElement::detach()
     72RenderObject* HTMLCanvasElement::createRenderer(RenderArena *arena, RenderStyle *style)
    8073{
    81     // Don't want to call image's detach().
    82     HTMLElement::detach();
    83 
    84     if (m_2DContext)
    85         m_2DContext->reset();
     74    RenderHTMLCanvas* r = new (arena) RenderHTMLCanvas(this);
     75    r->setIntrinsicWidth(width());
     76    r->setIntrinsicHeight(height());
     77    return r;
    8678}
    8779
    88 bool HTMLCanvasElement::isURLAttribute(Attribute *attr) const
     80void HTMLCanvasElement::setHeight(int value)
    8981{
    90     return ((attr->name() == usemapAttr && attr->value().domString()[0] != '#'));
     82    setAttribute(heightAttr, String::number(value));
     83}
     84
     85void HTMLCanvasElement::setWidth(int value)
     86{
     87    setAttribute(widthAttr, String::number(value));
    9188}
    9289
     
    10299}
    103100
    104 IntSize HTMLCanvasElement::size() const
     101void HTMLCanvasElement::willDraw(const FloatRect&)
    105102{
    106     RenderHTMLCanvas* canvasRenderer = static_cast<RenderHTMLCanvas*>(renderer());
    107     if (!canvasRenderer)
    108         return IntSize();
     103    // FIXME: Change to repaint just the dirty rect for speed.
     104    // Until we start doing this, we won't know if the rects passed in are
     105    // accurate. Also don't forget to take into account the transform
     106    // on the context when determining what needs to be repainted.
     107    if (renderer())
     108        renderer()->repaint();
     109}
     110
     111void HTMLCanvasElement::reset()
     112{
     113    bool ok;
     114    int w = getAttribute(widthAttr).toInt(&ok);
     115    if (!ok)
     116        w = defaultWidth;
     117    int h = getAttribute(heightAttr).toInt(&ok);
     118    if (!ok)
     119        h = defaultHeight;
     120    m_size = IntSize(w, h);
     121
     122    RenderHTMLCanvas* r = static_cast<RenderHTMLCanvas*>(renderer());
     123    if (r) {
     124        r->setIntrinsicWidth(w);
     125        r->setIntrinsicHeight(h);
     126        r->repaint();
     127    }
     128
     129    m_createdDrawingContext = false;
     130    CGContextRelease(m_drawingContext);
     131    m_drawingContext = 0;
     132    fastFree(m_data);
     133    m_data = 0;
     134}
     135
     136void HTMLCanvasElement::paint(GraphicsContext* p, const IntRect& r)
     137{
     138    if (p->paintingDisabled())
     139        return;
    109140#if __APPLE__
    110     if (CGContextRef context = canvasRenderer->drawingContext())
    111         return IntSize(CGBitmapContextGetWidth(context), CGBitmapContextGetHeight(context));
     141    if (CGImageRef image = createPlatformImage()) {
     142        CGContextDrawImage(p->currentCGContext(), r, image);
     143        CGImageRelease(image);
     144    }
    112145#endif
    113     return IntSize();
     146}
     147
     148void HTMLCanvasElement::createDrawingContext() const
     149{
     150    ASSERT(!m_createdDrawingContext);
     151    ASSERT(!m_data);
     152
     153    m_createdDrawingContext = true;
     154
     155    if (width() <= 0 || height() <= 0)
     156        return;
     157    unsigned w = width();
     158    size_t bytesPerRow = w * 4;
     159    if (bytesPerRow / 4 != w) // check for overflow
     160        return;
     161    m_data = fastCalloc(height(), bytesPerRow);
     162    if (!m_data)
     163        return;
     164#if __APPLE__
     165    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
     166    m_drawingContext = CGBitmapContextCreate(m_data, w, height(), 8, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
     167    CGColorSpaceRelease(colorSpace);
     168#endif
    114169}
    115170
    116171#if __APPLE__
    117172
     173CGContextRef HTMLCanvasElement::drawingContext() const
     174{
     175    if (!m_createdDrawingContext)
     176        createDrawingContext();
     177    return m_drawingContext;
     178}
     179
    118180CGImageRef HTMLCanvasElement::createPlatformImage() const
    119181{
    120     RenderHTMLCanvas* canvasRenderer = static_cast<RenderHTMLCanvas*>(renderer());
    121     if (!canvasRenderer)
    122         return 0;
    123     CGContextRef context = canvasRenderer->drawingContext();
     182    CGContextRef context = drawingContext();
    124183    if (!context)
    125184        return 0;
     185    CGContextFlush(context);
    126186    return CGBitmapContextCreateImage(context);
    127187}
  • trunk/WebCore/html/HTMLCanvasElement.h

    r13397 r13748  
    3030
    3131#if __APPLE__
     32// FIXME: Mac-specific parts need to move to the platform directory.
     33typedef struct CGContext* CGContextRef;
    3234typedef struct CGImage* CGImageRef;
    3335#endif
     
    3840typedef CanvasRenderingContext2D CanvasRenderingContext;
    3941
    40 // FIXME: Should inherit from HTMLElement instead of HTMLImageElement.
    41 class HTMLCanvasElement : public HTMLImageElement {
     42class HTMLCanvasElement : public HTMLElement {
    4243public:
    4344    HTMLCanvasElement(Document*);
    44     ~HTMLCanvasElement();
     45    virtual ~HTMLCanvasElement();
     46
     47    int width() const { return m_size.width(); }
     48    int height() const { return m_size.height(); }
     49    void setWidth(int);
     50    void setHeight(int);
    4551
    4652    CanvasRenderingContext* getContext(const String&);
    47 
    4853    // FIXME: Web Applications 1.0 describes a toDataURL function.
    4954
    50     virtual bool mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const;
    5155    virtual void parseMappedAttribute(MappedAttribute*);
     56    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    5257
    53     virtual void attach();
    54     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    55     virtual void detach();
    56    
    57     virtual bool isURLAttribute(Attribute*) const;
     58    IntSize size() const { return m_size; }
     59    void willDraw(const FloatRect&);
    5860
    59     IntSize size() const;
     61    void paint(GraphicsContext*, const IntRect&);
    6062
    6163#if __APPLE__
    6264    CGImageRef createPlatformImage() const;
     65    CGContextRef drawingContext() const;
    6366#endif
    6467
    6568private:
     69    void createDrawingContext() const;
     70    void reset();
     71
    6672    RefPtr<CanvasRenderingContext2D> m_2DContext;
    67     // FIXME: Web Applications 1.0 describes a security feature where we track if we ever drew
    68     // any images outside the domain.
     73    IntSize m_size;
     74
     75    // FIXME: Web Applications 1.0 describes a security feature where we track
     76    // if we ever drew any images outside the domain, so we can disable toDataURL.
     77
     78    mutable bool m_createdDrawingContext;
     79    mutable void* m_data;
     80
     81#if __APPLE__
     82    mutable CGContextRef m_drawingContext;
     83#endif
    6984};
    7085
  • trunk/WebCore/rendering/RenderHTMLCanvas.cpp

    r13592 r13748  
    2424 */
    2525
    26 //#define DEBUG_LAYOUT
    27 
    2826#include "config.h"
    2927#include "RenderHTMLCanvas.h"
    3028
    31 #if __APPLE__
    32 
    33 #include "Document.h"
    3429#include "GraphicsContext.h"
    3530#include "HTMLCanvasElement.h"
     
    4035using namespace HTMLNames;
    4136
    42 RenderHTMLCanvas::RenderHTMLCanvas(Node *_node)
    43     : RenderImage(_node), _drawingContext(0), _drawingContextData(0), _drawnImage(0), _needsImageUpdate(0)
     37RenderHTMLCanvas::RenderHTMLCanvas(Node* n)
     38    : RenderReplaced(n)
    4439{
    4540}
    4641
    47 RenderHTMLCanvas::~RenderHTMLCanvas()
     42const char* RenderHTMLCanvas::renderName() const
    4843{
    49     if (_drawingContext) {
    50         CFRelease (_drawingContext);
    51         _drawingContext = 0;
    52     }
    53    
    54     fastFree(_drawingContextData);
    55     _drawingContextData = 0;
    56    
    57     if (_drawnImage) {
    58         CFRelease (_drawnImage);
    59         _drawnImage = 0;
    60     }
     44    return "RenderHTMLCanvas";
    6145}
    6246
    63 #define BITS_PER_COMPONENT 8
    64 #define BYTES_PER_ROW(width,bitsPerComponent,numComponents) ((width * bitsPerComponent * numComponents + 7)/8)
    65 
    66 void RenderHTMLCanvas::createDrawingContext()
     47void RenderHTMLCanvas::paint(PaintInfo& i, int tx, int ty)
    6748{
    68     if (_drawingContext) {
    69         CFRelease (_drawingContext);
    70         _drawingContext = 0;
    71     }
    72     fastFree(_drawingContextData);
    73     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    74 
    75     int cWidth = contentWidth();
    76     int cHeight = contentHeight();
    77     size_t numComponents = CGColorSpaceGetNumberOfComponents(colorSpace);
    78     size_t bytesPerRow = BYTES_PER_ROW(cWidth,BITS_PER_COMPONENT,(numComponents+1)); // + 1 for alpha
    79     _drawingContextData = fastCalloc(height(), bytesPerRow);
    80     _drawingContext = CGBitmapContextCreate(_drawingContextData, cWidth, cHeight, BITS_PER_COMPONENT, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
    81    
    82 #ifdef DEBUG_CANVAS_BACKGROUND
    83     CGContextSetRGBFillColor(_drawingContext, 1.0, 0., 0., 1.);
    84     CGContextFillRect (_drawingContext, CGRectMake (0, 0, width(), height()));
    85     CGContextFlush (_drawingContext);
    86 #endif
    87    
    88     updateDrawnImage();
    89    
    90     CFRelease (colorSpace);
    91 }
    92 
    93 CGContextRef RenderHTMLCanvas::drawingContext()
    94 {
    95     if (!_drawingContext) {
    96         document()->updateLayout();
    97         createDrawingContext();
    98     }
    99    
    100     return _drawingContext;
    101 }
    102 
    103 void RenderHTMLCanvas::setNeedsImageUpdate()
    104 {
    105     _needsImageUpdate = true;
    106     repaint();
    107 }
    108 
    109 
    110 void RenderHTMLCanvas::updateDrawnImage()
    111 {
    112     if (_drawnImage)
    113         CFRelease (_drawnImage);
    114     CGContextFlush (_drawingContext);
    115     _drawnImage = CGBitmapContextCreateImage (_drawingContext);
    116 }
    117 
    118 CGImageRef RenderHTMLCanvas::drawnImage()
    119 {
    120     return _drawnImage;
    121 }
    122 
    123 void RenderHTMLCanvas::paint(PaintInfo& i, int _tx, int _ty)
    124 {
    125     if (!shouldPaint(i, _tx, _ty))
     49    if (!shouldPaint(i, tx, ty))
    12650        return;
    12751
    128     int x = _tx + m_x;
    129     int y = _ty + m_y;
     52    int x = tx + m_x;
     53    int y = ty + m_y;
    13054
    13155    if (shouldPaintBackgroundOrBorder() && (i.phase == PaintPhaseForeground || i.phase == PaintPhaseSelection))
    13256        paintBoxDecorations(i, x, y);
    13357
    134     GraphicsContext* p = i.p;
    135     if (p->paintingDisabled())
    136         return;
    137    
    13858    if ((i.phase == PaintPhaseOutline || i.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE)
    139         paintOutline(p, x, y, width(), height(), style());
     59        paintOutline(i.p, x, y, width(), height(), style());
    14060   
    14161    if (i.phase != PaintPhaseForeground && i.phase != PaintPhaseSelection)
     
    14565        return;
    14666
    147     bool isPrinting = i.p->printing();
    148     bool drawSelectionTint = (selectionState() != SelectionNone) && !isPrinting;
     67    bool drawSelectionTint = selectionState() != SelectionNone && !i.p->printing();
    14968    if (i.phase == PaintPhaseSelection) {
    15069        if (selectionState() == SelectionNone)
     
    15372    }
    15473
    155     int cWidth = contentWidth();
    156     int cHeight = contentHeight();
    157     int leftBorder = borderLeft();
    158     int topBorder = borderTop();
    159     int leftPad = paddingLeft();
    160     int topPad = paddingTop();
    161 
    162     x += leftBorder + leftPad;
    163     y += topBorder + topPad;
    164    
    165     if (_needsImageUpdate) {
    166         updateDrawnImage();
    167         _needsImageUpdate = false;
    168     }
    169    
    170     if (drawnImage()) {
    171         HTMLCanvasElement* i = (element() && element()->hasTagName(canvasTag)) ? static_cast<HTMLCanvasElement*>(element()) : 0;
    172         int oldOperation = 0;
    173         if (i) {
    174             oldOperation = GraphicsContext::getCompositeOperation(GraphicsContext::currentCGContext());
    175             GraphicsContext::setCompositeOperation(GraphicsContext::currentCGContext(), i->compositeOperator());
    176         }
    177         CGContextDrawImage(GraphicsContext::currentCGContext(), CGRectMake(x, y, cWidth, cHeight), drawnImage());
    178         if (i)
    179             GraphicsContext::setCompositeOperation(GraphicsContext::currentCGContext(), oldOperation);
    180     }
     74    if (element() && element()->hasTagName(canvasTag))
     75        static_cast<HTMLCanvasElement*>(element())->paint(i.p,
     76            IntRect(x + borderLeft() + paddingLeft(), y + borderTop() + paddingTop(), contentWidth(), contentHeight()));
    18177
    18278    if (drawSelectionTint)
    183         p->fillRect(selectionRect(), selectionColor(p));
     79        i.p->fillRect(selectionRect(), selectionColor(i.p));
    18480}
    18581
    18682void RenderHTMLCanvas::layout()
    18783{
    188     KHTMLAssert(needsLayout());
    189     KHTMLAssert(minMaxKnown());
     84    ASSERT(needsLayout());
     85    ASSERT(minMaxKnown());
    19086
    19187    IntRect oldBounds;
     
    19389    if (checkForRepaint)
    19490        oldBounds = getAbsoluteRepaintRect();
    195 
    196     int oldwidth = m_width;
    197     int oldheight = m_height;
    198    
    19991    calcWidth();
    20092    calcHeight();
    201 
    202     if ( m_width != oldwidth || m_height != oldheight ) {
    203         createDrawingContext();
    204     }
    205 
    20693    if (checkForRepaint)
    20794        repaintAfterLayoutIfNeeded(oldBounds, oldBounds);
    208    
     95
    20996    setNeedsLayout(false);
    21097}
    21198
    21299}
    213 
    214 #endif
  • trunk/WebCore/rendering/RenderHTMLCanvas.h

    r13393 r13748  
    2424 */
    2525
    26 #ifndef RENDER_CANVASIMAGE_H
    27 #define RENDER_CANVASIMAGE_H
     26#ifndef RENDERHTMLCANVAS_H
     27#define RENDERHTMLCANVAS_H
    2828
    29 
    30 #include "HTMLElement.h"
    31 #include "RenderImage.h"
    32 
    33 #if __APPLE__
    34 // FIXME: Mac-specific parts need to move to the platform directory.
    35 #include <ApplicationServices/ApplicationServices.h>
    36 #endif
     29#include "render_replaced.h"
    3730
    3831namespace WebCore {
    3932
    40 class DocLoader;
    41 
    42 class RenderHTMLCanvas : public RenderImage
    43 {
    44 public:
    45     RenderHTMLCanvas(Node*);
    46     virtual ~RenderHTMLCanvas();
    47 
    48     virtual const char *renderName() const { return "RenderCanvasImage"; }
    49    
    50     virtual void paint(PaintInfo& i, int tx, int ty);
    51 
    52     virtual void layout();
    53 
    54     void setNeedsImageUpdate();
    55    
    56     // don't even think about making this method virtual!
    57     HTMLElement* element() const
    58         { return static_cast<HTMLElement*>(RenderImage::element()); }
    59    
    60 #if __APPLE__
    61     void updateDrawnImage();
    62     CGContextRef drawingContext();
    63    
    64 private:
    65     void createDrawingContext();
    66     CGImageRef drawnImage();
    67 
    68     CGContextRef _drawingContext;
    69     void *_drawingContextData;
    70     CGImageRef _drawnImage;
    71    
    72     bool _needsImageUpdate : 1;
    73 #endif
    74 };
     33    class RenderHTMLCanvas : public RenderReplaced {
     34    public:
     35        RenderHTMLCanvas(Node*);
     36        virtual const char* renderName() const;
     37        virtual void paint(PaintInfo&, int tx, int ty);
     38        virtual void layout();
     39    };
    7540
    7641} //namespace
Note: See TracChangeset for help on using the changeset viewer.