Home | History | Annotate | Download | only in canvas
      1 /*
      2  * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
      3  * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
      4  * Copyright (C) 2007 Alp Toker <alp (at) atoker.com>
      5  * Copyright (C) 2008 Eric Seidel <eric (at) webkit.org>
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "config.h"
     30 #include "CanvasStyle.h"
     31 
     32 #include "CSSParser.h"
     33 #include "CanvasGradient.h"
     34 #include "CanvasPattern.h"
     35 #include "GraphicsContext.h"
     36 #include <wtf/PassRefPtr.h>
     37 
     38 #if PLATFORM(CG)
     39 #include <CoreGraphics/CGContext.h>
     40 #endif
     41 
     42 #if PLATFORM(QT)
     43 #include <QPainter>
     44 #include <QBrush>
     45 #include <QPen>
     46 #include <QColor>
     47 #endif
     48 
     49 namespace WebCore {
     50 
     51 CanvasStyle::CanvasStyle(const String& color)
     52     : m_type(ColorString)
     53     , m_color(color)
     54 {
     55 }
     56 
     57 CanvasStyle::CanvasStyle(float grayLevel)
     58     : m_type(GrayLevel)
     59     , m_alpha(1)
     60     , m_grayLevel(grayLevel)
     61 {
     62 }
     63 
     64 CanvasStyle::CanvasStyle(const String& color, float alpha)
     65     : m_type(ColorStringWithAlpha)
     66     , m_color(color)
     67     , m_alpha(alpha)
     68 {
     69 }
     70 
     71 CanvasStyle::CanvasStyle(float grayLevel, float alpha)
     72     : m_type(GrayLevel)
     73     , m_alpha(alpha)
     74     , m_grayLevel(grayLevel)
     75 {
     76 }
     77 
     78 CanvasStyle::CanvasStyle(float r, float g, float b, float a)
     79     : m_type(RGBA)
     80     , m_alpha(a)
     81     , m_red(r)
     82     , m_green(g)
     83     , m_blue(b)
     84 {
     85 }
     86 
     87 CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
     88     : m_type(CMYKA)
     89     , m_alpha(a)
     90     , m_cyan(c)
     91     , m_magenta(m)
     92     , m_yellow(y)
     93     , m_black(k)
     94 {
     95 }
     96 
     97 CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
     98     : m_type(gradient ? Gradient : ColorString)
     99     , m_gradient(gradient)
    100 {
    101 }
    102 
    103 CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
    104     : m_type(pattern ? ImagePattern : ColorString)
    105     , m_pattern(pattern)
    106 {
    107 }
    108 
    109 void CanvasStyle::applyStrokeColor(GraphicsContext* context)
    110 {
    111     if (!context)
    112         return;
    113     switch (m_type) {
    114         case ColorString: {
    115             Color c = Color(m_color);
    116             if (c.isValid()) {
    117                 context->setStrokeColor(c.rgb(), DeviceColorSpace);
    118                 break;
    119             }
    120             RGBA32 color = 0; // default is transparent black
    121             if (CSSParser::parseColor(color, m_color))
    122                 context->setStrokeColor(color, DeviceColorSpace);
    123             break;
    124         }
    125         case ColorStringWithAlpha: {
    126             Color c = Color(m_color);
    127             if (c.isValid()) {
    128                 context->setStrokeColor(colorWithOverrideAlpha(c.rgb(), m_alpha), DeviceColorSpace);
    129                 break;
    130             }
    131             RGBA32 color = 0; // default is transparent black
    132             if (CSSParser::parseColor(color, m_color))
    133                 context->setStrokeColor(colorWithOverrideAlpha(color, m_alpha), DeviceColorSpace);
    134             break;
    135         }
    136         case GrayLevel:
    137             // We're only supporting 255 levels of gray here.  Since this isn't
    138             // even part of HTML5, I don't expect anyone will care.  If they do
    139             // we'll make a fancier Color abstraction.
    140             context->setStrokeColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha), DeviceColorSpace);
    141             break;
    142         case RGBA:
    143             context->setStrokeColor(Color(m_red, m_green, m_blue, m_alpha), DeviceColorSpace);
    144             break;
    145         case CMYKA: {
    146             // FIXME: Do this through platform-independent GraphicsContext API.
    147             // We'll need a fancier Color abstraction to support CYMKA correctly
    148 #if PLATFORM(CG)
    149             CGContextSetCMYKStrokeColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
    150 #elif PLATFORM(QT)
    151             QPen currentPen = context->platformContext()->pen();
    152             QColor clr;
    153             clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
    154             currentPen.setColor(clr);
    155             context->platformContext()->setPen(currentPen);
    156 #else
    157             context->setStrokeColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha), DeviceColorSpace);
    158 #endif
    159             break;
    160         }
    161         case Gradient:
    162             context->setStrokeGradient(canvasGradient()->gradient());
    163             break;
    164         case ImagePattern:
    165             context->setStrokePattern(canvasPattern()->pattern());
    166             break;
    167     }
    168 }
    169 
    170 void CanvasStyle::applyFillColor(GraphicsContext* context)
    171 {
    172     if (!context)
    173         return;
    174     switch (m_type) {
    175         case ColorString: {
    176             Color c = Color(m_color);
    177             if (c.isValid()) {
    178                 context->setFillColor(c.rgb(), DeviceColorSpace);
    179                 break;
    180             }
    181             RGBA32 rgba = 0; // default is transparent black
    182             if (CSSParser::parseColor(rgba, m_color))
    183                 context->setFillColor(rgba, DeviceColorSpace);
    184             break;
    185         }
    186         case ColorStringWithAlpha: {
    187             Color c = Color(m_color);
    188             if (c.isValid()) {
    189                 context->setFillColor(colorWithOverrideAlpha(c.rgb(), m_alpha), DeviceColorSpace);
    190                 break;
    191             }
    192             RGBA32 color = 0; // default is transparent black
    193             if (CSSParser::parseColor(color, m_color))
    194                 context->setFillColor(colorWithOverrideAlpha(color, m_alpha), DeviceColorSpace);
    195             break;
    196         }
    197         case GrayLevel:
    198             // We're only supporting 255 levels of gray here.  Since this isn't
    199             // even part of HTML5, I don't expect anyone will care.  If they do
    200             // we'll make a fancier Color abstraction.
    201             context->setFillColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha), DeviceColorSpace);
    202             break;
    203         case RGBA:
    204             context->setFillColor(Color(m_red, m_green, m_blue, m_alpha), DeviceColorSpace);
    205             break;
    206         case CMYKA: {
    207             // FIXME: Do this through platform-independent GraphicsContext API.
    208             // We'll need a fancier Color abstraction to support CYMKA correctly
    209 #if PLATFORM(CG)
    210             CGContextSetCMYKFillColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
    211 #elif PLATFORM(QT)
    212             QBrush currentBrush = context->platformContext()->brush();
    213             QColor clr;
    214             clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
    215             currentBrush.setColor(clr);
    216             context->platformContext()->setBrush(currentBrush);
    217 #else
    218             context->setFillColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha), DeviceColorSpace);
    219 #endif
    220             break;
    221         }
    222         case Gradient:
    223             context->setFillGradient(canvasGradient()->gradient());
    224             break;
    225         case ImagePattern:
    226             context->setFillPattern(canvasPattern()->pattern());
    227             break;
    228     }
    229 }
    230 
    231 }
    232