Changeset 30056 in webkit


Ignore:
Timestamp:
Feb 6, 2008 5:52:05 PM (16 years ago)
Author:
mrowe@apple.com
Message:

2008-02-06 Brent Fulgham <bfulgham@gmail.com>

Reviewed by Adam Roben.

http://bugs.webkit.org/show_bug.cgi?id=16979
Conditionalize CoreGraphics vs Cairo support in Windows port.

Location:
trunk/WebCore
Files:
6 added
11 edited
7 copied
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r30055 r30056  
     12008-02-06  Brent Fulgham  <bfulgham@gmail.com>
     2
     3        Reviewed by Adam Roben.
     4
     5        http://bugs.webkit.org/show_bug.cgi?id=16979
     6        Conditionalize CoreGraphics vs Cairo support in Windows port.
     7
     8        * WebCore.vcproj/WebCore.vcproj:
     9        * bridge/win/FrameCGWin.cpp: Copied from WebCore/bridge/win/FrameWin.cpp.
     10        (WebCore::imageFromSelection):
     11        * bridge/win/FrameCairoWin.cpp: Added.
     12        (WebCore::imageFromSelection):
     13        * bridge/win/FrameWin.cpp:
     14        (WebCore::computePageRectsForFrame):
     15        * platform/graphics/SimpleFontData.h:
     16        * platform/graphics/cairo/GraphicsContextCairo.cpp:
     17        * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Copied from WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp.
     18        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
     19        (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate):
     20        (WebCore::GraphicsContextPlatformPrivate::beginTransparencyLayer):
     21        (WebCore::GraphicsContextPlatformPrivate::endTransparencyLayer):
     22        * platform/graphics/cg/GraphicsContextCG.cpp:
     23        (WebCore::GraphicsContext::savePlatformState):
     24        (WebCore::GraphicsContext::restorePlatformState):
     25        * platform/graphics/cg/GraphicsContextPlatformPrivate.h: Removed.
     26        * platform/graphics/cg/GraphicsContextPlatformPrivateCG.h: Copied from WebCore/platform/graphics/cg/GraphicsContextPlatformPrivate.h.
     27        * platform/graphics/win/FontCGWin.cpp: Copied from WebCore/platform/graphics/win/FontWin.cpp.
     28        (WebCore::Font::drawGlyphs):
     29        * platform/graphics/win/FontCairoWin.cpp: Added.
     30        (WebCore::Font::drawGlyphs):
     31        * platform/graphics/win/FontWin.cpp:
     32        * platform/graphics/win/GraphicsContextCGWin.cpp: Copied from WebCore/platform/graphics/win/GraphicsContextWin.cpp.
     33        (WebCore::CGContextWithHDC):
     34        (WebCore::GraphicsContext::inTransparencyLayer):
     35        (WebCore::GraphicsContext::getWindowsContext):
     36        (WebCore::GraphicsContext::releaseWindowsContext):
     37        (WebCore::GraphicsContextPlatformPrivate::scale):
     38        (WebCore::GraphicsContextPlatformPrivate::rotate):
     39        (WebCore::GraphicsContextPlatformPrivate::translate):
     40        (WebCore::GraphicsContextPlatformPrivate::concatCTM):
     41        (WebCore::setCGStrokeColor):
     42        (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
     43        * platform/graphics/win/GraphicsContextCairoWin.cpp: Added.
     44        (WebCore::GraphicsContext::GraphicsContext):
     45        (WebCore::GraphicsContext::getWindowsContext):
     46        (WebCore::GraphicsContext::inTransparencyLayer):
     47        (WebCore::GraphicsContext::releaseWindowsContext):
     48        (WebCore::GraphicsContext::concatCTM):
     49        * platform/graphics/win/GraphicsContextWin.cpp:
     50        * platform/graphics/win/ImageCGWin.cpp: Copied from WebCore/platform/graphics/win/ImageWin.cpp.
     51        (WebCore::BitmapImage::getHBITMAPOfSize):
     52        (WebCore::BitmapImage::drawFrameMatchingSourceSize):
     53        * platform/graphics/win/ImageCairoWin.cpp: Added.
     54        (WebCore::BitmapImage::getHBITMAPOfSize):
     55        (WebCore::BitmapImage::drawFrameMatchingSourceSize):
     56        * platform/graphics/win/ImageWin.cpp:
     57        * platform/graphics/win/SimpleFontDataCGWin.cpp: Copied from WebCore/platform/graphics/win/SimpleFontDataWin.cpp.
     58        (WebCore::scaleEmToUnits):
     59        (WebCore::SimpleFontData::platformInit):
     60        (WebCore::SimpleFontData::platformWidthForGlyph):
     61        * platform/graphics/win/SimpleFontDataCairoWin.cpp: Added.
     62        (WebCore::SimpleFontData::platformInit):
     63        (WebCore::SimpleFontData::platformDestroy):
     64        (WebCore::SimpleFontData::platformWidthForGlyph):
     65        * platform/graphics/win/SimpleFontDataWin.cpp:
     66        (WebCore::SimpleFontData::setShouldApplyMacAscentHack):
     67        (WebCore::SimpleFontData::shouldApplyMacAscentHack):
     68        * platform/win/DragImageCGWin.cpp: Copied from WebCore/platform/win/DragImageWin.cpp.
     69        (WebCore::scaleDragImage):
     70        (WebCore::createDragImageFromImage):
     71        * platform/win/DragImageCairoWin.cpp: Added.
     72        (WebCore::scaleDragImage):
     73        (WebCore::createDragImageFromImage):
     74        * platform/win/DragImageWin.cpp:
     75
    1762008-02-06  Anders Carlsson  <andersca@apple.com>
    277
  • trunk/WebCore/WebCore.vcproj/WebCore.vcproj

    r30035 r30056  
    34183418                                        >
    34193419                                </File>
     3420                                        RelativePath="..\platform\win\DragImageCGWin.cpp"
     3421                                        >
     3422                                </File>
    34203423                                <File
    34213424                                        RelativePath="..\platform\win\DragImageWin.cpp"
     
    38743877                                        <File
    38753878                                                RelativePath="..\platform\graphics\win\FontCacheWin.cpp"
     3879                                                >
     3880                                        </File>
     3881                                        <File
     3882                                                RelativePath="..\platform\graphics\win\FontCGWin.cpp"
    38763883                                                >
    38773884                                        </File>
     
    39333940                                        </File>
    39343941                                        <File
     3942                                                RelativePath="..\platform\graphics\win\GraphicsContextCGWin.cpp"
     3943                                                >
     3944                                        </File>
     3945                                        <File
    39353946                                                RelativePath="..\platform\graphics\win\GraphicsContextWin.cpp"
    39363947                                                >
     
    39413952                                        </File>
    39423953                                        <File
     3954                                                RelativePath="..\platform\graphics\win\ImageCGWin.cpp"
     3955                                                >
     3956                                        </File>
     3957                                        <File
    39433958                                                RelativePath="..\platform\graphics\win\ImageWin.cpp"
    39443959                                                >
     
    39623977                                        <File
    39633978                                                RelativePath="..\platform\graphics\win\MediaPlayerPrivateQuickTimeWin.h"
     3979                                                >
     3980                                        </File>
     3981                                        <File
     3982                                                RelativePath="..\platform\graphics\win\SimpleFontDataCGWin.cpp"
    39643983                                                >
    39653984                                        </File>
     
    64086427                                Name="win"
    64096428                                >
     6429                                <File
     6430                                        RelativePath="..\bridge\win\FrameCGWin.cpp"
     6431                                        >
     6432                                </File>
    64106433                                <File
    64116434                                        RelativePath="..\bridge\win\FrameWin.cpp"
  • trunk/WebCore/bridge/win/FrameCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "FrameWin.h"
    2828
    29 #include <winsock2.h>
    3029#include <windows.h>
    3130
    32 #include "AffineTransform.h"
    33 #include "FloatRect.h"
    34 #include "Document.h"
    35 #include "EditorClient.h"
    36 #include "FrameLoader.h"
    37 #include "FrameLoadRequest.h"
    38 #include "FramePrivate.h"
    3931#include "FrameView.h"
    40 #include "HTMLIFrameElement.h"
    41 #include "HTMLNames.h"
    42 #include "HTMLTableCellElement.h"
    43 #include "KeyboardEvent.h"
    44 #include "NP_jsobject.h"
    45 #include "NotImplemented.h"
    46 #include "Page.h"
    47 #include "Plugin.h"
    48 #include "PluginDatabase.h"
    49 #include "PluginView.h"
    50 #include "RegularExpression.h"
    51 #include "RenderFrame.h"
    52 #include "RenderTableCell.h"
    53 #include "RenderView.h"
    54 #include "ResourceHandle.h"
    55 #include "TextResourceDecoder.h"
    56 #include "kjs_proxy.h"
    57 #include "kjs_window.h"
    58 #include "npruntime_impl.h"
    59 #include "runtime_root.h"
    6032#include "GraphicsContext.h"
    6133#include "Settings.h"
    6234
    63 #if PLATFORM(CG)
    6435#include <CoreGraphics/CoreGraphics.h>
    65 #endif
    6636
    6737using std::min;
    68 using namespace KJS::Bindings;
    6938
    7039namespace WebCore {
    71 
    72 using namespace HTMLNames;
    73 
    74 void Frame::clearPlatformScriptObjects()
    75 {
    76 }
    77 
    78 KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(Widget* widget)
    79 {
    80     // FIXME: Ideally we'd have an isPluginView() here but we can't add that to the open source tree right now.
    81     if (widget->isFrameView())
    82         return 0;
    83 
    84     return static_cast<PluginView*>(widget)->bindingInstance();
    85 }
    86 
    87 
    88 void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight)
    89 {
    90     ASSERT(frame);
    91 
    92     pages.clear();
    93     outPageHeight = 0;
    94 
    95     if (!frame->document() || !frame->view() || !frame->document()->renderer())
    96         return;
    97  
    98     RenderView* root = static_cast<RenderView *>(frame->document()->renderer());
    99 
    100     if (!root) {
    101         LOG_ERROR("document to be printed has no renderer");
    102         return;
    103     }
    104 
    105     if (userScaleFactor <= 0) {
    106         LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);
    107         return;
    108     }
    109    
    110     float ratio = (float)printRect.height() / (float)printRect.width();
    111  
    112     float pageWidth  = (float) root->docWidth();
    113     float pageHeight = pageWidth * ratio;
    114     outPageHeight = (int) pageHeight;   // this is the height of the page adjusted by margins
    115     pageHeight -= (headerHeight + footerHeight);
    116 
    117     if (pageHeight <= 0) {
    118         LOG_ERROR("pageHeight has bad value %.2f", pageHeight);
    119         return;
    120     }
    121 
    122     float currPageHeight = pageHeight / userScaleFactor;
    123     float docHeight      = root->layer()->height();
    124     float docWidth       = root->layer()->width();
    125     float currPageWidth  = pageWidth / userScaleFactor;
    126 
    127    
    128     // always return at least one page, since empty files should print a blank page
    129     float printedPagesHeight = 0.0;
    130     do {
    131         float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
    132         frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
    133         currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
    134        
    135         pages.append(IntRect(0,printedPagesHeight,currPageWidth,currPageHeight));
    136         printedPagesHeight += currPageHeight;
    137     } while (printedPagesHeight < docHeight);
    138 }
    13940
    14041static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc)
     
    15354    frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
    15455    FloatRect fr = frame->selectionRect();
    155     IntRect ir((int)fr.x(), (int)fr.y(),(int)fr.width(),(int)fr.height());
     56    IntRect ir(static_cast<int>(fr.x()), static_cast<int>(fr.y()),
     57               static_cast<int>(fr.width()), static_cast<int>(fr.height()));
    15658
    15759    void* bits;
     
    16163    BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } };
    16264
    163     HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, (void**)&bits, 0, 0);
    164     HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, hbmp);
     65    HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
     66    HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
    16567    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    166     CGContextRef context = CGBitmapContextCreate((void*)bits, w, h,
     68    CGContextRef context = CGBitmapContextCreate(static_cast<void*>(bits), w, h,
    16769        8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    16870    CGColorSpaceRelease(deviceRGB);
     
    18385}
    18486
    185 DragImageRef Frame::dragImageForSelection()
    186 {   
    187     if (selectionController()->isRange())
    188         return imageFromSelection(this, false);
    189 
    190     return 0;
    191 }
    192 
    193 void Frame::dashboardRegionsChanged()
    194 {
    195 }
    196 
    19787} // namespace WebCore
  • trunk/WebCore/bridge/win/FrameWin.cpp

    r30015 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6161#include "Settings.h"
    6262
    63 #if PLATFORM(CG)
    64 #include <CoreGraphics/CoreGraphics.h>
    65 #endif
    66 
    6763using std::min;
    6864using namespace KJS::Bindings;
     
    8480    return static_cast<PluginView*>(widget)->bindingInstance();
    8581}
    86 
    8782
    8883void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight)
     
    108103    }
    109104   
    110     float ratio = (float)printRect.height() / (float)printRect.width();
     105    float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
    111106 
    112     float pageWidth  = (float) root->docWidth();
     107    float pageWidth  = static_cast<float>(root->docWidth());
    113108    float pageHeight = pageWidth * ratio;
    114     outPageHeight = (int) pageHeight;   // this is the height of the page adjusted by margins
     109    outPageHeight = static_cast<int>(pageHeight);   // this is the height of the page adjusted by margins
    115110    pageHeight -= (headerHeight + footerHeight);
    116111
     
    127122   
    128123    // always return at least one page, since empty files should print a blank page
    129     float printedPagesHeight = 0.0;
     124    float printedPagesHeight = 0.0f;
    130125    do {
    131126        float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
     
    133128        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
    134129       
    135         pages.append(IntRect(0,printedPagesHeight,currPageWidth,currPageHeight));
     130        pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
    136131        printedPagesHeight += currPageHeight;
    137132    } while (printedPagesHeight < docHeight);
    138 }
    139 
    140 static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc)
    141 {
    142     IntSize offset = view->scrollOffset();
    143     rect.move(-offset.width(), -offset.height());
    144     rect = view->convertToContainingWindow(rect);
    145 
    146     gc->concatCTM(AffineTransform().translate(-rect.x(), -rect.y()));
    147 
    148     view->paint(gc, rect);
    149 }
    150 
    151 HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
    152 {
    153     frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
    154     FloatRect fr = frame->selectionRect();
    155     IntRect ir((int)fr.x(), (int)fr.y(),(int)fr.width(),(int)fr.height());
    156 
    157     void* bits;
    158     HDC hdc = CreateCompatibleDC(0);
    159     int w = ir.width();
    160     int h = ir.height();
    161     BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } };
    162 
    163     HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, (void**)&bits, 0, 0);
    164     HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, hbmp);
    165     CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    166     CGContextRef context = CGBitmapContextCreate((void*)bits, w, h,
    167         8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    168     CGColorSpaceRelease(deviceRGB);
    169     CGContextSaveGState(context);
    170 
    171     GraphicsContext gc(context);
    172 
    173     frame->document()->updateLayout();
    174     drawRectIntoContext(ir, frame->view(), &gc);
    175 
    176     CGContextRelease(context);
    177     SelectObject(hdc, hbmpOld);
    178     DeleteDC(hdc);
    179 
    180     frame->setPaintRestriction(PaintRestrictionNone);
    181 
    182     return hbmp;
    183133}
    184134
  • trunk/WebCore/platform/graphics/SimpleFontData.h

    r29940 r30056  
    104104
    105105    static void setShouldApplyMacAscentHack(bool);
     106    static bool shouldApplyMacAscentHack();
    106107#endif
    107108
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

    r29961 r30056  
    4343#include <wtf/MathExtras.h>
    4444
    45 #if PLATFORM(WIN)
    46 #include <cairo-win32.h>
    47 #endif
    48 
    4945#if PLATFORM(GTK)
    5046#include <gdk/gdk.h>
    5147#include <pango/pango.h>
     48#elif PLATFORM(WIN)
     49#include <cairo-win32.h>
    5250#endif
    53 
     51#include "GraphicsContextPlatformPrivateCairo.h"
    5452
    5553#ifndef M_PI
     
    5856
    5957namespace WebCore {
    60 
    61 class GraphicsContextPlatformPrivate {
    62 public:
    63     GraphicsContextPlatformPrivate();
    64     ~GraphicsContextPlatformPrivate();
    65 
    66     cairo_t* cr;
    67     Vector<float> layers;
    68 
    69 #if PLATFORM(GTK)
    70     GdkEventExpose* expose;
    71 #endif
    72 };
    7358
    7459static inline void setColor(cairo_t* cr, const Color& col)
     
    8772    cairo_fill(cr);
    8873}
    89 
    90 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
    91     :  cr(0)
    92 #if PLATFORM(GTK)
    93     , expose(0)
    94 #endif
    95 {
    96 }
    97 
    98 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
    99 {
    100     cairo_destroy(cr);
    101 }
    102 
    103 #if PLATFORM(WIN)
    104 GraphicsContext::GraphicsContext(HDC dc)
    105     : m_common(createGraphicsContextPrivate())
    106     , m_data(new GraphicsContextPlatformPrivate)
    107 {
    108     if (dc) {
    109         cairo_surface_t* surface = cairo_win32_surface_create(dc);
    110         m_data->cr = cairo_create(surface);
    111     } else {
    112         setPaintingDisabled(true);
    113         m_data->cr = 0;
    114     }
    115 }
    116 #endif
    11774
    11875GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
     
    587544}
    588545
     546#if PLATFORM(GTK)
     547// FIXME:  This should be moved to something like GraphicsContextCairoGTK.cpp,
     548// as there is a Windows implementation in platform/graphics/win/GraphicsContextCairoWin.cpp
    589549void GraphicsContext::concatCTM(const AffineTransform& transform)
    590550{
     
    596556    cairo_transform(cr, matrix);
    597557}
     558#endif
    598559
    599560void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h

    r30053 r30056  
    22 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
    33 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
     4 * Copyright (C) 2008 Brent Fulgham <bfulgham@gmail.com>
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    2223 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    2324 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
    2526 */
    2627
    27 #include "config.h"
    2828#include "GraphicsContext.h"
    2929
    30 #if PLATFORM(CAIRO)
    31 
    32 #include "AffineTransform.h"
    33 #include "CairoPath.h"
    34 #include "FloatRect.h"
    35 #include "Font.h"
    36 #include "IntRect.h"
    37 #include "NotImplemented.h"
    38 #include "Path.h"
    39 #include "SimpleFontData.h"
    4030#include <cairo.h>
    4131#include <math.h>
     
    4333#include <wtf/MathExtras.h>
    4434
    45 #if PLATFORM(WIN)
    46 #include <cairo-win32.h>
    47 #endif
    48 
    4935#if PLATFORM(GTK)
    5036#include <gdk/gdk.h>
    5137#include <pango/pango.h>
    52 #endif
    53 
    54 
    55 #ifndef M_PI
    56 #define M_PI 3.14159265358979323846
     38#elif PLATFORM(WIN)
     39#include <cairo-win32.h>
    5740#endif
    5841
     
    6144class GraphicsContextPlatformPrivate {
    6245public:
    63     GraphicsContextPlatformPrivate();
    64     ~GraphicsContextPlatformPrivate();
     46    GraphicsContextPlatformPrivate()
     47        :  cr(0)
     48#if PLATFORM(GTK)
     49        , expose(0)
     50#elif PLATFORM(WIN)
     51        // NOTE:  These may note be needed: review and remove once Cairo implementation is complete
     52        , m_hdc(0)
     53        , m_transparencyCount(0)
     54#endif
     55    {
     56    }
     57
     58    ~GraphicsContextPlatformPrivate()
     59    {
     60        cairo_destroy(cr);
     61    }
     62
     63#if PLATFORM(WIN)
     64    // On Windows, we need to update the HDC for form controls to draw in the right place.
     65    void beginTransparencyLayer() { m_transparencyCount++; }
     66    void endTransparencyLayer() { m_transparencyCount--; }
     67#endif
    6568
    6669    cairo_t* cr;
     
    6972#if PLATFORM(GTK)
    7073    GdkEventExpose* expose;
     74#elif PLATFORM(WIN)
     75    HDC m_hdc;
     76    unsigned m_transparencyCount;
    7177#endif
    7278};
    7379
    74 static inline void setColor(cairo_t* cr, const Color& col)
    75 {
    76     float red, green, blue, alpha;
    77     col.getRGBA(red, green, blue, alpha);
    78     cairo_set_source_rgba(cr, red, green, blue, alpha);
    79 }
    80 
    81 // A fillRect helper
    82 static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const Color& col)
    83 {
    84     setColor(cr, col);
    85     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    86     cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
    87     cairo_fill(cr);
    88 }
    89 
    90 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
    91     :  cr(0)
    92 #if PLATFORM(GTK)
    93     , expose(0)
    94 #endif
    95 {
    96 }
    97 
    98 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
    99 {
    100     cairo_destroy(cr);
    101 }
    102 
    103 #if PLATFORM(WIN)
    104 GraphicsContext::GraphicsContext(HDC dc)
    105     : m_common(createGraphicsContextPrivate())
    106     , m_data(new GraphicsContextPlatformPrivate)
    107 {
    108     if (dc) {
    109         cairo_surface_t* surface = cairo_win32_surface_create(dc);
    110         m_data->cr = cairo_create(surface);
    111     } else {
    112         setPaintingDisabled(true);
    113         m_data->cr = 0;
    114     }
    115 }
    116 #endif
    117 
    118 GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
    119     : m_common(createGraphicsContextPrivate())
    120     , m_data(new GraphicsContextPlatformPrivate)
    121 {
    122     m_data->cr = cairo_reference(cr);
    123     setPaintingDisabled(!cr);
    124 }
    125 
    126 GraphicsContext::~GraphicsContext()
    127 {
    128     destroyGraphicsContextPrivate(m_common);
    129     delete m_data;
    130 }
    131 
    132 AffineTransform GraphicsContext::getCTM() const
    133 {
    134     cairo_t* cr = platformContext();
    135     cairo_matrix_t m;
    136     cairo_get_matrix(cr, &m);
    137     return m;
    138 }
    139 
    140 cairo_t* GraphicsContext::platformContext() const
    141 {
    142     return m_data->cr;
    143 }
    144 
    145 void GraphicsContext::savePlatformState()
    146 {
    147     cairo_save(m_data->cr);
    148 }
    149 
    150 void GraphicsContext::restorePlatformState()
    151 {
    152     cairo_restore(m_data->cr);
    153 }
    154 
    155 // Draws a filled rectangle with a stroked border.
    156 void GraphicsContext::drawRect(const IntRect& rect)
    157 {
    158     if (paintingDisabled())
    159         return;
    160 
    161     cairo_t* cr = m_data->cr;
    162     cairo_save(cr);
    163 
    164     if (fillColor().alpha())
    165         fillRectSourceOver(cr, rect, fillColor());
    166 
    167     if (strokeStyle() != NoStroke) {
    168         setColor(cr, strokeColor());
    169         FloatRect r(rect);
    170         r.inflate(-.5f);
    171         cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
    172         cairo_set_line_width(cr, 1.0);
    173         cairo_stroke(cr);
    174     }
    175 
    176     cairo_restore(cr);
    177 }
    178 
    179 // FIXME: Now that this is refactored, it should be shared by all contexts.
    180 static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style)
    181 {
    182     // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
    183     // works out.  For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
    184     // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
    185     // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
    186     if (style == DottedStroke || style == DashedStroke) {
    187         if (p1.x() == p2.x()) {
    188             p1.setY(p1.y() + strokeWidth);
    189             p2.setY(p2.y() - strokeWidth);
    190         }
    191         else {
    192             p1.setX(p1.x() + strokeWidth);
    193             p2.setX(p2.x() - strokeWidth);
    194         }
    195     }
    196 
    197     if (static_cast<int>(strokeWidth) % 2) {
    198         if (p1.x() == p2.x()) {
    199             // We're a vertical line.  Adjust our x.
    200             p1.setX(p1.x() + 0.5);
    201             p2.setX(p2.x() + 0.5);
    202         }
    203         else {
    204             // We're a horizontal line. Adjust our y.
    205             p1.setY(p1.y() + 0.5);
    206             p2.setY(p2.y() + 0.5);
    207         }
    208     }
    209 }
    210 
    211 // This is only used to draw borders.
    212 void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
    213 {
    214     if (paintingDisabled())
    215         return;
    216 
    217     StrokeStyle style = strokeStyle();
    218     if (style == NoStroke)
    219         return;
    220 
    221     cairo_t* cr = m_data->cr;
    222     cairo_save(cr);
    223 
    224     float width = strokeThickness();
    225     if (width < 1)
    226         width = 1;
    227 
    228     FloatPoint p1 = point1;
    229     FloatPoint p2 = point2;
    230     bool isVerticalLine = (p1.x() == p2.x());
    231 
    232     adjustLineToPixelBoundaries(p1, p2, width, style);
    233     cairo_set_line_width(cr, width);
    234 
    235     int patWidth = 0;
    236     switch (style) {
    237     case NoStroke:
    238     case SolidStroke:
    239         break;
    240     case DottedStroke:
    241         patWidth = static_cast<int>(width);
    242         break;
    243     case DashedStroke:
    244         patWidth = 3*static_cast<int>(width);
    245         break;
    246     }
    247 
    248     setColor(cr, strokeColor());
    249 
    250     cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
    251 
    252     if (patWidth) {
    253         // Do a rect fill of our endpoints.  This ensures we always have the
    254         // appearance of being a border.  We then draw the actual dotted/dashed line.
    255         if (isVerticalLine) {
    256             fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
    257             fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
    258         } else {
    259             fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
    260             fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
    261         }
    262 
    263         // Example: 80 pixels with a width of 30 pixels.
    264         // Remainder is 20.  The maximum pixels of line we could paint
    265         // will be 50 pixels.
    266         int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
    267         int remainder = distance%patWidth;
    268         int coverage = distance-remainder;
    269         int numSegments = coverage/patWidth;
    270 
    271         float patternOffset = 0;
    272         // Special case 1px dotted borders for speed.
    273         if (patWidth == 1)
    274             patternOffset = 1.0;
    275         else {
    276             bool evenNumberOfSegments = numSegments%2 == 0;
    277             if (remainder)
    278                 evenNumberOfSegments = !evenNumberOfSegments;
    279             if (evenNumberOfSegments) {
    280                 if (remainder) {
    281                     patternOffset += patWidth - remainder;
    282                     patternOffset += remainder/2;
    283                 }
    284                 else
    285                     patternOffset = patWidth/2;
    286             }
    287             else if (!evenNumberOfSegments) {
    288                 if (remainder)
    289                     patternOffset = (patWidth - remainder)/2;
    290             }
    291         }
    292 
    293         double dash = patWidth;
    294         cairo_set_dash(cr, &dash, 1, patternOffset);
    295     }
    296 
    297     cairo_move_to(cr, p1.x(), p1.y());
    298     cairo_line_to(cr, p2.x(), p2.y());
    299 
    300     cairo_stroke(cr);
    301     cairo_restore(cr);
    302 }
    303 
    304 // This method is only used to draw the little circles used in lists.
    305 void GraphicsContext::drawEllipse(const IntRect& rect)
    306 {
    307     if (paintingDisabled())
    308         return;
    309 
    310     cairo_t* cr = m_data->cr;
    311     cairo_save(cr);
    312     float yRadius = .5 * rect.height();
    313     float xRadius = .5 * rect.width();
    314     cairo_translate(cr, rect.x() + xRadius, rect.y() + yRadius);
    315     cairo_scale(cr, xRadius, yRadius);
    316     cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI);
    317     cairo_restore(cr);
    318 
    319     if (fillColor().alpha()) {
    320         setColor(cr, fillColor());
    321         cairo_fill_preserve(cr);
    322     }
    323 
    324     if (strokeStyle() != NoStroke) {
    325         setColor(cr, strokeColor());
    326         cairo_set_line_width(cr, strokeThickness());
    327         cairo_stroke(cr);
    328     }
    329 
    330     cairo_new_path(cr);
    331 }
    332 
    333 // FIXME: This function needs to be adjusted to match the functionality on the Mac side.
    334 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
    335 {
    336     if (paintingDisabled())
    337         return;
    338 
    339     if (strokeStyle() == NoStroke)
    340         return;
    341 
    342     int x = rect.x();
    343     int y = rect.y();
    344     float w = rect.width();
    345 #if 0 // FIXME: unused so far
    346     float h = rect.height();
    347     float scaleFactor = h / w;
    348     float reverseScaleFactor = w / h;
    349 #endif
    350     float r = w / 2;
    351     float fa = startAngle;
    352     float falen =  fa + angleSpan;
    353 
    354     cairo_t* cr = m_data->cr;
    355     cairo_save(cr);
    356     cairo_arc_negative(cr, x + r, y + r, r, -fa * M_PI/180, -falen * M_PI/180);
    357     setColor(cr, strokeColor());
    358     cairo_set_line_width(cr, strokeThickness());
    359     cairo_stroke(cr);
    360     cairo_restore(cr);
    361 }
    362 
    363 void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
    364 {
    365     if (paintingDisabled())
    366         return;
    367 
    368     if (npoints <= 1)
    369         return;
    370 
    371     cairo_t* cr = m_data->cr;
    372 
    373     cairo_save(cr);
    374     cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
    375     cairo_move_to(cr, points[0].x(), points[0].y());
    376     for (size_t i = 1; i < npoints; i++)
    377         cairo_line_to(cr, points[i].x(), points[i].y());
    378     cairo_close_path(cr);
    379 
    380     if (fillColor().alpha()) {
    381         setColor(cr, fillColor());
    382         cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
    383         cairo_fill_preserve(cr);
    384     }
    385 
    386     if (strokeStyle() != NoStroke) {
    387         setColor(cr, strokeColor());
    388         cairo_set_line_width(cr, strokeThickness());
    389         cairo_stroke(cr);
    390     }
    391 
    392     cairo_new_path(cr);
    393     cairo_restore(cr);
    394 }
    395 
    396 void GraphicsContext::fillRect(const IntRect& rect, const Color& color)
    397 {
    398     if (paintingDisabled())
    399         return;
    400 
    401     if (color.alpha())
    402         fillRectSourceOver(m_data->cr, rect, color);
    403 }
    404 
    405 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
    406 {
    407     if (paintingDisabled())
    408         return;
    409 
    410     if (color.alpha())
    411         fillRectSourceOver(m_data->cr, rect, color);
    412 }
    413 
    414 void GraphicsContext::clip(const IntRect& rect)
    415 {
    416     if (paintingDisabled())
    417         return;
    418 
    419     cairo_t* cr = m_data->cr;
    420     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    421     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    422     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
    423     cairo_clip(cr);
    424     cairo_set_fill_rule(cr, savedFillRule);
    425 }
    426 
    427 void GraphicsContext::drawFocusRing(const Color& color)
    428 {
    429     if (paintingDisabled())
    430         return;
    431 
    432     int radius = (focusRingWidth() - 1) / 2;
    433     int offset = radius + focusRingOffset();
    434 
    435     const Vector<IntRect>& rects = focusRingRects();
    436     unsigned rectCount = rects.size();
    437     IntRect finalFocusRect;
    438     for (unsigned i = 0; i < rectCount; i++) {
    439         IntRect focusRect = rects[i];
    440         focusRect.inflate(offset);
    441         finalFocusRect.unite(focusRect);
    442     }
    443 
    444     cairo_t* cr = m_data->cr;
    445     cairo_save(cr);
    446     // FIXME: These rects should be rounded
    447     cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height());
    448 
    449     // Force the alpha to 50%.  This matches what the Mac does with outline rings.
    450     Color ringColor(color.red(), color.green(), color.blue(), 127);
    451     setColor(cr, ringColor);
    452     cairo_stroke(cr);
    453     cairo_restore(cr);
    454 }
    455 
    456 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
    457 {
    458     if (paintingDisabled())
    459         return;
    460 
    461     // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659
    462     StrokeStyle savedStrokeStyle = strokeStyle();
    463     setStrokeStyle(SolidStroke);
    464 
    465     IntPoint endPoint = origin + IntSize(width, 0);
    466     drawLine(origin, endPoint);
    467 
    468     setStrokeStyle(savedStrokeStyle);
    469 }
    470 
    471 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
    472 {
    473     if (paintingDisabled())
    474         return;
    475 
    476 #if PLATFORM(GTK)
    477     cairo_t* cr = m_data->cr;
    478     cairo_save(cr);
    479 
    480     // Convention is green for grammar, red for spelling
    481     // These need to become configurable
    482     if (grammar)
    483         cairo_set_source_rgb(cr, 0, 1, 0);
    484     else
    485         cairo_set_source_rgb(cr, 1, 0, 0);
    486 
    487     // We ignore most of the provided constants in favour of the platform style
    488     pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
    489 
    490     cairo_restore(cr);
    491 #else
    492     notImplemented();
    493 #endif
    494 }
    495 
    496 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
    497 {
    498     FloatRect result;
    499     double x = frect.x();
    500     double y = frect.y();
    501     cairo_t* cr = m_data->cr;
    502     cairo_user_to_device(cr, &x, &y);
    503     x = round(x);
    504     y = round(y);
    505     cairo_device_to_user(cr, &x, &y);
    506     result.setX(static_cast<float>(x));
    507     result.setY(static_cast<float>(y));
    508     x = frect.width();
    509     y = frect.height();
    510     cairo_user_to_device_distance(cr, &x, &y);
    511     x = round(x);
    512     y = round(y);
    513     cairo_device_to_user_distance(cr, &x, &y);
    514     result.setWidth(static_cast<float>(x));
    515     result.setHeight(static_cast<float>(y));
    516     return result;
    517 }
    518 
    519 void GraphicsContext::translate(float x, float y)
    520 {
    521     if (paintingDisabled())
    522         return;
    523 
    524     cairo_t* cr = m_data->cr;
    525     cairo_translate(cr, x, y);
    526 }
    527 
    528 IntPoint GraphicsContext::origin()
    529 {
    530     cairo_matrix_t matrix;
    531     cairo_t* cr = m_data->cr;
    532     cairo_get_matrix(cr, &matrix);
    533     return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));
    534 }
    535 
    536 void GraphicsContext::setPlatformFillColor(const Color& col)
    537 {
    538     // FIXME: this is probably a no-op but I'm not sure
    539     // notImplemented(); // commented-out because it's chatty and clutters output
    540 }
    541 
    542 void GraphicsContext::setPlatformStrokeColor(const Color& col)
    543 {
    544     // FIXME: this is probably a no-op but I'm not sure
    545     //notImplemented(); // commented-out because it's chatty and clutters output
    546 }
    547 
    548 void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
    549 {
    550     if (paintingDisabled())
    551         return;
    552 
    553     cairo_set_line_width(m_data->cr, strokeThickness);
    554 }
    555 
    556 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
    557 {
    558     static double dashPattern[] = {5.0, 5.0};
    559     static double dotPattern[] = {1.0, 1.0};
    560 
    561     if (paintingDisabled())
    562         return;
    563 
    564     switch (strokeStyle) {
    565     case NoStroke:
    566         // FIXME: is it the right way to emulate NoStroke?
    567         cairo_set_line_width(m_data->cr, 0);
    568         break;
    569     case SolidStroke:
    570         cairo_set_dash(m_data->cr, 0, 0, 0);
    571         break;
    572     case DottedStroke:
    573         cairo_set_dash(m_data->cr, dotPattern, 2, 0);
    574         break;
    575     case DashedStroke:
    576         cairo_set_dash(m_data->cr, dashPattern, 2, 0);
    577         break;
    578     default:
    579         notImplemented();
    580         break;
    581     }
    582 }
    583 
    584 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
    585 {
    586     notImplemented();
    587 }
    588 
    589 void GraphicsContext::concatCTM(const AffineTransform& transform)
    590 {
    591     if (paintingDisabled())
    592         return;
    593 
    594     cairo_t* cr = m_data->cr;
    595     const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
    596     cairo_transform(cr, matrix);
    597 }
    598 
    599 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
    600 {
    601     if (paintingDisabled())
    602         return;
    603 
    604     clip(rect);
    605 
    606     Path p;
    607     FloatRect r(rect);
    608     // Add outer ellipse
    609     p.addEllipse(r);
    610     // Add inner ellipse
    611     r.inflate(-thickness);
    612     p.addEllipse(r);
    613     addPath(p);
    614 
    615     cairo_t* cr = m_data->cr;
    616     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    617     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
    618     cairo_clip(cr);
    619     cairo_set_fill_rule(cr, savedFillRule);
    620 }
    621 
    622 
    623 void GraphicsContext::setShadow(IntSize const&, int, Color const&)
    624 {
    625     notImplemented();
    626 }
    627 
    628 void GraphicsContext::clearShadow()
    629 {
    630     notImplemented();
    631 }
    632 
    633 void GraphicsContext::beginTransparencyLayer(float opacity)
    634 {
    635     if (paintingDisabled())
    636         return;
    637 
    638     cairo_t* cr = m_data->cr;
    639     cairo_push_group(cr);
    640     m_data->layers.append(opacity);
    641 }
    642 
    643 void GraphicsContext::endTransparencyLayer()
    644 {
    645     if (paintingDisabled())
    646         return;
    647 
    648     cairo_t* cr = m_data->cr;
    649 
    650     cairo_pop_group_to_source(cr);
    651     cairo_paint_with_alpha(cr, m_data->layers.last());
    652     m_data->layers.removeLast();
    653 }
    654 
    655 void GraphicsContext::clearRect(const FloatRect& rect)
    656 {
    657     if (paintingDisabled())
    658         return;
    659 
    660     cairo_t* cr = m_data->cr;
    661 
    662     cairo_save(cr);
    663     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    664     cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
    665     cairo_fill(cr);
    666     cairo_restore(cr);
    667 }
    668 
    669 void GraphicsContext::strokeRect(const FloatRect& rect, float width)
    670 {
    671     if (paintingDisabled())
    672         return;
    673 
    674     cairo_t* cr = m_data->cr;
    675     cairo_save(cr);
    676     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
    677     setColor(cr, strokeColor());
    678     cairo_set_line_width(cr, width);
    679     cairo_stroke(cr);
    680     cairo_restore(cr);
    681 }
    682 
    683 void GraphicsContext::setLineCap(LineCap lineCap)
    684 {
    685     if (paintingDisabled())
    686         return;
    687 
    688     cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;
    689     switch (lineCap) {
    690         case ButtCap:
    691             // no-op
    692             break;
    693         case RoundCap:
    694             cairoCap = CAIRO_LINE_CAP_ROUND;
    695             break;
    696         case SquareCap:
    697             cairoCap = CAIRO_LINE_CAP_SQUARE;
    698             break;
    699     }
    700     cairo_set_line_cap(m_data->cr, cairoCap);
    701 }
    702 
    703 void GraphicsContext::setLineJoin(LineJoin lineJoin)
    704 {
    705     if (paintingDisabled())
    706         return;
    707 
    708     cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;
    709     switch (lineJoin) {
    710         case MiterJoin:
    711             // no-op
    712             break;
    713         case RoundJoin:
    714             cairoJoin = CAIRO_LINE_JOIN_ROUND;
    715             break;
    716         case BevelJoin:
    717             cairoJoin = CAIRO_LINE_JOIN_BEVEL;
    718             break;
    719     }
    720     cairo_set_line_join(m_data->cr, cairoJoin);
    721 }
    722 
    723 void GraphicsContext::setMiterLimit(float miter)
    724 {
    725     if (paintingDisabled())
    726         return;
    727 
    728     cairo_set_miter_limit(m_data->cr, miter);
    729 }
    730 
    731 void GraphicsContext::setAlpha(float)
    732 {
    733     notImplemented();
    734 }
    735 
    736 static inline cairo_operator_t toCairoOperator(CompositeOperator op)
    737 {
    738     switch (op) {
    739         case CompositeClear:
    740             return CAIRO_OPERATOR_CLEAR;
    741         case CompositeCopy:
    742             return CAIRO_OPERATOR_SOURCE;
    743         case CompositeSourceOver:
    744             return CAIRO_OPERATOR_OVER;
    745         case CompositeSourceIn:
    746             return CAIRO_OPERATOR_IN;
    747         case CompositeSourceOut:
    748             return CAIRO_OPERATOR_OUT;
    749         case CompositeSourceAtop:
    750             return CAIRO_OPERATOR_ATOP;
    751         case CompositeDestinationOver:
    752             return CAIRO_OPERATOR_DEST_OVER;
    753         case CompositeDestinationIn:
    754             return CAIRO_OPERATOR_DEST_IN;
    755         case CompositeDestinationOut:
    756             return CAIRO_OPERATOR_DEST_OUT;
    757         case CompositeDestinationAtop:
    758             return CAIRO_OPERATOR_DEST_ATOP;
    759         case CompositeXOR:
    760             return CAIRO_OPERATOR_XOR;
    761         case CompositePlusDarker:
    762             return CAIRO_OPERATOR_SATURATE;
    763         case CompositeHighlight:
    764             // There is no Cairo equivalent for CompositeHighlight.
    765             return CAIRO_OPERATOR_OVER;
    766         case CompositePlusLighter:
    767             return CAIRO_OPERATOR_ADD;
    768         default:
    769             return CAIRO_OPERATOR_SOURCE;
    770     }
    771 }
    772 
    773 void GraphicsContext::setCompositeOperation(CompositeOperator op)
    774 {
    775     if (paintingDisabled())
    776         return;
    777 
    778     cairo_set_operator(m_data->cr, toCairoOperator(op));
    779 }
    780 
    781 void GraphicsContext::beginPath()
    782 {
    783     if (paintingDisabled())
    784         return;
    785 
    786     cairo_t* cr = m_data->cr;
    787     cairo_new_path(cr);
    788 }
    789 
    790 void GraphicsContext::addPath(const Path& path)
    791 {
    792     if (paintingDisabled())
    793         return;
    794 
    795     cairo_t* cr = m_data->cr;
    796     cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
    797     cairo_append_path(cr, p);
    798     cairo_path_destroy(p);
    799 }
    800 
    801 void GraphicsContext::clip(const Path& path)
    802 {
    803     if (paintingDisabled())
    804         return;
    805 
    806     cairo_t* cr = m_data->cr;
    807     cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
    808     cairo_append_path(cr, p);
    809     cairo_path_destroy(p);
    810     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    811     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
    812     cairo_clip(cr);
    813     cairo_set_fill_rule(cr, savedFillRule);
    814 }
    815 
    816 void GraphicsContext::clipOut(const Path& path)
    817 {
    818     if (paintingDisabled())
    819         return;
    820 
    821     cairo_t* cr = m_data->cr;
    822     double x1, y1, x2, y2;
    823     cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
    824     cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
    825     addPath(path);
    826 
    827     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    828     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
    829     cairo_clip(cr);
    830     cairo_set_fill_rule(cr, savedFillRule);
    831 }
    832 
    833 void GraphicsContext::rotate(float radians)
    834 {
    835     if (paintingDisabled())
    836         return;
    837 
    838     cairo_rotate(m_data->cr, radians);
    839 }
    840 
    841 void GraphicsContext::scale(const FloatSize& size)
    842 {
    843     if (paintingDisabled())
    844         return;
    845 
    846     cairo_scale(m_data->cr, size.width(), size.height());
    847 }
    848 
    849 void GraphicsContext::clipOut(const IntRect& r)
    850 {
    851     if (paintingDisabled())
    852         return;
    853 
    854     cairo_t* cr = m_data->cr;
    855     double x1, y1, x2, y2;
    856     cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
    857     cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1);
    858     cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
    859     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    860     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
    861     cairo_clip(cr);
    862     cairo_set_fill_rule(cr, savedFillRule);
    863 }
    864 
    865 void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
    866 {
    867     if (paintingDisabled())
    868         return;
    869 
    870     Path p;
    871     p.addEllipse(r);
    872     clipOut(p);
    873 }
    874 
    875 void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
    876 {
    877     if (paintingDisabled())
    878         return;
    879 
    880     cairo_t* cr = m_data->cr;
    881     cairo_save(cr);
    882     beginPath();
    883     addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
    884     setColor(cr, color);
    885     cairo_fill(cr);
    886     cairo_restore(cr);
    887 }
    888 
    889 #if PLATFORM(GTK)
    890 void GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose)
    891 {
    892     m_data->expose = expose;
    893 }
    894 
    895 GdkEventExpose* GraphicsContext::gdkExposeEvent() const
    896 {
    897     return m_data->expose;
    898 }
    899 
    900 GdkDrawable* GraphicsContext::gdkDrawable() const
    901 {
    902     if (!m_data->expose)
    903         return 0;
    904 
    905     return GDK_DRAWABLE(m_data->expose->window);
    906 }
    907 
    908 IntPoint GraphicsContext::translatePoint(const IntPoint& point) const
    909 {
    910     cairo_matrix_t tm;
    911     cairo_get_matrix(m_data->cr, &tm);
    912     double x = point.x();
    913     double y = point.y();
    914 
    915     cairo_matrix_transform_point(&tm, &x, &y);
    916     return IntPoint(x, y);
    917 }
    918 #endif
    919 
    920 void GraphicsContext::setUseAntialiasing(bool enable)
    921 {
    922     if (paintingDisabled())
    923         return;
    924 
    925     // When true, use the default Cairo backend antialias mode (usually this
    926     // enables standard 'grayscale' antialiasing); false to explicitly disable
    927     // antialiasing. This is the same strategy as used in drawConvexPolygon().
    928     cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
    929 }
    930 
    93180} // namespace WebCore
    93281
    933 #endif // PLATFORM(CAIRO)
  • trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp

    r29827 r30056  
    2828#include "GraphicsContext.h"
    2929
    30 #if PLATFORM(CG)
    31 
    3230#include "AffineTransform.h"
    3331#include "FloatConversion.h"
    34 #include "GraphicsContextPlatformPrivate.h"
     32#include "GraphicsContextPlatformPrivateCG.h"
    3533#include "KURL.h"
    3634#include "Path.h"
     
    8482{
    8583    // Note: Do not use this function within this class implementation, since we want to avoid the extra
    86     // save of the secondary context (in GraphicsContextPlatformPrivate.h).
     84    // save of the secondary context (in GraphicsContextPlatformPrivateCG.h).
    8785    CGContextSaveGState(platformContext());
    8886    m_data->save();
     
    9290{
    9391    // Note: Do not use this function within this class implementation, since we want to avoid the extra
    94     // restore of the secondary context (in GraphicsContextPlatformPrivate.h).
     92    // restore of the secondary context (in GraphicsContextPlatformPrivateCG.h).
    9593    CGContextRestoreGState(platformContext());
    9694    m_data->restore();
     
    931929}
    932930
    933 #endif // PLATFORM(CG)
  • trunk/WebCore/platform/graphics/win/FontCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "Font.h"
    2828
    29 #include "FontFallbackList.h"
    3029#include "GlyphBuffer.h"
    3130#include "GraphicsContext.h"
    3231#include "IntRect.h"
    33 #include "NotImplemented.h"
    3432#include "SimpleFontData.h"
    3533#include "UniscribeController.h"
     
    6967        // Set the correct color.
    7068        HDC textDrawingDC = hdc;
    71         /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
    72             // GDI can't handle drawing transparent text.  We have to draw into a mask.  We draw black text on a white-filled background.
    73             // We also do this when inside transparency layers, since GDI also can't draw onto a surface with alpha.
    74             graphicsContext->save();
    75             graphicsContext->setFillColor(Color::white);
    76             textDrawingDC = graphicsContext->getWindowsBitmapContext(textRect);
    77             SetTextColor(hdc, RGB(0, 0, 0));
    78         } else*/
    79             SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
     69        SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
    8070
    8171        SetBkMode(hdc, TRANSPARENT);
     
    9686        ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data());
    9787
    98         /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
    99             // TODOD: We have to walk the bits of the bitmap and invert them.  We also copy over the green component value into the alpha value
    100             // to keep ClearType looking reasonable.
    101 
    102             // Now that we have drawn the text into a bitmap and inverted it, obtain a CGImageRef mask.
    103             CGImageRef mask = graphicsContext->releaseWindowsBitmapContextIntoMask(textDrawingDC, textRect);
    104            
    105             // Apply the mask to the fill color.
    106             CGContextRef bitmapContext = graphicsContext->getWindowsCompatibleCGBitmapContext(textRect.size());
    107             CGFloat red, green, blue, alpha;
    108             color.getRGBA(red, green, blue, alpha);
    109             CGContextSetRGBFillColor(context, red, green, blue, alpha);
    110             CGContextFillRect(bitmapContext, IntRect(0, 0, textRect.width(), textRect.height()));
    111             CGImageRef fillColorImage = CGBitmapContextCreateImage(bitmapContext);
    112        
    113             // Apply the mask.
    114             CGImageRef finalImage = CGImageCreateWithMask(fillColorImage, mask);
    115 
    116             // The bitmap image needs to be drawn into the HDC.
    117             graphicsContext->drawImageIntoWindowsContext(hdc, finalImage);
    118 
    119             // Release our images and contexts.
    120             CGImageRelease(mask);
    121             CGImageRelease(fillColorImage);
    122             CGImageRelease(finalImage);
    123             CGContextRelease(bitmapContext);
    124         }*/
    125 
    12688        graphicsContext->releaseWindowsContext(hdc, textRect);
    12789        return;
     
    140102    matrix.d = -matrix.d;
    141103
    142     if (platformData.syntheticOblique())
    143     {
    144         static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90);
     104    if (platformData.syntheticOblique()) {
     105        static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90.0f);
    145106        matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
    146107    }
     
    164125}
    165126
    166 FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,
    167                                             int from, int to) const
    168 {
    169     UniscribeController it(this, run);
    170     it.advance(from);
    171     float beforeWidth = it.runWidthSoFar();
    172     it.advance(to);
    173     float afterWidth = it.runWidthSoFar();
    174 
    175     // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning
    176     if (run.rtl()) {
    177         it.advance(run.length());
    178         float totalWidth = it.runWidthSoFar();
    179         return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h);
    180     }
    181    
    182     return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h);
    183127}
    184 
    185 void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,
    186                            int from, int to) const
    187 {
    188     // This glyph buffer holds our glyphs + advances + font data for each glyph.
    189     GlyphBuffer glyphBuffer;
    190 
    191     float startX = point.x();
    192     UniscribeController controller(this, run);
    193     controller.advance(from);
    194     float beforeWidth = controller.runWidthSoFar();
    195     controller.advance(to, &glyphBuffer);
    196    
    197     // We couldn't generate any glyphs for the run.  Give up.
    198     if (glyphBuffer.isEmpty())
    199         return;
    200    
    201     float afterWidth = controller.runWidthSoFar();
    202 
    203     if (run.rtl()) {
    204         controller.advance(run.length());
    205         startX += controller.runWidthSoFar() - afterWidth;
    206     } else
    207         startX += beforeWidth;
    208 
    209     // Draw the glyph buffer now at the starting point returned in startX.
    210     FloatPoint startPoint(startX, point.y());
    211     drawGlyphBuffer(context, glyphBuffer, run, startPoint);
    212 }
    213 
    214 float Font::floatWidthForComplexText(const TextRun& run) const
    215 {
    216     UniscribeController controller(this, run);
    217     controller.advance(run.length());
    218     return controller.runWidthSoFar();
    219 }
    220 
    221 int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const
    222 {
    223     UniscribeController controller(this, run);
    224     return controller.offsetForPosition(x, includePartialGlyphs);
    225 }
    226 
    227 }
  • trunk/WebCore/platform/graphics/win/FontWin.cpp

    r29706 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434#include "SimpleFontData.h"
    3535#include "UniscribeController.h"
    36 #include <ApplicationServices/ApplicationServices.h>
    37 #include <WebKitSystemInterface/WebKitSystemInterface.h>
    3836#include <wtf/MathExtras.h>
    3937
    4038namespace WebCore {
    41 
    42 const int syntheticObliqueAngle = 14;
    43 
    44 void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
    45                       int from, int numGlyphs, const FloatPoint& point) const
    46 {
    47     if (font->m_font.useGDI()) {
    48         // FIXME: Support alpha blending.
    49         // FIXME: Support text stroke/fill.
    50         // FIXME: Support text shadow.
    51         Color fillColor = graphicsContext->fillColor();
    52         if (fillColor.alpha() == 0)
    53             return;
    54 
    55         // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
    56         Vector<int, 2048> gdiAdvances;
    57         int totalWidth = 0;
    58         for (int i = 0; i < numGlyphs; i++) {
    59             gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
    60             totalWidth += gdiAdvances[i];
    61         }
    62 
    63         // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
    64         int lineGap = font->lineGap();
    65         IntRect textRect(point.x() - lineGap, point.y() - font->ascent() - lineGap, totalWidth + 2 * lineGap, font->lineSpacing());
    66         HDC hdc = graphicsContext->getWindowsContext(textRect);
    67         SelectObject(hdc, font->m_font.hfont());
    68 
    69         // Set the correct color.
    70         HDC textDrawingDC = hdc;
    71         /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
    72             // GDI can't handle drawing transparent text.  We have to draw into a mask.  We draw black text on a white-filled background.
    73             // We also do this when inside transparency layers, since GDI also can't draw onto a surface with alpha.
    74             graphicsContext->save();
    75             graphicsContext->setFillColor(Color::white);
    76             textDrawingDC = graphicsContext->getWindowsBitmapContext(textRect);
    77             SetTextColor(hdc, RGB(0, 0, 0));
    78         } else*/
    79             SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
    80 
    81         SetBkMode(hdc, TRANSPARENT);
    82         SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
    83 
    84         // Uniscribe gives us offsets to help refine the positioning of combining glyphs.
    85         FloatSize translation = glyphBuffer.offsetAt(from);
    86         if (translation.width() || translation.height()) {
    87             XFORM xform;
    88             xform.eM11 = 1.0;
    89             xform.eM12 = 0;
    90             xform.eM21 = 0;
    91             xform.eM22 = 1.0;
    92             xform.eDx = translation.width();
    93             xform.eDy = translation.height();
    94             ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
    95         }
    96         ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data());
    97 
    98         /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
    99             // TODOD: We have to walk the bits of the bitmap and invert them.  We also copy over the green component value into the alpha value
    100             // to keep ClearType looking reasonable.
    101 
    102             // Now that we have drawn the text into a bitmap and inverted it, obtain a CGImageRef mask.
    103             CGImageRef mask = graphicsContext->releaseWindowsBitmapContextIntoMask(textDrawingDC, textRect);
    104            
    105             // Apply the mask to the fill color.
    106             CGContextRef bitmapContext = graphicsContext->getWindowsCompatibleCGBitmapContext(textRect.size());
    107             CGFloat red, green, blue, alpha;
    108             color.getRGBA(red, green, blue, alpha);
    109             CGContextSetRGBFillColor(context, red, green, blue, alpha);
    110             CGContextFillRect(bitmapContext, IntRect(0, 0, textRect.width(), textRect.height()));
    111             CGImageRef fillColorImage = CGBitmapContextCreateImage(bitmapContext);
    112        
    113             // Apply the mask.
    114             CGImageRef finalImage = CGImageCreateWithMask(fillColorImage, mask);
    115 
    116             // The bitmap image needs to be drawn into the HDC.
    117             graphicsContext->drawImageIntoWindowsContext(hdc, finalImage);
    118 
    119             // Release our images and contexts.
    120             CGImageRelease(mask);
    121             CGImageRelease(fillColorImage);
    122             CGImageRelease(finalImage);
    123             CGContextRelease(bitmapContext);
    124         }*/
    125 
    126         graphicsContext->releaseWindowsContext(hdc, textRect);
    127         return;
    128     }
    129 
    130     CGContextRef cgContext = graphicsContext->platformContext();
    131 
    132     uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext);
    133 
    134     const FontPlatformData& platformData = font->platformData();
    135 
    136     CGContextSetFont(cgContext, platformData.cgFont());
    137 
    138     CGAffineTransform matrix = CGAffineTransformIdentity;
    139     matrix.b = -matrix.b;
    140     matrix.d = -matrix.d;
    141 
    142     if (platformData.syntheticOblique())
    143     {
    144         static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90);
    145         matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
    146     }
    147 
    148     // Uniscribe gives us offsets to help refine the positioning of combining glyphs.
    149     FloatSize translation = glyphBuffer.offsetAt(from);
    150     if (translation.width() || translation.height())
    151         CGAffineTransformTranslate(matrix, translation.width(), translation.height());
    152    
    153     CGContextSetTextMatrix(cgContext, matrix);
    154 
    155     CGContextSetFontSize(cgContext, platformData.size());
    156     CGContextSetTextPosition(cgContext, point.x(), point.y());
    157     CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
    158     if (font->m_syntheticBoldOffset) {
    159         CGContextSetTextPosition(cgContext, point.x() + font->m_syntheticBoldOffset, point.y());
    160         CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
    161     }
    162 
    163     wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
    164 }
    16539
    16640FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,
  • trunk/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "NotImplemented.h"
    3131#include "Path.h"
     32
    3233#include <CoreGraphics/CGBitmapContext.h>
    3334#include <WebKitSystemInterface/WebKitSystemInterface.h>
    34 #include <wtf/MathExtras.h>
    35 
    36 #include "GraphicsContextPlatformPrivate.h"
     35#include "GraphicsContextPlatformPrivateCG.h"
    3736
    3837using namespace std;
     
    4039namespace WebCore {
    4140
    42 class SVGResourceImage;
    43 
    4441static CGContextRef CGContextWithHDC(HDC hdc)
    4542{
    46     HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
     43    HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
    4744    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    4845    BITMAP info;
     
    7774    }
    7875}
     76
     77bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
    7978
    8079HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
     
    119118        // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
    120119        XFORM xform;
    121         xform.eM11 = 1.0;
    122         xform.eM12 = 0;
    123         xform.eM21 = 0;
    124         xform.eM22 = 1.0;
     120        xform.eM11 = 1.0f;
     121        xform.eM12 = 0.0f;
     122        xform.eM21 = 0.0f;
     123        xform.eM22 = 1.0f;
    125124        xform.eDx = -dstRect.x();
    126125        xform.eDy = -dstRect.y();
     
    135134}
    136135
    137 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
    138 
    139136void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
    140137{
     
    143140            return;
    144141
    145         HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
     142        HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
    146143
    147144        // Need to make a CGImage out of the bitmap's pixel buffer and then draw
     
    204201    XFORM xform;
    205202    xform.eM11 = size.width();
    206     xform.eM12 = 0;
    207     xform.eM21 = 0;
     203    xform.eM12 = 0.0f;
     204    xform.eM21 = 0.0f;
    208205    xform.eM22 = size.height();
    209     xform.eDx = 0;
    210     xform.eDy = 0;
     206    xform.eDx = 0.0f;
     207    xform.eDy = 0.0f;
    211208    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    212209}
     
    224221    xform.eM21 = sinAngle;
    225222    xform.eM22 = cosAngle;
    226     xform.eDx = 0;
    227     xform.eDy = 0;
     223    xform.eDx = 0.0f;
     224    xform.eDy = 0.0f;
    228225    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    229226}
     
    234231        return;
    235232    XFORM xform;
    236     xform.eM11 = 1.0;
    237     xform.eM12 = 0;
    238     xform.eM21 = 0;
    239     xform.eM22 = 1.0;
     233    xform.eM11 = 1.0f;
     234    xform.eM12 = 0.0f;
     235    xform.eM21 = 0.0f;
     236    xform.eM22 = 1.0f;
    240237    xform.eDx = x;
    241238    xform.eDy = y;
     
    247244    if (!m_hdc)
    248245        return;
     246
    249247    CGAffineTransform mat = transform;
    250248    XFORM xform;
     
    255253    xform.eDx = mat.tx;
    256254    xform.eDy = mat.ty;
     255
    257256    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    258257}
     
    288287}
    289288
     289// Pulled from GraphicsContextCG
     290static void setCGStrokeColor(CGContextRef context, const Color& color)
     291{
     292    CGFloat red, green, blue, alpha;
     293    color.getRGBA(red, green, blue, alpha);
     294    CGContextSetRGBStrokeColor(context, red, green, blue, alpha);
     295}
     296
    290297static const Color& spellingPatternColor() {
    291298    static const Color spellingColor(255, 0, 0);
     
    298305}
    299306
    300 // Pulled from GraphicsContextCG
    301 static void setCGStrokeColor(CGContextRef context, const Color& color)
    302 {
    303     CGFloat red, green, blue, alpha;
    304     color.getRGBA(red, green, blue, alpha);
    305     CGContextSetRGBStrokeColor(context, red, green, blue, alpha);
    306 }
    307 
    308307void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
    309308{
    310309    if (paintingDisabled())
    311310        return;
    312    
     311
    313312    // These are the same for misspelling or bad grammar
    314313    const int patternHeight = 3; // 3 rows
     
    344343    // Dash lengths for the top and bottom of the error underline are the same.
    345344    // These are magic.
    346     static const float edge_dash_lengths[] = {2, 2};
     345    static const float edge_dash_lengths[] = {2.0f, 2.0f};
    347346    static const float middle_dash_lengths[] = {2.76f, 1.24f};
    348347    static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f;
     
    375374}
    376375
    377 #if ENABLE(SVG)
    378 GraphicsContext* contextForImage(SVGResourceImage*)
    379 {
    380     // FIXME: This should go in GraphicsContextCG.cpp
    381     notImplemented();
    382     return 0;
    383 }
    384 #endif
    385 
    386 }
     376}
  • trunk/WebCore/platform/graphics/win/GraphicsContextWin.cpp

    r29479 r30056  
    11/*
    2  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
     2 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "NotImplemented.h"
    3131#include "Path.h"
    32 #include <CoreGraphics/CGBitmapContext.h>
    33 #include <WebKitSystemInterface/WebKitSystemInterface.h>
    3432#include <wtf/MathExtras.h>
    35 
    36 #include "GraphicsContextPlatformPrivate.h"
    3733
    3834using namespace std;
     
    4137
    4238class SVGResourceImage;
    43 
    44 static CGContextRef CGContextWithHDC(HDC hdc)
    45 {
    46     HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
    47     CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    48     BITMAP info;
    49 
    50     GetObject(bitmap, sizeof(info), &info);
    51     ASSERT(info.bmBitsPixel == 32);
    52     CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
    53                                                  info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
    54     CGColorSpaceRelease(deviceRGB);
    55 
    56     // Flip coords
    57     CGContextTranslateCTM(context, 0, info.bmHeight);
    58     CGContextScaleCTM(context, 1, -1);
    59    
    60     // Put the HDC In advanced mode so it will honor affine transforms.
    61     SetGraphicsMode(hdc, GM_ADVANCED);
    62    
    63     return context;
    64 }
    65 
    66 GraphicsContext::GraphicsContext(HDC hdc)
    67     : m_common(createGraphicsContextPrivate())
    68     , m_data(new GraphicsContextPlatformPrivate(CGContextWithHDC(hdc)))
    69 {
    70     CGContextRelease(m_data->m_cgContext);
    71     m_data->m_hdc = hdc;
    72     setPaintingDisabled(!m_data->m_cgContext);
    73     if (m_data->m_cgContext) {
    74         // Make sure the context starts in sync with our state.
    75         setPlatformFillColor(fillColor());
    76         setPlatformStrokeColor(strokeColor());
    77     }
    78 }
    79 
    80 HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
    81 {
    82     if (inTransparencyLayer()) {
    83         if (dstRect.isEmpty())
    84             return 0;
    85 
    86         // Create a bitmap DC in which to draw.
    87         BITMAPINFO bitmapInfo;
    88         bitmapInfo.bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
    89         bitmapInfo.bmiHeader.biWidth         = dstRect.width();
    90         bitmapInfo.bmiHeader.biHeight        = dstRect.height();
    91         bitmapInfo.bmiHeader.biPlanes        = 1;
    92         bitmapInfo.bmiHeader.biBitCount      = 32;
    93         bitmapInfo.bmiHeader.biCompression   = BI_RGB;
    94         bitmapInfo.bmiHeader.biSizeImage     = 0;
    95         bitmapInfo.bmiHeader.biXPelsPerMeter = 0;
    96         bitmapInfo.bmiHeader.biYPelsPerMeter = 0;
    97         bitmapInfo.bmiHeader.biClrUsed       = 0;
    98         bitmapInfo.bmiHeader.biClrImportant  = 0;
    99 
    100         void* pixels = 0;
    101         HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
    102         if (!bitmap)
    103             return 0;
    104 
    105         HDC bitmapDC = ::CreateCompatibleDC(m_data->m_hdc);
    106         ::SelectObject(bitmapDC, bitmap);
    107 
    108         // Fill our buffer with clear if we're going to alpha blend.
    109         if (supportAlphaBlend) {
    110             BITMAP bmpInfo;
    111             GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
    112             int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
    113             memset(bmpInfo.bmBits, 0, bufferSize);
    114         }
    115 
    116         // Make sure we can do world transforms.
    117         SetGraphicsMode(bitmapDC, GM_ADVANCED);
    118 
    119         // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
    120         XFORM xform;
    121         xform.eM11 = 1.0;
    122         xform.eM12 = 0;
    123         xform.eM21 = 0;
    124         xform.eM22 = 1.0;
    125         xform.eDx = -dstRect.x();
    126         xform.eDy = -dstRect.y();
    127         ::SetWorldTransform(bitmapDC, &xform);
    128 
    129         return bitmapDC;
    130     }
    131 
    132     CGContextFlush(platformContext());
    133     m_data->save();
    134     return m_data->m_hdc;
    135 }
    136 
    137 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
    138 
    139 void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
    140 {
    141     if (hdc && inTransparencyLayer()) {
    142         if (dstRect.isEmpty())
    143             return;
    144 
    145         HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
    146 
    147         // Need to make a CGImage out of the bitmap's pixel buffer and then draw
    148         // it into our context.
    149         BITMAP info;
    150         GetObject(bitmap, sizeof(info), &info);
    151         ASSERT(info.bmBitsPixel == 32);
    152 
    153         CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    154         CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
    155                                                            info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little |
    156                                                            (supportAlphaBlend ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst));
    157         CGColorSpaceRelease(deviceRGB);
    158 
    159         CGImageRef image = CGBitmapContextCreateImage(bitmapContext);
    160         CGContextDrawImage(m_data->m_cgContext, dstRect, image);
    161        
    162         // Delete all our junk.
    163         CGImageRelease(image);
    164         CGContextRelease(bitmapContext);
    165         ::DeleteDC(hdc);
    166         ::DeleteObject(bitmap);
    167 
    168         return;
    169     }
    170 
    171     m_data->restore();
    172 }
    173 
    174 void GraphicsContextPlatformPrivate::save()
    175 {
    176     if (!m_hdc)
    177         return;
    178     SaveDC(m_hdc);
    179 }
    180 
    181 void GraphicsContextPlatformPrivate::restore()
    182 {
    183     if (!m_hdc)
    184         return;
    185     RestoreDC(m_hdc, -1);
    186 }
    187 
    188 void GraphicsContextPlatformPrivate::clip(const IntRect& clipRect)
    189 {
    190     if (!m_hdc)
    191         return;
    192     IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.right(), clipRect.bottom());
    193 }
    194 
    195 void GraphicsContextPlatformPrivate::clip(const Path&)
    196 {
    197     notImplemented();
    198 }
    199 
    200 void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
    201 {
    202     if (!m_hdc)
    203         return;
    204     XFORM xform;
    205     xform.eM11 = size.width();
    206     xform.eM12 = 0;
    207     xform.eM21 = 0;
    208     xform.eM22 = size.height();
    209     xform.eDx = 0;
    210     xform.eDy = 0;
    211     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    212 }
    213 
    214 static const double deg2rad = 0.017453292519943295769; // pi/180
    215 
    216 void GraphicsContextPlatformPrivate::rotate(float degreesAngle)
    217 {
    218     float radiansAngle = degreesAngle * deg2rad;
    219     float cosAngle = cosf(radiansAngle);
    220     float sinAngle = sinf(radiansAngle);
    221     XFORM xform;
    222     xform.eM11 = cosAngle;
    223     xform.eM12 = -sinAngle;
    224     xform.eM21 = sinAngle;
    225     xform.eM22 = cosAngle;
    226     xform.eDx = 0;
    227     xform.eDy = 0;
    228     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    229 }
    230 
    231 void GraphicsContextPlatformPrivate::translate(float x , float y)
    232 {
    233     if (!m_hdc)
    234         return;
    235     XFORM xform;
    236     xform.eM11 = 1.0;
    237     xform.eM12 = 0;
    238     xform.eM21 = 0;
    239     xform.eM22 = 1.0;
    240     xform.eDx = x;
    241     xform.eDy = y;
    242     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    243 }
    244 
    245 void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform)
    246 {
    247     if (!m_hdc)
    248         return;
    249     CGAffineTransform mat = transform;
    250     XFORM xform;
    251     xform.eM11 = mat.a;
    252     xform.eM12 = mat.b;
    253     xform.eM21 = mat.c;
    254     xform.eM22 = mat.d;
    255     xform.eDx = mat.tx;
    256     xform.eDy = mat.ty;
    257     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
    258 }
    259 
    260 void GraphicsContext::drawFocusRing(const Color& color)
    261 {
    262     if (paintingDisabled())
    263         return;
    264 
    265     float radius = (focusRingWidth() - 1) / 2.0f;
    266     int offset = radius + focusRingOffset();
    267     CGColorRef colorRef = color.isValid() ? cgColor(color) : 0;
    268 
    269     CGMutablePathRef focusRingPath = CGPathCreateMutable();
    270     const Vector<IntRect>& rects = focusRingRects();
    271     unsigned rectCount = rects.size();
    272     for (unsigned i = 0; i < rectCount; i++)
    273         CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset));
    274 
    275     CGContextRef context = platformContext();
    276     CGContextSaveGState(context);
    277 
    278     CGContextBeginPath(context);
    279     CGContextAddPath(context, focusRingPath);
    280 
    281     wkDrawFocusRing(context, colorRef, radius);
    282 
    283     CGColorRelease(colorRef);
    284 
    285     CGPathRelease(focusRingPath);
    286 
    287     CGContextRestoreGState(context);
    288 }
    289 
    290 static const Color& spellingPatternColor() {
    291     static const Color spellingColor(255, 0, 0);
    292     return spellingColor;
    293 }
    294 
    295 static const Color& grammarPatternColor() {
    296     static const Color grammarColor(0, 128, 0);
    297     return grammarColor;
    298 }
    299 
    300 // Pulled from GraphicsContextCG
    301 static void setCGStrokeColor(CGContextRef context, const Color& color)
    302 {
    303     CGFloat red, green, blue, alpha;
    304     color.getRGBA(red, green, blue, alpha);
    305     CGContextSetRGBStrokeColor(context, red, green, blue, alpha);
    306 }
    307 
    308 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
    309 {
    310     if (paintingDisabled())
    311         return;
    312    
    313     // These are the same for misspelling or bad grammar
    314     const int patternHeight = 3; // 3 rows
    315     ASSERT(cMisspellingLineThickness == patternHeight);
    316     const int patternWidth = 4; // 4 pixels
    317     ASSERT(patternWidth == cMisspellingLinePatternWidth);
    318 
    319     // Make sure to draw only complete dots.
    320     // NOTE: Code here used to shift the underline to the left and increase the width
    321     // to make sure everything gets underlined, but that results in drawing out of
    322     // bounds (e.g. when at the edge of a view) and could make it appear that the
    323     // space between adjacent misspelled words was underlined.
    324     // allow slightly more considering that the pattern ends with a transparent pixel
    325     int widthMod = width % patternWidth;
    326     if (patternWidth - widthMod > cMisspellingLinePatternGapWidth)
    327         width -= widthMod;
    328      
    329     // Draw the underline
    330     CGContextRef context = platformContext();
    331     CGContextSaveGState(context);
    332 
    333     const Color& patternColor = grammar ? grammarPatternColor() : spellingPatternColor();
    334     setCGStrokeColor(context, patternColor);
    335 
    336     wkSetPatternPhaseInUserSpace(context, point);
    337     CGContextSetBlendMode(context, kCGBlendModeNormal);
    338    
    339     // 3 rows, each offset by half a pixel for blending purposes
    340     const CGPoint upperPoints [] = {{point.x(), point.y() + patternHeight - 2.5 }, {point.x() + width, point.y() + patternHeight - 2.5}};
    341     const CGPoint middlePoints [] = {{point.x(), point.y() + patternHeight - 1.5 }, {point.x() + width, point.y() + patternHeight - 1.5}};
    342     const CGPoint lowerPoints [] = {{point.x(), point.y() + patternHeight - 0.5 }, {point.x() + width, point.y() + patternHeight - 0.5 }};
    343    
    344     // Dash lengths for the top and bottom of the error underline are the same.
    345     // These are magic.
    346     static const float edge_dash_lengths[] = {2, 2};
    347     static const float middle_dash_lengths[] = {2.76f, 1.24f};
    348     static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f;
    349     static const float middle_offset = -(middle_dash_lengths[1] - 1.0f) / 2.0f;
    350 
    351     // Line opacities.  Once again, these are magic.
    352     const float upperOpacity = 0.33f;
    353     const float middleOpacity = 0.75f;
    354     const float lowerOpacity = 0.88f;
    355 
    356     //Top line
    357     CGContextSetLineDash(context, edge_offset, edge_dash_lengths,
    358                          sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0]));
    359     CGContextSetAlpha(context, upperOpacity);
    360     CGContextStrokeLineSegments(context, upperPoints, 2);
    361  
    362     // Middle line
    363     CGContextSetLineDash(context, middle_offset, middle_dash_lengths,
    364                          sizeof(middle_dash_lengths) / sizeof(middle_dash_lengths[0]));
    365     CGContextSetAlpha(context, middleOpacity);
    366     CGContextStrokeLineSegments(context, middlePoints, 2);
    367    
    368     // Bottom line
    369     CGContextSetLineDash(context, edge_offset, edge_dash_lengths,
    370                          sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0]));
    371     CGContextSetAlpha(context, lowerOpacity);
    372     CGContextStrokeLineSegments(context, lowerPoints, 2);
    373 
    374     CGContextRestoreGState(context);
    375 }
    37639
    37740#if ENABLE(SVG)
  • trunk/WebCore/platform/graphics/win/ImageCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include <ApplicationServices/ApplicationServices.h>
    3131
    32 #include <winsock2.h>
    3332#include <windows.h>
    3433#include "PlatformString.h"
    35 #include "MIMETypeRegistry.h"
    36 #include "SharedBuffer.h"
    37 
    38 // This function loads resources from WebKit
    39 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char*);
    4034
    4135namespace WebCore {
    42 
    43 void BitmapImage::initPlatformData()
    44 {
    45 }
    46 
    47 void BitmapImage::invalidatePlatformData()
    48 {
    49 }
    50 
    51 Image* Image::loadPlatformResource(const char *name)
    52 {
    53     RefPtr<SharedBuffer> buffer = loadResourceIntoBuffer(name);
    54     BitmapImage* img = new BitmapImage;
    55     img->setData(buffer.release(), true);
    56     return img;
    57 }
    58 
    59 bool BitmapImage::getHBITMAP(HBITMAP bmp)
    60 {
    61     return getHBITMAPOfSize(bmp, 0);
    62 }
    6336
    6437bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
     
    7750 
    7851    GraphicsContext gc(cgContext);
     52
    7953    IntSize imageSize = BitmapImage::size();
    8054    if (size)
    81         drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), CompositeCopy);
     55        drawFrameMatchingSourceSize(&gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), CompositeCopy);
    8256    else
    83         draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), CompositeCopy);
     57        draw(&gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), CompositeCopy);
    8458
    8559    // Do cleanup
    8660    CGContextRelease(cgContext);
    8761    CGColorSpaceRelease(deviceRGB);
     62
    8863    return true;
    8964}
     
    9469    for (int i = 0; i < frames; ++i) {
    9570        CGImageRef image = frameAtIndex(i);
    96         if (CGImageGetHeight(image) == (size_t)srcSize.height() && CGImageGetWidth(image) == (size_t)srcSize.width()) {
     71        if (CGImageGetHeight(image) == static_cast<size_t>(srcSize.height()) && CGImageGetWidth(image) == static_cast<size_t>(srcSize.width())) {
    9772            size_t currentFrame = m_currentFrame;
    9873            m_currentFrame = i;
    99             draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), compositeOp);
     74            draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), compositeOp);
    10075            m_currentFrame = currentFrame;
    10176            return;
     
    10580    // No image of the correct size was found, fallback to drawing the current frame
    10681    IntSize imageSize = BitmapImage::size();
    107     draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), compositeOp);
     82    draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp);
    10883}
    10984
  • trunk/WebCore/platform/graphics/win/ImageWin.cpp

    r25674 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "Image.h"
    2828#include "BitmapImage.h"
    29 #include "GraphicsContext.h"
    30 #include <ApplicationServices/ApplicationServices.h>
    3129
    32 #include <winsock2.h>
    33 #include <windows.h>
    34 #include "PlatformString.h"
    35 #include "MIMETypeRegistry.h"
    3630#include "SharedBuffer.h"
    3731
     
    6256}
    6357
    64 bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
    65 {
    66     ASSERT(bmp);
    67 
    68     BITMAP bmpInfo;
    69     GetObject(bmp, sizeof(BITMAP), &bmpInfo);
    70 
    71     ASSERT(bmpInfo.bmBitsPixel == 32);
    72     int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
    73    
    74     CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    75     CGContextRef cgContext = CGBitmapContextCreate(bmpInfo.bmBits, bmpInfo.bmWidth, bmpInfo.bmHeight,
    76         8, bmpInfo.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
    77  
    78     GraphicsContext gc(cgContext);
    79     IntSize imageSize = BitmapImage::size();
    80     if (size)
    81         drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), CompositeCopy);
    82     else
    83         draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), CompositeCopy);
    84 
    85     // Do cleanup
    86     CGContextRelease(cgContext);
    87     CGColorSpaceRelease(deviceRGB);
    88     return true;
    89 }
    90 
    91 void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator compositeOp)
    92 {
    93     int frames = frameCount();
    94     for (int i = 0; i < frames; ++i) {
    95         CGImageRef image = frameAtIndex(i);
    96         if (CGImageGetHeight(image) == (size_t)srcSize.height() && CGImageGetWidth(image) == (size_t)srcSize.width()) {
    97             size_t currentFrame = m_currentFrame;
    98             m_currentFrame = i;
    99             draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), compositeOp);
    100             m_currentFrame = currentFrame;
    101             return;
    102         }
    103     }
    104 
    105     // No image of the correct size was found, fallback to drawing the current frame
    106     IntSize imageSize = BitmapImage::size();
    107     draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), compositeOp);
    108 }
    109 
    11058} // namespace WebCore
  • trunk/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3939#include <unicode/unorm.h>
    4040#include <ApplicationServices/ApplicationServices.h>
     41#include <WebKitSystemInterface/WebKitSystemInterface.h>
    4142#include <mlang.h>
    4243#include <tchar.h>
    43 #include <WebKitSystemInterface/WebKitSystemInterface.h>
    4444
    4545namespace WebCore {
     
    4747using std::max;
    4848
    49 const float cSmallCapsFontSizeMultiplier = 0.7f;
    50 
    51 static bool shouldApplyMacAscentHack;
    52 
    53 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / (float)unitsPerEm : x; }
    54 
    55 void SimpleFontData::setShouldApplyMacAscentHack(bool b)
    56 {
    57     shouldApplyMacAscentHack = b;
    58 }
     49static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / static_cast<float>(unitsPerEm) : x; }
    5950
    6051void SimpleFontData::platformInit()
    61 {   
     52{
    6253    m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
    6354    m_scriptCache = 0;
     
    111102        ReleaseDC(0, dc);
    112103
    113         if (shouldApplyMacAscentHack) {
     104        if (shouldApplyMacAscentHack()) {
    114105            // This code comes from FontDataMac.mm. We only ever do this when running regression tests so that our metrics will match Mac.
    115106
     
    161152}
    162153
    163 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
    164 {
    165     if (!m_smallCapsFontData) {
    166         float smallCapsHeight = cSmallCapsFontSizeMultiplier * m_font.size();
    167         if (isCustomFont()) {
    168             FontPlatformData smallCapsFontData(m_font);
    169             smallCapsFontData.setSize(smallCapsHeight);
    170             m_smallCapsFontData = new SimpleFontData(smallCapsFontData, true, false);
    171         } else {
    172             LOGFONT winfont;
    173             GetObject(m_font.hfont(), sizeof(LOGFONT), &winfont);
    174             winfont.lfHeight = -lroundf(smallCapsHeight * (m_font.useGDI() ? 1 : 32));
    175             HFONT hfont = CreateFontIndirect(&winfont);
    176             m_smallCapsFontData = new SimpleFontData(FontPlatformData(hfont, smallCapsHeight, fontDescription.bold(), fontDescription.italic(), m_font.useGDI()));
    177         }
    178     }
    179     return m_smallCapsFontData;
    180 }
    181 
    182 bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
    183 {
    184     // FIXME: Support custom fonts.
    185     if (isCustomFont())
    186         return false;
    187 
    188     // FIXME: Microsoft documentation seems to imply that characters can be output using a given font and DC
    189     // merely by testing code page intersection.  This seems suspect though.  Can't a font only partially
    190     // cover a given code page?
    191     IMLangFontLink2* langFontLink = FontCache::getFontLinkInterface();
    192     if (!langFontLink)
    193         return false;
    194 
    195     HDC dc = GetDC(0);
    196    
    197     DWORD acpCodePages;
    198     langFontLink->CodePageToCodePages(CP_ACP, &acpCodePages);
    199 
    200     DWORD fontCodePages;
    201     langFontLink->GetFontCodePages(dc, m_font.hfont(), &fontCodePages);
    202 
    203     DWORD actualCodePages;
    204     long numCharactersProcessed;
    205     long offset = 0;
    206     while (offset < length) {
    207         langFontLink->GetStrCodePages(characters, length, acpCodePages, &actualCodePages, &numCharactersProcessed);
    208         if ((actualCodePages & fontCodePages) == 0)
    209             return false;
    210         offset += numCharactersProcessed;
    211     }
    212 
    213     ReleaseDC(0, dc);
    214 
    215     return true;
    216 }
    217 
    218 void SimpleFontData::determinePitch()
    219 {
    220     if (isCustomFont()) {
    221         m_treatAsFixedPitch = false;
    222         return;
    223     }
    224 
    225     // TEXTMETRICS have this.  Set m_treatAsFixedPitch based off that.
    226     HDC dc = GetDC(0);
    227     SaveDC(dc);
    228     SelectObject(dc, m_font.hfont());
    229 
    230     // Yes, this looks backwards, but the fixed pitch bit is actually set if the font
    231     // is *not* fixed pitch.  Unbelievable but true.
    232     TEXTMETRIC tm;
    233     GetTextMetrics(dc, &tm);
    234     m_treatAsFixedPitch = ((tm.tmPitchAndFamily & TMPF_FIXED_PITCH) == 0);
    235 
    236     RestoreDC(dc, -1);
    237     ReleaseDC(0, dc);
    238 }
    239 
    240154float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
    241155{
     
    254168    CGSize advance;
    255169    CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
     170 
    256171    // FIXME: Need to add real support for printer fonts.
    257172    bool isPrinterFont = false;
    258173    wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
     174
    259175    return advance.width + m_syntheticBoldOffset;
    260176}
    261177
    262 SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
    263 {
    264     if (!m_scriptFontProperties) {
    265         m_scriptFontProperties = new SCRIPT_FONTPROPERTIES;
    266         memset(m_scriptFontProperties, 0, sizeof(SCRIPT_FONTPROPERTIES));
    267         m_scriptFontProperties->cBytes = sizeof(SCRIPT_FONTPROPERTIES);
    268         HRESULT result = ScriptGetFontProperties(0, scriptCache(), m_scriptFontProperties);
    269         if (result == E_PENDING) {
    270             HDC dc = GetDC(0);
    271             SaveDC(dc);
    272             SelectObject(dc, m_font.hfont());
    273             ScriptGetFontProperties(dc, scriptCache(), m_scriptFontProperties);
    274             RestoreDC(dc, -1);
    275             ReleaseDC(0, dc);
    276         }
    277     }
    278     return m_scriptFontProperties;
    279178}
    280 
    281 }
  • trunk/WebCore/platform/graphics/win/SimpleFontDataWin.cpp

    r29250 r30056  
    11/*
    2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4949const float cSmallCapsFontSizeMultiplier = 0.7f;
    5050
    51 static bool shouldApplyMacAscentHack;
    52 
    53 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / (float)unitsPerEm : x; }
     51static bool g_shouldApplyMacAscentHack;
    5452
    5553void SimpleFontData::setShouldApplyMacAscentHack(bool b)
    5654{
    57     shouldApplyMacAscentHack = b;
     55    g_shouldApplyMacAscentHack = b;
    5856}
    5957
    60 void SimpleFontData::platformInit()
    61 {   
    62     m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
    63     m_scriptCache = 0;
    64     m_scriptFontProperties = 0;
    65     m_isSystemFont = false;
    66    
    67     if (m_font.useGDI()) {
    68         HDC hdc = GetDC(0);
    69         HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
    70         OUTLINETEXTMETRIC metrics;
    71         GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
    72         TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
    73         m_ascent = textMetrics.tmAscent;
    74         m_descent = textMetrics.tmDescent;
    75         m_lineGap = textMetrics.tmExternalLeading;
    76         m_lineSpacing = m_ascent + m_descent + m_lineGap;
    77         m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
    78 
    79         GLYPHMETRICS gm;
    80         MAT2 mat = { 1, 0, 0, 1 };
    81         DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
    82         if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
    83             m_xHeight = gm.gmptGlyphOrigin.y;
    84 
    85         m_unitsPerEm = metrics.otmEMSquare;
    86 
    87         SelectObject(hdc, oldFont);
    88         ReleaseDC(0, hdc);
    89 
    90         return;
    91     }
    92 
    93     CGFontRef font = m_font.cgFont();
    94     int iAscent = CGFontGetAscent(font);
    95     int iDescent = CGFontGetDescent(font);
    96     int iLineGap = CGFontGetLeading(font);
    97     m_unitsPerEm = CGFontGetUnitsPerEm(font);
    98     float pointSize = m_font.size();
    99     float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize;
    100     float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize;
    101     float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize;
    102 
    103     if (!isCustomFont()) {
    104         HDC dc = GetDC(0);
    105         HGDIOBJ oldFont = SelectObject(dc, m_font.hfont());
    106         int faceLength = GetTextFace(dc, 0, 0);
    107         Vector<TCHAR> faceName(faceLength);
    108         GetTextFace(dc, faceLength, faceName.data());
    109         m_isSystemFont = !_tcscmp(faceName.data(), _T("Lucida Grande"));
    110         SelectObject(dc, oldFont);
    111         ReleaseDC(0, dc);
    112 
    113         if (shouldApplyMacAscentHack) {
    114             // This code comes from FontDataMac.mm. We only ever do this when running regression tests so that our metrics will match Mac.
    115 
    116             // We need to adjust Times, Helvetica, and Courier to closely match the
    117             // vertical metrics of their Microsoft counterparts that are the de facto
    118             // web standard. The AppKit adjustment of 20% is too big and is
    119             // incorrectly added to line spacing, so we use a 15% adjustment instead
    120             // and add it to the ascent.
    121             if (!_tcscmp(faceName.data(), _T("Times")) || !_tcscmp(faceName.data(), _T("Helvetica")) || !_tcscmp(faceName.data(), _T("Courier")))
    122                 fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f);
    123         }
    124     }
    125 
    126     m_ascent = lroundf(fAscent);
    127     m_descent = lroundf(fDescent);
    128     m_lineGap = lroundf(fLineGap);
    129     m_lineSpacing = m_ascent + m_descent + m_lineGap;
    130 
    131     // Measure the actual character "x", because AppKit synthesizes X height rather than getting it from the font.
    132     // Unfortunately, NSFont will round this for us so we don't quite get the right value.
    133     GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
    134     Glyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0;
    135     if (xGlyph) {
    136         CGRect xBox;
    137         CGFontGetGlyphBBoxes(font, &xGlyph, 1, &xBox);
    138         // Use the maximum of either width or height because "x" is nearly square
    139         // and web pages that foolishly use this metric for width will be laid out
    140         // poorly if we return an accurate height. Classic case is Times 13 point,
    141         // which has an "x" that is 7x6 pixels.
    142         m_xHeight = scaleEmToUnits(max(CGRectGetMaxX(xBox), CGRectGetMaxY(xBox)), m_unitsPerEm) * pointSize;
    143     } else {
    144         int iXHeight = CGFontGetXHeight(font);
    145         m_xHeight = scaleEmToUnits(iXHeight, m_unitsPerEm) * pointSize;
    146     }
    147 }
    148 
    149 void SimpleFontData::platformDestroy()
     58bool SimpleFontData::shouldApplyMacAscentHack()
    15059{
    151     if (!isCustomFont()) {
    152         DeleteObject(m_font.hfont());
    153         CGFontRelease(m_font.cgFont());
    154     }
    155 
    156     // We don't hash this on Win32, so it's effectively owned by us.
    157     delete m_smallCapsFontData;
    158 
    159     ScriptFreeCache(&m_scriptCache);
    160     delete m_scriptFontProperties;
     60    return g_shouldApplyMacAscentHack;
    16161}
    16262
     
    238138}
    239139
    240 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
    241 {
    242     if (m_font.useGDI()) {
    243         HDC hdc = GetDC(0);
    244         HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
    245         int width;
    246         GetCharWidthI(hdc, glyph, 1, 0, &width);
    247         SelectObject(hdc, oldFont);
    248         ReleaseDC(0, hdc);
    249         return width;
    250     }
    251 
    252     CGFontRef font = m_font.cgFont();
    253     float pointSize = m_font.size();
    254     CGSize advance;
    255     CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
    256     // FIXME: Need to add real support for printer fonts.
    257     bool isPrinterFont = false;
    258     wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
    259     return advance.width + m_syntheticBoldOffset;
    260 }
    261 
    262140SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
    263141{
  • trunk/WebCore/platform/win/DragImageCGWin.cpp

    r30053 r30056  
    11/*
    2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3737
    3838namespace WebCore {
    39 
    40 IntSize dragImageSize(DragImageRef image)
    41 {
    42     if (!image)
    43         return IntSize();
    44     BITMAP b;
    45     GetObject(image, sizeof(BITMAP), &b);
    46     return IntSize(b.bmWidth, b.bmHeight);
    47 }
    48 
    49 void deleteDragImage(DragImageRef image)
    50 {
    51     if (image)
    52         ::DeleteObject(image);
    53 }
    5439
    5540HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
     
    10792    CGImageRef srcImage;
    10893    IntSize srcSize = dragImageSize(image);
    109     IntSize dstSize((int)(srcSize.width() * scale.width()), (int)(srcSize.height() * scale.height()));
     94    IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height()));
    11095    HBITMAP hbmp = 0;
    11196    HDC dc = GetDC(0);
     
    140125}
    141126   
    142 DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
     127DragImageRef createDragImageFromImage(Image* img)
    143128{
    144     //We don't do this on windows as the dragimage is blended by the OS
    145     return image;
    146 }
    147        
    148 DragImageRef createDragImageFromImage(Image* img)
    149 {   
    150129    HBITMAP hbmp = 0;
    151130    HDC dc = GetDC(0);
     
    185164}
    186165   
    187 DragImageRef createDragImageIconForCachedImage(CachedImage*)
    188 {
    189     //FIXME: Provide icon for image type <rdar://problem/5015949>
    190     return 0;     
    191166}
    192    
    193 }
  • trunk/WebCore/platform/win/DragImageWin.cpp

    r29663 r30056  
    11/*
    2  * Copyright (C) 2007 Apple Inc.  All rights reserved.
     2 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3232#include "RetainPtr.h"
    3333
    34 #include <CoreGraphics/CoreGraphics.h>
    35 
    3634#include <windows.h>
    3735
     
    5351}
    5452
    55 HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
    56 {
    57     HBITMAP hbmp;
    58     BITMAPINFO bmpInfo = {0};
    59     bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    60     bmpInfo.bmiHeader.biWidth = size.width();
    61     bmpInfo.bmiHeader.biHeight = size.height();
    62     bmpInfo.bmiHeader.biPlanes = 1;
    63     bmpInfo.bmiHeader.biBitCount = 32;
    64     bmpInfo.bmiHeader.biCompression = BI_RGB;
    65     LPVOID bits;
    66     hbmp = CreateDIBSection(dc, &bmpInfo, DIB_RGB_COLORS, &bits, 0, 0);
    67 
    68     if (!targetRef)
    69         return hbmp;
    70 
    71     CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    72     CGContextRef bitmapContext = CGBitmapContextCreate(bits, bmpInfo.bmiHeader.biWidth, bmpInfo.bmiHeader.biHeight, 8,
    73                                                        bmpInfo.bmiHeader.biWidth * 4, deviceRGB,
    74                                                        kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
    75     CGColorSpaceRelease(deviceRGB);
    76     if (!bitmapContext) {
    77         DeleteObject(hbmp);
    78         return 0;
    79     }
    80 
    81     *targetRef = bitmapContext;
    82     return hbmp;
    83 }
    84 
    85 static CGContextRef createCgContextFromBitmap(HBITMAP bitmap)
    86 {
    87     BITMAP info;
    88     GetObject(bitmap, sizeof(info), &info);
    89     ASSERT(info.bmBitsPixel == 32);
    90 
    91     CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
    92     CGContextRef bitmapContext = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8,
    93                                                        info.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst);
    94     CGColorSpaceRelease(deviceRGB);
    95     return bitmapContext;
    96 }
    97 
    98 DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
    99 {
    100     // FIXME: due to the way drag images are done on windows we need
    101     // to preprocess the alpha channel <rdar://problem/5015946>
    102 
    103     if (!image)
    104         return 0;
    105     CGContextRef targetContext;
    106     CGContextRef srcContext;
    107     CGImageRef srcImage;
    108     IntSize srcSize = dragImageSize(image);
    109     IntSize dstSize((int)(srcSize.width() * scale.width()), (int)(srcSize.height() * scale.height()));
    110     HBITMAP hbmp = 0;
    111     HDC dc = GetDC(0);
    112     HDC dstDC = CreateCompatibleDC(dc);
    113     if (!dstDC)
    114         goto exit;
    115 
    116     hbmp = allocImage(dstDC, dstSize, &targetContext);
    117     if (!hbmp)
    118         goto exit;
    119 
    120     srcContext = createCgContextFromBitmap(image);
    121     srcImage = CGBitmapContextCreateImage(srcContext);
    122     CGRect rect;
    123     rect.origin.x = 0;
    124     rect.origin.y = 0;
    125     rect.size = dstSize;
    126     CGContextDrawImage(targetContext, rect, srcImage);
    127     CGImageRelease(srcImage);
    128     CGContextRelease(srcContext);
    129     CGContextRelease(targetContext);
    130     ::DeleteObject(image);
    131     image = 0;
    132 
    133 exit:
    134     if (!hbmp)
    135         hbmp = image;
    136     if (dstDC)
    137         DeleteDC(dstDC);
    138     ReleaseDC(0, dc);
    139     return hbmp;
    140 }
    141    
    14253DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
    14354{
     
    14657}
    14758       
    148 DragImageRef createDragImageFromImage(Image* img)
    149 {   
    150     HBITMAP hbmp = 0;
    151     HDC dc = GetDC(0);
    152     HDC workingDC = CreateCompatibleDC(dc);
    153     CGContextRef drawContext = 0;
    154     if (!workingDC)
    155         goto exit;
    156 
    157     hbmp = allocImage(workingDC, img->size(), &drawContext);
    158 
    159     if (!hbmp)
    160         goto exit;
    161 
    162     if (!drawContext) {
    163         ::DeleteObject(hbmp);
    164         hbmp = 0;
    165     }
    166 
    167     CGImageRef srcImage = img->getCGImageRef();
    168     CGRect rect;
    169     rect.size = img->size();
    170     rect.origin.x = 0;
    171     rect.origin.y = -rect.size.height;
    172     static const CGFloat white [] = {1.0, 1.0, 1.0, 1.0};
    173     CGContextScaleCTM(drawContext, 1, -1);
    174     CGContextSetFillColor(drawContext, white);
    175     CGContextFillRect(drawContext, rect);
    176     CGContextSetBlendMode(drawContext, kCGBlendModeNormal);
    177     CGContextDrawImage(drawContext, rect, srcImage);
    178     CGContextRelease(drawContext);
    179 
    180 exit:
    181     if (workingDC)
    182         DeleteDC(workingDC);
    183     ReleaseDC(0, dc);
    184     return hbmp;
    185 }
    186    
    18759DragImageRef createDragImageIconForCachedImage(CachedImage*)
    18860{
Note: See TracChangeset for help on using the changeset viewer.