| Differences between
and this patch
- WebCore/ChangeLog +73 lines
Lines 1-3 WebCore/ChangeLog_sec1
1
2008-01-29  Brent Fulgham  <bfulgham@gmail.com>
2
3
        Reviewed by NOBODY (OOPS!).
4
5
        First step towards reenabling Cairo support under Windows.
6
        - adds various PLATFORM guards to code that will not build
7
          under Cairo.
8
        - breaks some files into CG and Cairo-specific implementations.
9
        - provides some win32/Cairo support (but by no means a complete
10
          port -- yet).
11
12
        WARNING: NO TEST CASES ADDED OR CHANGED
13
14
        * WebCore.vcproj/WebCore.vcproj:
15
        * bridge/win/FrameCGWin.cpp: Copied from WebCore/bridge/win/FrameWin.cpp.
16
        (WebCore::imageFromSelection):
17
        * bridge/win/FrameCairoWin.cpp: Added.
18
        (WebCore::imageFromSelection):
19
        * bridge/win/FrameWin.cpp:
20
        (WebCore::computePageRectsForFrame):
21
        * platform/graphics/SimpleFontData.h:
22
        * platform/graphics/cairo/GraphicsContextCairo.cpp:
23
        * platform/graphics/cairo/GraphicsContextPlatformPrivate.h: Copied from WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp.
24
        * platform/graphics/win/FontCGWin.cpp: Copied from WebCore/platform/graphics/win/FontWin.cpp.
25
        (WebCore::Font::drawGlyphs):
26
        * platform/graphics/win/FontCairoWin.cpp: Added.
27
        (WebCore::Font::drawGlyphs):
28
        * platform/graphics/win/FontWin.cpp:
29
        * platform/graphics/win/GraphicsContextCGWin.cpp: Copied from WebCore/platform/graphics/win/GraphicsContextWin.cpp.
30
        (WebCore::CGContextWithHDC):
31
        (WebCore::GraphicsContext::getWindowsContext):
32
        (WebCore::GraphicsContext::releaseWindowsContext):
33
        (WebCore::GraphicsContextPlatformPrivate::concatCTM):
34
        (WebCore::setCGStrokeColor):
35
        (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
36
        * platform/graphics/win/GraphicsContextCairoWin.cpp: Added.
37
        (WebCore::GraphicsContext::GraphicsContext):
38
        (WebCore::GraphicsContext::getWindowsContext):
39
        (WebCore::GraphicsContext::inTransparencyLayer):
40
        (WebCore::GraphicsContext::releaseWindowsContext):
41
        (WebCore::GraphicsContextPlatformPrivate::concatCTM):
42
        (WebCore::GraphicsContext::drawFocusRing):
43
        (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar):
44
        * platform/graphics/win/GraphicsContextWin.cpp:
45
        (WebCore::GraphicsContextPlatformPrivate::scale):
46
        (WebCore::GraphicsContextPlatformPrivate::rotate):
47
        (WebCore::GraphicsContextPlatformPrivate::translate):
48
        * platform/graphics/win/ImageCGWin.cpp: Copied from WebCore/platform/graphics/win/ImageWin.cpp.
49
        (WebCore::BitmapImage::getHBITMAPOfSize):
50
        (WebCore::BitmapImage::drawFrameMatchingSourceSize):
51
        * platform/graphics/win/ImageCairoWin.cpp: Added.
52
        (WebCore::BitmapImage::getHBITMAPOfSize):
53
        (WebCore::BitmapImage::drawFrameMatchingSourceSize):
54
        * platform/graphics/win/ImageWin.cpp:
55
        * platform/graphics/win/SimpleFontDataCGWin.cpp: Copied from WebCore/platform/graphics/win/SimpleFontDataWin.cpp.
56
        (WebCore::scaleEmToUnits):
57
        (WebCore::SimpleFontData::platformInit):
58
        (WebCore::SimpleFontData::platformWidthForGlyph):
59
        * platform/graphics/win/SimpleFontDataCairoWin.cpp: Added.
60
        (WebCore::SimpleFontData::platformInit):
61
        (WebCore::SimpleFontData::platformDestroy):
62
        (WebCore::SimpleFontData::platformWidthForGlyph):
63
        * platform/graphics/win/SimpleFontDataWin.cpp:
64
        (WebCore::SimpleFontData::setShouldApplyMacAscentHack):
65
        (WebCore::SimpleFontData::shouldApplyMacAscentHack):
66
        * platform/win/DragImageCGWin.cpp: Copied from WebCore/platform/win/DragImageWin.cpp.
67
        (WebCore::scaleDragImage):
68
        (WebCore::createDragImageFromImage):
69
        * platform/win/DragImageCairoWin.cpp: Added.
70
        (WebCore::scaleDragImage):
71
        (WebCore::createDragImageFromImage):
72
        * platform/win/DragImageWin.cpp:
73
1
2008-01-29  Adam Roben  <aroben@apple.com>
74
2008-01-29  Adam Roben  <aroben@apple.com>
2
75
3
        Fix <rdar://5711136> Full-screen Flash on 1up.com is unresponsive
76
        Fix <rdar://5711136> Full-screen Flash on 1up.com is unresponsive
- WebCore/WebCore.vcproj/WebCore.vcproj +28 lines
Lines 3422-3427 WebCore/WebCore.vcproj/WebCore.vcproj_sec1
3422
					>
3422
					>
3423
				</File>
3423
				</File>
3424
				<File
3424
				<File
3425
					RelativePath="..\platform\win\DragImageCGWin.cpp"
3426
					>
3427
				</File>
3428
				<File
3425
					RelativePath="..\platform\win\EditorWin.cpp"
3429
					RelativePath="..\platform\win\EditorWin.cpp"
3426
					>
3430
					>
3427
				</File>
3431
				</File>
Lines 3757-3762 WebCore/WebCore.vcproj/WebCore.vcproj_sec2
3757
					>
3761
					>
3758
				</File>
3762
				</File>
3759
				<File
3763
				<File
3764
					RelativePath="..\platform\graphics\cg\GraphicsContextPlatformPrivate.h"
3765
					>
3766
				</File>
3767
				<File
3760
					RelativePath="..\platform\graphics\GraphicsContext.cpp"
3768
					RelativePath="..\platform\graphics\GraphicsContext.cpp"
3761
					>
3769
					>
3762
				</File>
3770
				</File>
Lines 3876-3881 WebCore/WebCore.vcproj/WebCore.vcproj_sec3
3876
						>
3884
						>
3877
					</File>
3885
					</File>
3878
					<File
3886
					<File
3887
						RelativePath="..\platform\graphics\win\FontCGWin.cpp"
3888
						>
3889
					</File>
3890
					<File
3879
						RelativePath="..\platform\graphics\win\FontCustomPlatformData.cpp"
3891
						RelativePath="..\platform\graphics\win\FontCustomPlatformData.cpp"
3880
						>
3892
						>
3881
					</File>
3893
					</File>
Lines 3932-3937 WebCore/WebCore.vcproj/WebCore.vcproj_sec4
3932
						>
3944
						>
3933
					</File>
3945
					</File>
3934
					<File
3946
					<File
3947
						RelativePath="..\platform\graphics\win\GraphicsContextCGWin.cpp"
3948
						>
3949
					</File>
3950
					<File
3935
						RelativePath="..\platform\graphics\win\GraphicsContextWin.cpp"
3951
						RelativePath="..\platform\graphics\win\GraphicsContextWin.cpp"
3936
						>
3952
						>
3937
					</File>
3953
					</File>
Lines 3940-3945 WebCore/WebCore.vcproj/WebCore.vcproj_sec5
3940
						>
3956
						>
3941
					</File>
3957
					</File>
3942
					<File
3958
					<File
3959
						RelativePath="..\platform\graphics\win\ImageCGWin.cpp"
3960
						>
3961
					</File>
3962
					<File
3943
						RelativePath="..\platform\graphics\win\ImageWin.cpp"
3963
						RelativePath="..\platform\graphics\win\ImageWin.cpp"
3944
						>
3964
						>
3945
					</File>
3965
					</File>
Lines 3964-3969 WebCore/WebCore.vcproj/WebCore.vcproj_sec6
3964
						>
3984
						>
3965
					</File>
3985
					</File>
3966
					<File
3986
					<File
3987
						RelativePath="..\platform\graphics\win\SimpleFontDataCGWin.cpp"
3988
						>
3989
					</File>
3990
					<File
3967
						RelativePath="..\platform\graphics\win\SimpleFontDataWin.cpp"
3991
						RelativePath="..\platform\graphics\win\SimpleFontDataWin.cpp"
3968
						>
3992
						>
3969
					</File>
3993
					</File>
Lines 6408-6413 WebCore/WebCore.vcproj/WebCore.vcproj_sec7
6408
				Name="win"
6432
				Name="win"
6409
				>
6433
				>
6410
				<File
6434
				<File
6435
					RelativePath="..\bridge\win\FrameCGWin.cpp"
6436
					>
6437
				</File>
6438
				<File
6411
					RelativePath="..\bridge\win\FrameWin.cpp"
6439
					RelativePath="..\bridge\win\FrameWin.cpp"
6412
					>
6440
					>
6413
				</File>
6441
				</File>
- WebCore/bridge/win/FrameCGWin.cpp +197 lines
Line 0 WebCore/bridge/win/FrameCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FrameWin.h"
28
29
#include <winsock2.h>
30
#include <windows.h>
31
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"
39
#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 "PluginDatabaseWin.h"
49
#include "PluginViewWin.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"
60
#include "GraphicsContext.h"
61
#include "Settings.h"
62
63
#if PLATFORM(CG)
64
#include <CoreGraphics/CoreGraphics.h>
65
#endif
66
67
using std::min;
68
using namespace KJS::Bindings;
69
70
namespace 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<PluginViewWin*>(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
}
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;
183
}
184
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
197
} // namespace WebCore
- WebCore/bridge/win/FrameCGWin.cpp -116 / +6 lines
Lines 1-5 WebCore/bridge/win/FrameCGWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 26-142 WebCore/bridge/win/FrameCGWin.cpp_sec2
26
#include "config.h"
26
#include "config.h"
27
#include "FrameWin.h"
27
#include "FrameWin.h"
28
28
29
#include <winsock2.h>
30
#include <windows.h>
29
#include <windows.h>
31
30
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"
39
#include "FrameView.h"
31
#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 "PluginDatabaseWin.h"
49
#include "PluginViewWin.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"
60
#include "GraphicsContext.h"
32
#include "GraphicsContext.h"
61
#include "Settings.h"
33
#include "Settings.h"
62
34
63
#if PLATFORM(CG)
64
#include <CoreGraphics/CoreGraphics.h>
35
#include <CoreGraphics/CoreGraphics.h>
65
#endif
66
36
67
using std::min;
37
using std::min;
68
using namespace KJS::Bindings;
69
38
70
namespace WebCore {
39
namespace WebCore {
71
40
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<PluginViewWin*>(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
}
139
140
static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc)
41
static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc)
141
{
42
{
142
    IntSize offset = view->scrollOffset();
43
    IntSize offset = view->scrollOffset();
Lines 152-158 HBITMAP imageFromSelection(Frame* frame, WebCore/bridge/win/FrameCGWin.cpp_sec3
152
{
53
{
153
    frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
54
    frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly);
154
    FloatRect fr = frame->selectionRect();
55
    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()));
156
58
157
    void* bits;
59
    void* bits;
158
    HDC hdc = CreateCompatibleDC(0);
60
    HDC hdc = CreateCompatibleDC(0);
Lines 160-169 HBITMAP imageFromSelection(Frame* frame, WebCore/bridge/win/FrameCGWin.cpp_sec4
160
    int h = ir.height();
62
    int h = ir.height();
161
    BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } };
63
    BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } };
162
64
163
    HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, (void**)&bits, 0, 0);
65
    HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
164
    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, hbmp);
66
    HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
165
    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
67
    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
166
    CGContextRef context = CGBitmapContextCreate((void*)bits, w, h,
68
    CGContextRef context = CGBitmapContextCreate(static_cast<void*>(bits), w, h,
167
        8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
69
        8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
168
    CGColorSpaceRelease(deviceRGB);
70
    CGColorSpaceRelease(deviceRGB);
169
    CGContextSaveGState(context);
71
    CGContextSaveGState(context);
Lines 182-197 HBITMAP imageFromSelection(Frame* frame, WebCore/bridge/win/FrameCGWin.cpp_sec5
182
    return hbmp;
84
    return hbmp;
183
}
85
}
184
86
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
197
} // namespace WebCore
87
} // namespace WebCore
- WebCore/bridge/win/FrameCairoWin.cpp +42 lines
Line 0 WebCore/bridge/win/FrameCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "FrameWin.h"
28
29
#include "EditorClient.h"
30
#include "NotImplemented.h"
31
32
using std::min;
33
34
namespace WebCore {
35
36
HBITMAP imageFromSelection(Frame* frame, bool forceBlackText)
37
{
38
    notImplemented();
39
    return 0;
40
}
41
42
} // namespace WebCore
- WebCore/bridge/win/FrameWin.cpp -56 / +6 lines
Lines 1-5 WebCore/bridge/win/FrameWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 60-69 WebCore/bridge/win/FrameWin.cpp_sec2
60
#include "GraphicsContext.h"
60
#include "GraphicsContext.h"
61
#include "Settings.h"
61
#include "Settings.h"
62
62
63
#if PLATFORM(CG)
64
#include <CoreGraphics/CoreGraphics.h>
65
#endif
66
67
using std::min;
63
using std::min;
68
using namespace KJS::Bindings;
64
using namespace KJS::Bindings;
69
65
Lines 84-90 KJS::Bindings::Instance* Frame::createSc WebCore/bridge/win/FrameWin.cpp_sec3
84
    return static_cast<PluginViewWin*>(widget)->bindingInstance();
80
    return static_cast<PluginViewWin*>(widget)->bindingInstance();
85
}
81
}
86
82
87
88
void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight)
83
void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight)
89
{
84
{
90
    ASSERT(frame);
85
    ASSERT(frame);
Lines 107-117 void computePageRectsForFrame(Frame* fra WebCore/bridge/win/FrameWin.cpp_sec4
107
        return;
102
        return;
108
    }
103
    }
109
    
104
    
110
    float ratio = (float)printRect.height() / (float)printRect.width();
105
    float ratio = static_cast<float>(printRect.height()) / static_cast<float>(printRect.width());
111
 
106
 
112
    float pageWidth  = (float) root->docWidth();
107
    float pageWidth  = static_cast<float>(root->docWidth());
113
    float pageHeight = pageWidth * ratio;
108
    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
115
    pageHeight -= (headerHeight + footerHeight);
110
    pageHeight -= (headerHeight + footerHeight);
116
111
117
    if (pageHeight <= 0) {
112
    if (pageHeight <= 0) {
Lines 126-187 void computePageRectsForFrame(Frame* fra WebCore/bridge/win/FrameWin.cpp_sec5
126
121
127
    
122
    
128
    // always return at least one page, since empty files should print a blank page
123
    // always return at least one page, since empty files should print a blank page
129
    float printedPagesHeight = 0.0;
124
    float printedPagesHeight = 0.0f;
130
    do {
125
    do {
131
        float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
126
        float proposedBottom = min(docHeight, printedPagesHeight + pageHeight);
132
        frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
127
        frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight);
133
        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
128
        currPageHeight = max(1.0f, proposedBottom - printedPagesHeight);
134
       
129
       
135
        pages.append(IntRect(0,printedPagesHeight,currPageWidth,currPageHeight));
130
        pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight));
136
        printedPagesHeight += currPageHeight;
131
        printedPagesHeight += currPageHeight;
137
    } while (printedPagesHeight < docHeight);
132
    } while (printedPagesHeight < docHeight);
138
}
133
}
139
134
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;
183
}
184
185
DragImageRef Frame::dragImageForSelection()
135
DragImageRef Frame::dragImageForSelection()
186
{    
136
{    
187
    if (selectionController()->isRange())
137
    if (selectionController()->isRange())
- WebCore/platform/graphics/SimpleFontData.h +1 lines
Lines 103-108 public: WebCore/platform/graphics/SimpleFontData.h_sec1
103
    SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
103
    SCRIPT_CACHE* scriptCache() const { return &m_scriptCache; }
104
104
105
    static void setShouldApplyMacAscentHack(bool);
105
    static void setShouldApplyMacAscentHack(bool);
106
    static bool shouldApplyMacAscentHack();
106
#endif
107
#endif
107
108
108
#if PLATFORM(GTK)
109
#if PLATFORM(GTK)
- WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp -46 / +7 lines
Lines 41-55 WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec1
41
#include <stdio.h>
41
#include <stdio.h>
42
#include <wtf/MathExtras.h>
42
#include <wtf/MathExtras.h>
43
43
44
#if PLATFORM(WIN)
45
#include <cairo-win32.h>
46
#endif
47
48
#if PLATFORM(GTK)
44
#if PLATFORM(GTK)
49
#include <gdk/gdk.h>
45
#include <gdk/gdk.h>
50
#include <pango/pango.h>
46
#include <pango/pango.h>
47
#elif PLATFORM(WIN)
48
#include <cairo-win32.h>
51
#endif
49
#endif
52
50
#include "GraphicsContextPlatformPrivateCairo.h"
53
51
54
#ifndef M_PI
52
#ifndef M_PI
55
#define M_PI 3.14159265358979323846
53
#define M_PI 3.14159265358979323846
Lines 57-75 WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec2
57
55
58
namespace WebCore {
56
namespace WebCore {
59
57
60
class GraphicsContextPlatformPrivate {
61
public:
62
    GraphicsContextPlatformPrivate();
63
    ~GraphicsContextPlatformPrivate();
64
65
    cairo_t* cr;
66
    Vector<float> layers;
67
68
#if PLATFORM(GTK)
69
    GdkEventExpose* expose;
70
#endif
71
};
72
73
static inline void setColor(cairo_t* cr, const Color& col)
58
static inline void setColor(cairo_t* cr, const Color& col)
74
{
59
{
75
    float red, green, blue, alpha;
60
    float red, green, blue, alpha;
Lines 86-119 static inline void fillRectSourceOver(ca WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec3
86
    cairo_fill(cr);
71
    cairo_fill(cr);
87
}
72
}
88
73
89
GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
90
    :  cr(0)
91
#if PLATFORM(GTK)
92
    , expose(0)
93
#endif
94
{
95
}
96
97
GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
98
{
99
    cairo_destroy(cr);
100
}
101
102
#if PLATFORM(WIN)
103
GraphicsContext::GraphicsContext(HDC dc)
104
    : m_common(createGraphicsContextPrivate())
105
    , m_data(new GraphicsContextPlatformPrivate)
106
{
107
    if (dc) {
108
        cairo_surface_t* surface = cairo_win32_surface_create(dc);
109
        m_data->cr = cairo_create(surface);
110
    } else {
111
        setPaintingDisabled(true);
112
        m_data->cr = 0;
113
    }
114
}
115
#endif
116
117
GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
74
GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
118
    : m_common(createGraphicsContextPrivate())
75
    : m_common(createGraphicsContextPrivate())
119
    , m_data(new GraphicsContextPlatformPrivate)
76
    , m_data(new GraphicsContextPlatformPrivate)
Lines 577-582 void GraphicsContext::setURLForRect(cons WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec4
577
    notImplemented();
534
    notImplemented();
578
}
535
}
579
536
537
#if PLATFORM(GTK)
538
// FIXME:  This should be moved to something like GraphicsContextCairoGTK.cpp,
539
// as there is a Windows implementation in platform/graphics/win/GraphicsContextCairoWin.cpp
580
void GraphicsContext::concatCTM(const AffineTransform& transform)
540
void GraphicsContext::concatCTM(const AffineTransform& transform)
581
{
541
{
582
    if (paintingDisabled())
542
    if (paintingDisabled())
Lines 586-591 void GraphicsContext::concatCTM(const Af WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec5
586
    const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
546
    const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
587
    cairo_transform(cr, matrix);
547
    cairo_transform(cr, matrix);
588
}
548
}
549
#endif
589
550
590
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
551
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
591
{
552
{
- WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h +924 lines
Line 0 WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h_sec1
1
/*
2
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
 * (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
 */
26
27
#include "config.h"
28
#include "GraphicsContext.h"
29
30
#if PLATFORM(CAIRO)
31
32
#include "CairoPath.h"
33
#include "FloatRect.h"
34
#include "Font.h"
35
#include "IntRect.h"
36
#include "NotImplemented.h"
37
#include "Path.h"
38
#include "SimpleFontData.h"
39
#include <cairo.h>
40
#include <math.h>
41
#include <stdio.h>
42
#include <wtf/MathExtras.h>
43
44
#if PLATFORM(WIN)
45
#include <cairo-win32.h>
46
#endif
47
48
#if PLATFORM(GTK)
49
#include <gdk/gdk.h>
50
#include <pango/pango.h>
51
#endif
52
53
54
#ifndef M_PI
55
#define M_PI 3.14159265358979323846
56
#endif
57
58
namespace WebCore {
59
60
class GraphicsContextPlatformPrivate {
61
public:
62
    GraphicsContextPlatformPrivate();
63
    ~GraphicsContextPlatformPrivate();
64
65
    cairo_t* cr;
66
    Vector<float> layers;
67
68
#if PLATFORM(GTK)
69
    GdkEventExpose* expose;
70
#endif
71
};
72
73
static inline void setColor(cairo_t* cr, const Color& col)
74
{
75
    float red, green, blue, alpha;
76
    col.getRGBA(red, green, blue, alpha);
77
    cairo_set_source_rgba(cr, red, green, blue, alpha);
78
}
79
80
// A fillRect helper
81
static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const Color& col)
82
{
83
    setColor(cr, col);
84
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
85
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
86
    cairo_fill(cr);
87
}
88
89
GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
90
    :  cr(0)
91
#if PLATFORM(GTK)
92
    , expose(0)
93
#endif
94
{
95
}
96
97
GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
98
{
99
    cairo_destroy(cr);
100
}
101
102
#if PLATFORM(WIN)
103
GraphicsContext::GraphicsContext(HDC dc)
104
    : m_common(createGraphicsContextPrivate())
105
    , m_data(new GraphicsContextPlatformPrivate)
106
{
107
    if (dc) {
108
        cairo_surface_t* surface = cairo_win32_surface_create(dc);
109
        m_data->cr = cairo_create(surface);
110
    } else {
111
        setPaintingDisabled(true);
112
        m_data->cr = 0;
113
    }
114
}
115
#endif
116
117
GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
118
    : m_common(createGraphicsContextPrivate())
119
    , m_data(new GraphicsContextPlatformPrivate)
120
{
121
    m_data->cr = cairo_reference(cr);
122
    setPaintingDisabled(!cr);
123
}
124
125
GraphicsContext::~GraphicsContext()
126
{
127
    destroyGraphicsContextPrivate(m_common);
128
    delete m_data;
129
}
130
131
cairo_t* GraphicsContext::platformContext() const
132
{
133
    return m_data->cr;
134
}
135
136
void GraphicsContext::savePlatformState()
137
{
138
    cairo_save(m_data->cr);
139
}
140
141
void GraphicsContext::restorePlatformState()
142
{
143
    cairo_restore(m_data->cr);
144
}
145
146
// Draws a filled rectangle with a stroked border.
147
void GraphicsContext::drawRect(const IntRect& rect)
148
{
149
    if (paintingDisabled())
150
        return;
151
152
    cairo_t* cr = m_data->cr;
153
    cairo_save(cr);
154
155
    if (fillColor().alpha())
156
        fillRectSourceOver(cr, rect, fillColor());
157
158
    if (strokeStyle() != NoStroke) {
159
        setColor(cr, strokeColor());
160
        FloatRect r(rect);
161
        r.inflate(-.5f);
162
        cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
163
        cairo_set_line_width(cr, 1.0);
164
        cairo_stroke(cr);
165
    }
166
167
    cairo_restore(cr);
168
}
169
170
// FIXME: Now that this is refactored, it should be shared by all contexts.
171
static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style)
172
{
173
    // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
174
    // works out.  For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
175
    // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
176
    // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
177
    if (style == DottedStroke || style == DashedStroke) {
178
        if (p1.x() == p2.x()) {
179
            p1.setY(p1.y() + strokeWidth);
180
            p2.setY(p2.y() - strokeWidth);
181
        }
182
        else {
183
            p1.setX(p1.x() + strokeWidth);
184
            p2.setX(p2.x() - strokeWidth);
185
        }
186
    }
187
188
    if (static_cast<int>(strokeWidth) % 2) {
189
        if (p1.x() == p2.x()) {
190
            // We're a vertical line.  Adjust our x.
191
            p1.setX(p1.x() + 0.5);
192
            p2.setX(p2.x() + 0.5);
193
        }
194
        else {
195
            // We're a horizontal line. Adjust our y.
196
            p1.setY(p1.y() + 0.5);
197
            p2.setY(p2.y() + 0.5);
198
        }
199
    }
200
}
201
202
// This is only used to draw borders.
203
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
204
{
205
    if (paintingDisabled())
206
        return;
207
208
    StrokeStyle style = strokeStyle();
209
    if (style == NoStroke)
210
        return;
211
212
    cairo_t* cr = m_data->cr;
213
    cairo_save(cr);
214
215
    float width = strokeThickness();
216
    if (width < 1)
217
        width = 1;
218
219
    FloatPoint p1 = point1;
220
    FloatPoint p2 = point2;
221
    bool isVerticalLine = (p1.x() == p2.x());
222
 
223
    adjustLineToPixelBoundaries(p1, p2, width, style);
224
    cairo_set_line_width(cr, width);
225
226
    int patWidth = 0;
227
    switch (style) {
228
    case NoStroke:
229
    case SolidStroke:
230
        break;
231
    case DottedStroke:
232
        patWidth = static_cast<int>(width);
233
        break;
234
    case DashedStroke:
235
        patWidth = 3*static_cast<int>(width);
236
        break;
237
    }
238
239
    setColor(cr, strokeColor());
240
241
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
242
243
    if (patWidth) {
244
        // Do a rect fill of our endpoints.  This ensures we always have the
245
        // appearance of being a border.  We then draw the actual dotted/dashed line.
246
        if (isVerticalLine) {
247
            fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
248
            fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
249
        } else {
250
            fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
251
            fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
252
        }
253
254
        // Example: 80 pixels with a width of 30 pixels.
255
        // Remainder is 20.  The maximum pixels of line we could paint
256
        // will be 50 pixels.
257
        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
258
        int remainder = distance%patWidth;
259
        int coverage = distance-remainder;
260
        int numSegments = coverage/patWidth;
261
262
        float patternOffset = 0;
263
        // Special case 1px dotted borders for speed.
264
        if (patWidth == 1)
265
            patternOffset = 1.0;
266
        else {
267
            bool evenNumberOfSegments = numSegments%2 == 0;
268
            if (remainder)
269
                evenNumberOfSegments = !evenNumberOfSegments;
270
            if (evenNumberOfSegments) {
271
                if (remainder) {
272
                    patternOffset += patWidth - remainder;
273
                    patternOffset += remainder/2;
274
                }
275
                else
276
                    patternOffset = patWidth/2;
277
            }
278
            else if (!evenNumberOfSegments) {
279
                if (remainder)
280
                    patternOffset = (patWidth - remainder)/2;
281
            }
282
        }
283
284
        double dash = patWidth;
285
        cairo_set_dash(cr, &dash, 1, patternOffset);
286
    }
287
288
    cairo_move_to(cr, p1.x(), p1.y());
289
    cairo_line_to(cr, p2.x(), p2.y());
290
291
    cairo_stroke(cr);
292
    cairo_restore(cr);
293
}
294
295
// This method is only used to draw the little circles used in lists.
296
void GraphicsContext::drawEllipse(const IntRect& rect)
297
{
298
    if (paintingDisabled())
299
        return;
300
301
    cairo_t* cr = m_data->cr;
302
    cairo_save(cr);
303
    float yRadius = .5 * rect.height();
304
    float xRadius = .5 * rect.width();
305
    cairo_translate(cr, rect.x() + xRadius, rect.y() + yRadius);
306
    cairo_scale(cr, xRadius, yRadius);
307
    cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI);
308
    cairo_restore(cr);
309
310
    if (fillColor().alpha()) {
311
        setColor(cr, fillColor());
312
        cairo_fill_preserve(cr);
313
    }
314
315
    if (strokeStyle() != NoStroke) {
316
        setColor(cr, strokeColor());
317
        cairo_set_line_width(cr, strokeThickness());
318
        cairo_stroke(cr);
319
    }
320
321
    cairo_new_path(cr);
322
}
323
324
// FIXME: This function needs to be adjusted to match the functionality on the Mac side.
325
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
326
{
327
    if (paintingDisabled())
328
        return;
329
330
    if (strokeStyle() == NoStroke)
331
        return;
332
333
    int x = rect.x();
334
    int y = rect.y();
335
    float w = rect.width();
336
#if 0 // FIXME: unused so far
337
    float h = rect.height();
338
    float scaleFactor = h / w;
339
    float reverseScaleFactor = w / h;
340
#endif
341
    float r = w / 2;
342
    float fa = startAngle;
343
    float falen =  fa + angleSpan;
344
345
    cairo_t* cr = m_data->cr;
346
    cairo_save(cr);
347
    cairo_arc_negative(cr, x + r, y + r, r, -fa * M_PI/180, -falen * M_PI/180);
348
    setColor(cr, strokeColor());
349
    cairo_set_line_width(cr, strokeThickness());
350
    cairo_stroke(cr);
351
    cairo_restore(cr);
352
}
353
354
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
355
{
356
    if (paintingDisabled())
357
        return;
358
359
    if (npoints <= 1)
360
        return;
361
362
    cairo_t* cr = m_data->cr;
363
364
    cairo_save(cr);
365
    cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
366
    cairo_move_to(cr, points[0].x(), points[0].y());
367
    for (size_t i = 1; i < npoints; i++)
368
        cairo_line_to(cr, points[i].x(), points[i].y());
369
    cairo_close_path(cr);
370
371
    if (fillColor().alpha()) {
372
        setColor(cr, fillColor());
373
        cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
374
        cairo_fill_preserve(cr);
375
    }
376
377
    if (strokeStyle() != NoStroke) {
378
        setColor(cr, strokeColor());
379
        cairo_set_line_width(cr, strokeThickness());
380
        cairo_stroke(cr);
381
    }
382
383
    cairo_new_path(cr);
384
    cairo_restore(cr);
385
}
386
387
void GraphicsContext::fillRect(const IntRect& rect, const Color& color)
388
{
389
    if (paintingDisabled())
390
        return;
391
392
    if (color.alpha())
393
        fillRectSourceOver(m_data->cr, rect, color);
394
}
395
396
void GraphicsContext::fillRect(const FloatRect& 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::clip(const IntRect& rect)
406
{
407
    if (paintingDisabled())
408
        return;
409
410
    cairo_t* cr = m_data->cr;
411
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
412
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
413
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
414
    cairo_clip(cr);
415
    cairo_set_fill_rule(cr, savedFillRule);
416
}
417
418
void GraphicsContext::drawFocusRing(const Color& color)
419
{
420
    if (paintingDisabled())
421
        return;
422
423
    int radius = (focusRingWidth() - 1) / 2;
424
    int offset = radius + focusRingOffset();
425
426
    const Vector<IntRect>& rects = focusRingRects();
427
    unsigned rectCount = rects.size();
428
    IntRect finalFocusRect;
429
    for (unsigned i = 0; i < rectCount; i++) {
430
        IntRect focusRect = rects[i];
431
        focusRect.inflate(offset);
432
        finalFocusRect.unite(focusRect);
433
    }
434
435
    cairo_t* cr = m_data->cr;
436
    cairo_save(cr);
437
    // FIXME: These rects should be rounded
438
    cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height());
439
440
    // Force the alpha to 50%.  This matches what the Mac does with outline rings.
441
    Color ringColor(color.red(), color.green(), color.blue(), 127);
442
    setColor(cr, ringColor);
443
    cairo_stroke(cr);
444
    cairo_restore(cr);
445
}
446
447
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
448
{
449
    if (paintingDisabled())
450
        return;
451
452
    // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659
453
    StrokeStyle savedStrokeStyle = strokeStyle();
454
    setStrokeStyle(SolidStroke);
455
456
    IntPoint endPoint = origin + IntSize(width, 0);
457
    drawLine(origin, endPoint);
458
459
    setStrokeStyle(savedStrokeStyle);
460
}
461
462
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
463
{
464
    if (paintingDisabled())
465
        return;
466
467
#if PLATFORM(GTK)
468
    cairo_t* cr = m_data->cr;
469
    cairo_save(cr);
470
471
    // Convention is green for grammar, red for spelling
472
    // These need to become configurable
473
    if (grammar)
474
        cairo_set_source_rgb(cr, 0, 1, 0);
475
    else
476
        cairo_set_source_rgb(cr, 1, 0, 0);
477
478
    // We ignore most of the provided constants in favour of the platform style
479
    pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
480
481
    cairo_restore(cr);
482
#else
483
    notImplemented();
484
#endif
485
}
486
487
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
488
{
489
    FloatRect result;
490
    double x = frect.x();
491
    double y = frect.y();
492
    cairo_t* cr = m_data->cr;
493
    cairo_user_to_device(cr, &x, &y);
494
    x = round(x);
495
    y = round(y);
496
    cairo_device_to_user(cr, &x, &y);
497
    result.setX(static_cast<float>(x));
498
    result.setY(static_cast<float>(y));
499
    x = frect.width();
500
    y = frect.height();
501
    cairo_user_to_device_distance(cr, &x, &y);
502
    x = round(x);
503
    y = round(y);
504
    cairo_device_to_user_distance(cr, &x, &y);
505
    result.setWidth(static_cast<float>(x));
506
    result.setHeight(static_cast<float>(y));
507
    return result;
508
}
509
510
void GraphicsContext::translate(float x, float y)
511
{
512
    if (paintingDisabled())
513
        return;
514
515
    cairo_t* cr = m_data->cr;
516
    cairo_translate(cr, x, y);
517
}
518
519
IntPoint GraphicsContext::origin()
520
{
521
    cairo_matrix_t matrix;
522
    cairo_t* cr = m_data->cr;
523
    cairo_get_matrix(cr, &matrix);
524
    return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));
525
}
526
527
void GraphicsContext::setPlatformFillColor(const Color& col)
528
{
529
    // FIXME: this is probably a no-op but I'm not sure
530
    // notImplemented(); // commented-out because it's chatty and clutters output
531
}
532
533
void GraphicsContext::setPlatformStrokeColor(const Color& col)
534
{
535
    // FIXME: this is probably a no-op but I'm not sure
536
    //notImplemented(); // commented-out because it's chatty and clutters output
537
}
538
539
void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
540
{
541
    if (paintingDisabled())
542
        return;
543
544
    cairo_set_line_width(m_data->cr, strokeThickness);
545
}
546
547
void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
548
{
549
    static double dashPattern[] = {5.0, 5.0};
550
    static double dotPattern[] = {1.0, 1.0};
551
552
    if (paintingDisabled())
553
        return;
554
555
    switch (strokeStyle) {
556
    case NoStroke:
557
        // FIXME: is it the right way to emulate NoStroke?
558
        cairo_set_line_width(m_data->cr, 0);
559
        break;
560
    case SolidStroke:
561
        cairo_set_dash(m_data->cr, 0, 0, 0);
562
        break;
563
    case DottedStroke:
564
        cairo_set_dash(m_data->cr, dotPattern, 2, 0);
565
        break;
566
    case DashedStroke:
567
        cairo_set_dash(m_data->cr, dashPattern, 2, 0);
568
        break;
569
    default:
570
        notImplemented();
571
        break;
572
    }
573
}
574
575
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
576
{
577
    notImplemented();
578
}
579
580
void GraphicsContext::concatCTM(const AffineTransform& transform)
581
{
582
    if (paintingDisabled())
583
        return;
584
585
    cairo_t* cr = m_data->cr;
586
    const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
587
    cairo_transform(cr, matrix);
588
}
589
590
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
591
{
592
    if (paintingDisabled())
593
        return;
594
595
    clip(rect);
596
597
    Path p;
598
    FloatRect r(rect);
599
    // Add outer ellipse
600
    p.addEllipse(r);
601
    // Add inner ellipse
602
    r.inflate(-thickness);
603
    p.addEllipse(r);
604
    addPath(p);
605
606
    cairo_t* cr = m_data->cr;
607
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
608
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
609
    cairo_clip(cr);
610
    cairo_set_fill_rule(cr, savedFillRule);
611
}
612
613
614
void GraphicsContext::setShadow(IntSize const&, int, Color const&)
615
{
616
    notImplemented();
617
}
618
619
void GraphicsContext::clearShadow()
620
{
621
    notImplemented();
622
}
623
624
void GraphicsContext::beginTransparencyLayer(float opacity)
625
{
626
    if (paintingDisabled())
627
        return;
628
629
    cairo_t* cr = m_data->cr;
630
    cairo_push_group(cr);
631
    m_data->layers.append(opacity);
632
}
633
634
void GraphicsContext::endTransparencyLayer()
635
{
636
    if (paintingDisabled())
637
        return;
638
639
    cairo_t* cr = m_data->cr;
640
641
    cairo_pop_group_to_source(cr);
642
    cairo_paint_with_alpha(cr, m_data->layers.last());
643
    m_data->layers.removeLast();
644
}
645
646
void GraphicsContext::clearRect(const FloatRect& rect)
647
{
648
    if (paintingDisabled())
649
        return;
650
651
    cairo_t* cr = m_data->cr;
652
653
    cairo_save(cr);
654
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
655
    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
656
    cairo_fill(cr);
657
    cairo_restore(cr);
658
}
659
660
void GraphicsContext::strokeRect(const FloatRect& rect, float width)
661
{
662
    if (paintingDisabled())
663
        return;
664
665
    cairo_t* cr = m_data->cr;
666
    cairo_save(cr);
667
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
668
    setColor(cr, strokeColor());
669
    cairo_set_line_width(cr, width);
670
    cairo_stroke(cr);
671
    cairo_restore(cr);
672
}
673
674
void GraphicsContext::setLineCap(LineCap lineCap)
675
{
676
    if (paintingDisabled())
677
        return;
678
679
    cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;
680
    switch (lineCap) {
681
        case ButtCap:
682
            // no-op
683
            break;
684
        case RoundCap:
685
            cairoCap = CAIRO_LINE_CAP_ROUND;
686
            break;
687
        case SquareCap:
688
            cairoCap = CAIRO_LINE_CAP_SQUARE;
689
            break;
690
    }
691
    cairo_set_line_cap(m_data->cr, cairoCap);
692
}
693
694
void GraphicsContext::setLineJoin(LineJoin lineJoin)
695
{
696
    if (paintingDisabled())
697
        return;
698
699
    cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;
700
    switch (lineJoin) {
701
        case MiterJoin:
702
            // no-op
703
            break;
704
        case RoundJoin:
705
            cairoJoin = CAIRO_LINE_JOIN_ROUND;
706
            break;
707
        case BevelJoin:
708
            cairoJoin = CAIRO_LINE_JOIN_BEVEL;
709
            break;
710
    }
711
    cairo_set_line_join(m_data->cr, cairoJoin);
712
}
713
714
void GraphicsContext::setMiterLimit(float miter)
715
{
716
    if (paintingDisabled())
717
        return;
718
719
    cairo_set_miter_limit(m_data->cr, miter);
720
}
721
722
void GraphicsContext::setAlpha(float)
723
{
724
    notImplemented();
725
}
726
727
static inline cairo_operator_t toCairoOperator(CompositeOperator op)
728
{
729
    switch (op) {
730
        case CompositeClear:
731
            return CAIRO_OPERATOR_CLEAR;
732
        case CompositeCopy:
733
            return CAIRO_OPERATOR_SOURCE;
734
        case CompositeSourceOver:
735
            return CAIRO_OPERATOR_OVER;
736
        case CompositeSourceIn:
737
            return CAIRO_OPERATOR_IN;
738
        case CompositeSourceOut:
739
            return CAIRO_OPERATOR_OUT;
740
        case CompositeSourceAtop:
741
            return CAIRO_OPERATOR_ATOP;
742
        case CompositeDestinationOver:
743
            return CAIRO_OPERATOR_DEST_OVER;
744
        case CompositeDestinationIn:
745
            return CAIRO_OPERATOR_DEST_IN;
746
        case CompositeDestinationOut:
747
            return CAIRO_OPERATOR_DEST_OUT;
748
        case CompositeDestinationAtop:
749
            return CAIRO_OPERATOR_DEST_ATOP;
750
        case CompositeXOR:
751
            return CAIRO_OPERATOR_XOR;
752
        case CompositePlusDarker:
753
            return CAIRO_OPERATOR_SATURATE;
754
        case CompositeHighlight:
755
            // There is no Cairo equivalent for CompositeHighlight.
756
            return CAIRO_OPERATOR_OVER;
757
        case CompositePlusLighter:
758
            return CAIRO_OPERATOR_ADD;
759
        default:
760
            return CAIRO_OPERATOR_SOURCE;
761
    }
762
}
763
764
void GraphicsContext::setCompositeOperation(CompositeOperator op)
765
{
766
    if (paintingDisabled())
767
        return;
768
769
    cairo_set_operator(m_data->cr, toCairoOperator(op));
770
}
771
772
void GraphicsContext::beginPath()
773
{
774
    if (paintingDisabled())
775
        return;
776
777
    cairo_t* cr = m_data->cr;
778
    cairo_new_path(cr);
779
}
780
781
void GraphicsContext::addPath(const Path& path)
782
{
783
    if (paintingDisabled())
784
        return;
785
786
    cairo_t* cr = m_data->cr;
787
    cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
788
    cairo_append_path(cr, p);
789
    cairo_path_destroy(p);
790
}
791
792
void GraphicsContext::clip(const Path& path)
793
{
794
    if (paintingDisabled())
795
        return;
796
797
    cairo_t* cr = m_data->cr;
798
    cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
799
    cairo_append_path(cr, p);
800
    cairo_path_destroy(p);
801
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
802
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
803
    cairo_clip(cr);
804
    cairo_set_fill_rule(cr, savedFillRule);
805
}
806
807
void GraphicsContext::clipOut(const Path& path)
808
{
809
    if (paintingDisabled())
810
        return;
811
812
    cairo_t* cr = m_data->cr;
813
    double x1, y1, x2, y2;
814
    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
815
    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
816
    addPath(path);
817
818
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
819
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
820
    cairo_clip(cr);
821
    cairo_set_fill_rule(cr, savedFillRule);
822
}
823
824
void GraphicsContext::rotate(float radians)
825
{
826
    if (paintingDisabled())
827
        return;
828
829
    cairo_rotate(m_data->cr, radians);
830
}
831
832
void GraphicsContext::scale(const FloatSize& size)
833
{
834
    if (paintingDisabled())
835
        return;
836
837
    cairo_scale(m_data->cr, size.width(), size.height());
838
}
839
840
void GraphicsContext::clipOut(const IntRect& r)
841
{
842
    if (paintingDisabled())
843
        return;
844
845
    cairo_t* cr = m_data->cr;
846
    double x1, y1, x2, y2;
847
    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
848
    cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1);
849
    cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
850
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
851
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
852
    cairo_clip(cr);
853
    cairo_set_fill_rule(cr, savedFillRule);
854
}
855
856
void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
857
{
858
    if (paintingDisabled())
859
        return;
860
861
    Path p;
862
    p.addEllipse(r);
863
    clipOut(p);
864
}
865
866
void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
867
{
868
    if (paintingDisabled())
869
        return;
870
871
    cairo_t* cr = m_data->cr;
872
    cairo_save(cr);
873
    beginPath();
874
    addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
875
    setColor(cr, color);
876
    cairo_fill(cr);
877
    cairo_restore(cr);
878
}
879
880
#if PLATFORM(GTK)
881
void GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose)
882
{
883
    m_data->expose = expose;
884
}
885
886
GdkEventExpose* GraphicsContext::gdkExposeEvent() const
887
{
888
    return m_data->expose;
889
}
890
891
GdkDrawable* GraphicsContext::gdkDrawable() const
892
{
893
    if (!m_data->expose)
894
        return 0;
895
896
    return GDK_DRAWABLE(m_data->expose->window);
897
}
898
899
IntPoint GraphicsContext::translatePoint(const IntPoint& point) const
900
{
901
    cairo_matrix_t tm;
902
    cairo_get_matrix(m_data->cr, &tm);
903
    double x = point.x();
904
    double y = point.y();
905
906
    cairo_matrix_transform_point(&tm, &x, &y);
907
    return IntPoint(x, y);
908
}
909
#endif
910
911
void GraphicsContext::setUseAntialiasing(bool enable)
912
{
913
    if (paintingDisabled())
914
        return;
915
916
    // When true, use the default Cairo backend antialias mode (usually this
917
    // enables standard 'grayscale' antialiasing); false to explicitly disable
918
    // antialiasing. This is the same strategy as used in drawConvexPolygon().
919
    cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
920
}
921
922
} // namespace WebCore
923
924
#endif // PLATFORM(CAIRO)
- WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h -866 / +28 lines
Lines 1-6 WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h_sec1
1
/*
1
/*
2
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
2
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
3
 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4
 * Copyright (C) 2008 Brent Fulgham <bfulgham@gmail.com>
4
 *
5
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
Lines 25-923 WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h_sec2
25
 */
26
 */
26
27
27
#include "config.h"
28
#include "config.h"
28
#include "GraphicsContext.h"
29
29
30
#if PLATFORM(CAIRO)
30
#if PLATFORM(CAIRO)
31
31
32
#include "CairoPath.h"
32
#include "GraphicsContext.h"
33
#include "FloatRect.h"
33
34
#include "Font.h"
35
#include "IntRect.h"
36
#include "NotImplemented.h"
37
#include "Path.h"
38
#include "SimpleFontData.h"
39
#include <cairo.h>
34
#include <cairo.h>
40
#include <math.h>
35
#include <math.h>
41
#include <stdio.h>
36
#include <stdio.h>
42
#include <wtf/MathExtras.h>
37
#include <wtf/MathExtras.h>
43
38
44
#if PLATFORM(WIN)
45
#include <cairo-win32.h>
46
#endif
47
48
#if PLATFORM(GTK)
39
#if PLATFORM(GTK)
49
#include <gdk/gdk.h>
40
#include <gdk/gdk.h>
50
#include <pango/pango.h>
41
#include <pango/pango.h>
51
#endif
42
#elif PLATFORM(WIN)
52
43
#include <cairo-win32.h>
53
54
#ifndef M_PI
55
#define M_PI 3.14159265358979323846
56
#endif
44
#endif
57
45
58
namespace WebCore {
46
namespace WebCore {
59
47
60
class GraphicsContextPlatformPrivate {
48
class GraphicsContextPlatformPrivate {
61
public:
49
public:
62
    GraphicsContextPlatformPrivate();
50
    GraphicsContextPlatformPrivate()
63
    ~GraphicsContextPlatformPrivate();
51
        :  cr(0)
64
65
    cairo_t* cr;
66
    Vector<float> layers;
67
68
#if PLATFORM(GTK)
69
    GdkEventExpose* expose;
70
#endif
71
};
72
73
static inline void setColor(cairo_t* cr, const Color& col)
74
{
75
    float red, green, blue, alpha;
76
    col.getRGBA(red, green, blue, alpha);
77
    cairo_set_source_rgba(cr, red, green, blue, alpha);
78
}
79
80
// A fillRect helper
81
static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const Color& col)
82
{
83
    setColor(cr, col);
84
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
85
    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
86
    cairo_fill(cr);
87
}
88
89
GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
90
    :  cr(0)
91
#if PLATFORM(GTK)
52
#if PLATFORM(GTK)
92
    , expose(0)
53
        , expose(0)
93
#endif
54
#elif PLATFORM(WIN)
94
{
55
        // NOTE:  These may note be needed: review and remove once Cairo implementation is complete
95
}
56
        , m_hdc(0)
96
57
        , m_transparencyCount(0)
97
GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
58
#endif
98
{
59
    {
99
    cairo_destroy(cr);
100
}
101
102
#if PLATFORM(WIN)
103
GraphicsContext::GraphicsContext(HDC dc)
104
    : m_common(createGraphicsContextPrivate())
105
    , m_data(new GraphicsContextPlatformPrivate)
106
{
107
    if (dc) {
108
        cairo_surface_t* surface = cairo_win32_surface_create(dc);
109
        m_data->cr = cairo_create(surface);
110
    } else {
111
        setPaintingDisabled(true);
112
        m_data->cr = 0;
113
    }
114
}
115
#endif
116
117
GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)
118
    : m_common(createGraphicsContextPrivate())
119
    , m_data(new GraphicsContextPlatformPrivate)
120
{
121
    m_data->cr = cairo_reference(cr);
122
    setPaintingDisabled(!cr);
123
}
124
125
GraphicsContext::~GraphicsContext()
126
{
127
    destroyGraphicsContextPrivate(m_common);
128
    delete m_data;
129
}
130
131
cairo_t* GraphicsContext::platformContext() const
132
{
133
    return m_data->cr;
134
}
135
136
void GraphicsContext::savePlatformState()
137
{
138
    cairo_save(m_data->cr);
139
}
140
141
void GraphicsContext::restorePlatformState()
142
{
143
    cairo_restore(m_data->cr);
144
}
145
146
// Draws a filled rectangle with a stroked border.
147
void GraphicsContext::drawRect(const IntRect& rect)
148
{
149
    if (paintingDisabled())
150
        return;
151
152
    cairo_t* cr = m_data->cr;
153
    cairo_save(cr);
154
155
    if (fillColor().alpha())
156
        fillRectSourceOver(cr, rect, fillColor());
157
158
    if (strokeStyle() != NoStroke) {
159
        setColor(cr, strokeColor());
160
        FloatRect r(rect);
161
        r.inflate(-.5f);
162
        cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
163
        cairo_set_line_width(cr, 1.0);
164
        cairo_stroke(cr);
165
    }
166
167
    cairo_restore(cr);
168
}
169
170
// FIXME: Now that this is refactored, it should be shared by all contexts.
171
static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style)
172
{
173
    // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic
174
    // works out.  For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,
175
    // (50+53)/2 = 103/2 = 51 when we want 51.5.  It is always true that an even width gave
176
    // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.
177
    if (style == DottedStroke || style == DashedStroke) {
178
        if (p1.x() == p2.x()) {
179
            p1.setY(p1.y() + strokeWidth);
180
            p2.setY(p2.y() - strokeWidth);
181
        }
182
        else {
183
            p1.setX(p1.x() + strokeWidth);
184
            p2.setX(p2.x() - strokeWidth);
185
        }
186
    }
187
188
    if (static_cast<int>(strokeWidth) % 2) {
189
        if (p1.x() == p2.x()) {
190
            // We're a vertical line.  Adjust our x.
191
            p1.setX(p1.x() + 0.5);
192
            p2.setX(p2.x() + 0.5);
193
        }
194
        else {
195
            // We're a horizontal line. Adjust our y.
196
            p1.setY(p1.y() + 0.5);
197
            p2.setY(p2.y() + 0.5);
198
        }
199
    }
200
}
201
202
// This is only used to draw borders.
203
void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
204
{
205
    if (paintingDisabled())
206
        return;
207
208
    StrokeStyle style = strokeStyle();
209
    if (style == NoStroke)
210
        return;
211
212
    cairo_t* cr = m_data->cr;
213
    cairo_save(cr);
214
215
    float width = strokeThickness();
216
    if (width < 1)
217
        width = 1;
218
219
    FloatPoint p1 = point1;
220
    FloatPoint p2 = point2;
221
    bool isVerticalLine = (p1.x() == p2.x());
222
 
223
    adjustLineToPixelBoundaries(p1, p2, width, style);
224
    cairo_set_line_width(cr, width);
225
226
    int patWidth = 0;
227
    switch (style) {
228
    case NoStroke:
229
    case SolidStroke:
230
        break;
231
    case DottedStroke:
232
        patWidth = static_cast<int>(width);
233
        break;
234
    case DashedStroke:
235
        patWidth = 3*static_cast<int>(width);
236
        break;
237
    }
238
239
    setColor(cr, strokeColor());
240
241
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
242
243
    if (patWidth) {
244
        // Do a rect fill of our endpoints.  This ensures we always have the
245
        // appearance of being a border.  We then draw the actual dotted/dashed line.
246
        if (isVerticalLine) {
247
            fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());
248
            fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());
249
        } else {
250
            fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());
251
            fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());
252
        }
253
254
        // Example: 80 pixels with a width of 30 pixels.
255
        // Remainder is 20.  The maximum pixels of line we could paint
256
        // will be 50 pixels.
257
        int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);
258
        int remainder = distance%patWidth;
259
        int coverage = distance-remainder;
260
        int numSegments = coverage/patWidth;
261
262
        float patternOffset = 0;
263
        // Special case 1px dotted borders for speed.
264
        if (patWidth == 1)
265
            patternOffset = 1.0;
266
        else {
267
            bool evenNumberOfSegments = numSegments%2 == 0;
268
            if (remainder)
269
                evenNumberOfSegments = !evenNumberOfSegments;
270
            if (evenNumberOfSegments) {
271
                if (remainder) {
272
                    patternOffset += patWidth - remainder;
273
                    patternOffset += remainder/2;
274
                }
275
                else
276
                    patternOffset = patWidth/2;
277
            }
278
            else if (!evenNumberOfSegments) {
279
                if (remainder)
280
                    patternOffset = (patWidth - remainder)/2;
281
            }
282
        }
283
284
        double dash = patWidth;
285
        cairo_set_dash(cr, &dash, 1, patternOffset);
286
    }
287
288
    cairo_move_to(cr, p1.x(), p1.y());
289
    cairo_line_to(cr, p2.x(), p2.y());
290
291
    cairo_stroke(cr);
292
    cairo_restore(cr);
293
}
294
295
// This method is only used to draw the little circles used in lists.
296
void GraphicsContext::drawEllipse(const IntRect& rect)
297
{
298
    if (paintingDisabled())
299
        return;
300
301
    cairo_t* cr = m_data->cr;
302
    cairo_save(cr);
303
    float yRadius = .5 * rect.height();
304
    float xRadius = .5 * rect.width();
305
    cairo_translate(cr, rect.x() + xRadius, rect.y() + yRadius);
306
    cairo_scale(cr, xRadius, yRadius);
307
    cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI);
308
    cairo_restore(cr);
309
310
    if (fillColor().alpha()) {
311
        setColor(cr, fillColor());
312
        cairo_fill_preserve(cr);
313
    }
314
315
    if (strokeStyle() != NoStroke) {
316
        setColor(cr, strokeColor());
317
        cairo_set_line_width(cr, strokeThickness());
318
        cairo_stroke(cr);
319
    }
320
321
    cairo_new_path(cr);
322
}
323
324
// FIXME: This function needs to be adjusted to match the functionality on the Mac side.
325
void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
326
{
327
    if (paintingDisabled())
328
        return;
329
330
    if (strokeStyle() == NoStroke)
331
        return;
332
333
    int x = rect.x();
334
    int y = rect.y();
335
    float w = rect.width();
336
#if 0 // FIXME: unused so far
337
    float h = rect.height();
338
    float scaleFactor = h / w;
339
    float reverseScaleFactor = w / h;
340
#endif
341
    float r = w / 2;
342
    float fa = startAngle;
343
    float falen =  fa + angleSpan;
344
345
    cairo_t* cr = m_data->cr;
346
    cairo_save(cr);
347
    cairo_arc_negative(cr, x + r, y + r, r, -fa * M_PI/180, -falen * M_PI/180);
348
    setColor(cr, strokeColor());
349
    cairo_set_line_width(cr, strokeThickness());
350
    cairo_stroke(cr);
351
    cairo_restore(cr);
352
}
353
354
void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
355
{
356
    if (paintingDisabled())
357
        return;
358
359
    if (npoints <= 1)
360
        return;
361
362
    cairo_t* cr = m_data->cr;
363
364
    cairo_save(cr);
365
    cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
366
    cairo_move_to(cr, points[0].x(), points[0].y());
367
    for (size_t i = 1; i < npoints; i++)
368
        cairo_line_to(cr, points[i].x(), points[i].y());
369
    cairo_close_path(cr);
370
371
    if (fillColor().alpha()) {
372
        setColor(cr, fillColor());
373
        cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
374
        cairo_fill_preserve(cr);
375
    }
376
377
    if (strokeStyle() != NoStroke) {
378
        setColor(cr, strokeColor());
379
        cairo_set_line_width(cr, strokeThickness());
380
        cairo_stroke(cr);
381
    }
60
    }
382
61
383
    cairo_new_path(cr);
62
    ~GraphicsContextPlatformPrivate()
384
    cairo_restore(cr);
63
    {
385
}
64
        cairo_destroy(cr);
386
387
void GraphicsContext::fillRect(const IntRect& rect, const Color& color)
388
{
389
    if (paintingDisabled())
390
        return;
391
392
    if (color.alpha())
393
        fillRectSourceOver(m_data->cr, rect, color);
394
}
395
396
void GraphicsContext::fillRect(const FloatRect& 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::clip(const IntRect& rect)
406
{
407
    if (paintingDisabled())
408
        return;
409
410
    cairo_t* cr = m_data->cr;
411
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
412
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
413
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
414
    cairo_clip(cr);
415
    cairo_set_fill_rule(cr, savedFillRule);
416
}
417
418
void GraphicsContext::drawFocusRing(const Color& color)
419
{
420
    if (paintingDisabled())
421
        return;
422
423
    int radius = (focusRingWidth() - 1) / 2;
424
    int offset = radius + focusRingOffset();
425
426
    const Vector<IntRect>& rects = focusRingRects();
427
    unsigned rectCount = rects.size();
428
    IntRect finalFocusRect;
429
    for (unsigned i = 0; i < rectCount; i++) {
430
        IntRect focusRect = rects[i];
431
        focusRect.inflate(offset);
432
        finalFocusRect.unite(focusRect);
433
    }
65
    }
434
66
435
    cairo_t* cr = m_data->cr;
67
#if PLATFORM(WIN)
436
    cairo_save(cr);
68
    // On Windows, we need to update the HDC for form controls to draw in the right place.
437
    // FIXME: These rects should be rounded
69
    void beginTransparencyLayer() { m_transparencyCount++; }
438
    cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height());
70
    void endTransparencyLayer() { m_transparencyCount--; }
439
440
    // Force the alpha to 50%.  This matches what the Mac does with outline rings.
441
    Color ringColor(color.red(), color.green(), color.blue(), 127);
442
    setColor(cr, ringColor);
443
    cairo_stroke(cr);
444
    cairo_restore(cr);
445
}
446
447
void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
448
{
449
    if (paintingDisabled())
450
        return;
451
452
    // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659
453
    StrokeStyle savedStrokeStyle = strokeStyle();
454
    setStrokeStyle(SolidStroke);
455
456
    IntPoint endPoint = origin + IntSize(width, 0);
457
    drawLine(origin, endPoint);
458
459
    setStrokeStyle(savedStrokeStyle);
460
}
461
462
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
463
{
464
    if (paintingDisabled())
465
        return;
466
467
#if PLATFORM(GTK)
468
    cairo_t* cr = m_data->cr;
469
    cairo_save(cr);
470
471
    // Convention is green for grammar, red for spelling
472
    // These need to become configurable
473
    if (grammar)
474
        cairo_set_source_rgb(cr, 0, 1, 0);
475
    else
476
        cairo_set_source_rgb(cr, 1, 0, 0);
477
478
    // We ignore most of the provided constants in favour of the platform style
479
    pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);
480
481
    cairo_restore(cr);
482
#else
483
    notImplemented();
484
#endif
71
#endif
485
}
486
72
487
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
73
    cairo_t* cr;
488
{
74
    Vector<float> layers;
489
    FloatRect result;
490
    double x = frect.x();
491
    double y = frect.y();
492
    cairo_t* cr = m_data->cr;
493
    cairo_user_to_device(cr, &x, &y);
494
    x = round(x);
495
    y = round(y);
496
    cairo_device_to_user(cr, &x, &y);
497
    result.setX(static_cast<float>(x));
498
    result.setY(static_cast<float>(y));
499
    x = frect.width();
500
    y = frect.height();
501
    cairo_user_to_device_distance(cr, &x, &y);
502
    x = round(x);
503
    y = round(y);
504
    cairo_device_to_user_distance(cr, &x, &y);
505
    result.setWidth(static_cast<float>(x));
506
    result.setHeight(static_cast<float>(y));
507
    return result;
508
}
509
510
void GraphicsContext::translate(float x, float y)
511
{
512
    if (paintingDisabled())
513
        return;
514
515
    cairo_t* cr = m_data->cr;
516
    cairo_translate(cr, x, y);
517
}
518
519
IntPoint GraphicsContext::origin()
520
{
521
    cairo_matrix_t matrix;
522
    cairo_t* cr = m_data->cr;
523
    cairo_get_matrix(cr, &matrix);
524
    return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));
525
}
526
527
void GraphicsContext::setPlatformFillColor(const Color& col)
528
{
529
    // FIXME: this is probably a no-op but I'm not sure
530
    // notImplemented(); // commented-out because it's chatty and clutters output
531
}
532
533
void GraphicsContext::setPlatformStrokeColor(const Color& col)
534
{
535
    // FIXME: this is probably a no-op but I'm not sure
536
    //notImplemented(); // commented-out because it's chatty and clutters output
537
}
538
539
void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
540
{
541
    if (paintingDisabled())
542
        return;
543
544
    cairo_set_line_width(m_data->cr, strokeThickness);
545
}
546
547
void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
548
{
549
    static double dashPattern[] = {5.0, 5.0};
550
    static double dotPattern[] = {1.0, 1.0};
551
552
    if (paintingDisabled())
553
        return;
554
555
    switch (strokeStyle) {
556
    case NoStroke:
557
        // FIXME: is it the right way to emulate NoStroke?
558
        cairo_set_line_width(m_data->cr, 0);
559
        break;
560
    case SolidStroke:
561
        cairo_set_dash(m_data->cr, 0, 0, 0);
562
        break;
563
    case DottedStroke:
564
        cairo_set_dash(m_data->cr, dotPattern, 2, 0);
565
        break;
566
    case DashedStroke:
567
        cairo_set_dash(m_data->cr, dashPattern, 2, 0);
568
        break;
569
    default:
570
        notImplemented();
571
        break;
572
    }
573
}
574
575
void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
576
{
577
    notImplemented();
578
}
579
580
void GraphicsContext::concatCTM(const AffineTransform& transform)
581
{
582
    if (paintingDisabled())
583
        return;
584
585
    cairo_t* cr = m_data->cr;
586
    const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);
587
    cairo_transform(cr, matrix);
588
}
589
590
void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
591
{
592
    if (paintingDisabled())
593
        return;
594
595
    clip(rect);
596
597
    Path p;
598
    FloatRect r(rect);
599
    // Add outer ellipse
600
    p.addEllipse(r);
601
    // Add inner ellipse
602
    r.inflate(-thickness);
603
    p.addEllipse(r);
604
    addPath(p);
605
606
    cairo_t* cr = m_data->cr;
607
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
608
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
609
    cairo_clip(cr);
610
    cairo_set_fill_rule(cr, savedFillRule);
611
}
612
613
614
void GraphicsContext::setShadow(IntSize const&, int, Color const&)
615
{
616
    notImplemented();
617
}
618
619
void GraphicsContext::clearShadow()
620
{
621
    notImplemented();
622
}
623
624
void GraphicsContext::beginTransparencyLayer(float opacity)
625
{
626
    if (paintingDisabled())
627
        return;
628
629
    cairo_t* cr = m_data->cr;
630
    cairo_push_group(cr);
631
    m_data->layers.append(opacity);
632
}
633
634
void GraphicsContext::endTransparencyLayer()
635
{
636
    if (paintingDisabled())
637
        return;
638
639
    cairo_t* cr = m_data->cr;
640
641
    cairo_pop_group_to_source(cr);
642
    cairo_paint_with_alpha(cr, m_data->layers.last());
643
    m_data->layers.removeLast();
644
}
645
646
void GraphicsContext::clearRect(const FloatRect& rect)
647
{
648
    if (paintingDisabled())
649
        return;
650
651
    cairo_t* cr = m_data->cr;
652
653
    cairo_save(cr);
654
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
655
    cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
656
    cairo_fill(cr);
657
    cairo_restore(cr);
658
}
659
660
void GraphicsContext::strokeRect(const FloatRect& rect, float width)
661
{
662
    if (paintingDisabled())
663
        return;
664
665
    cairo_t* cr = m_data->cr;
666
    cairo_save(cr);
667
    cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
668
    setColor(cr, strokeColor());
669
    cairo_set_line_width(cr, width);
670
    cairo_stroke(cr);
671
    cairo_restore(cr);
672
}
673
674
void GraphicsContext::setLineCap(LineCap lineCap)
675
{
676
    if (paintingDisabled())
677
        return;
678
679
    cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;
680
    switch (lineCap) {
681
        case ButtCap:
682
            // no-op
683
            break;
684
        case RoundCap:
685
            cairoCap = CAIRO_LINE_CAP_ROUND;
686
            break;
687
        case SquareCap:
688
            cairoCap = CAIRO_LINE_CAP_SQUARE;
689
            break;
690
    }
691
    cairo_set_line_cap(m_data->cr, cairoCap);
692
}
693
694
void GraphicsContext::setLineJoin(LineJoin lineJoin)
695
{
696
    if (paintingDisabled())
697
        return;
698
699
    cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;
700
    switch (lineJoin) {
701
        case MiterJoin:
702
            // no-op
703
            break;
704
        case RoundJoin:
705
            cairoJoin = CAIRO_LINE_JOIN_ROUND;
706
            break;
707
        case BevelJoin:
708
            cairoJoin = CAIRO_LINE_JOIN_BEVEL;
709
            break;
710
    }
711
    cairo_set_line_join(m_data->cr, cairoJoin);
712
}
713
714
void GraphicsContext::setMiterLimit(float miter)
715
{
716
    if (paintingDisabled())
717
        return;
718
719
    cairo_set_miter_limit(m_data->cr, miter);
720
}
721
722
void GraphicsContext::setAlpha(float)
723
{
724
    notImplemented();
725
}
726
727
static inline cairo_operator_t toCairoOperator(CompositeOperator op)
728
{
729
    switch (op) {
730
        case CompositeClear:
731
            return CAIRO_OPERATOR_CLEAR;
732
        case CompositeCopy:
733
            return CAIRO_OPERATOR_SOURCE;
734
        case CompositeSourceOver:
735
            return CAIRO_OPERATOR_OVER;
736
        case CompositeSourceIn:
737
            return CAIRO_OPERATOR_IN;
738
        case CompositeSourceOut:
739
            return CAIRO_OPERATOR_OUT;
740
        case CompositeSourceAtop:
741
            return CAIRO_OPERATOR_ATOP;
742
        case CompositeDestinationOver:
743
            return CAIRO_OPERATOR_DEST_OVER;
744
        case CompositeDestinationIn:
745
            return CAIRO_OPERATOR_DEST_IN;
746
        case CompositeDestinationOut:
747
            return CAIRO_OPERATOR_DEST_OUT;
748
        case CompositeDestinationAtop:
749
            return CAIRO_OPERATOR_DEST_ATOP;
750
        case CompositeXOR:
751
            return CAIRO_OPERATOR_XOR;
752
        case CompositePlusDarker:
753
            return CAIRO_OPERATOR_SATURATE;
754
        case CompositeHighlight:
755
            // There is no Cairo equivalent for CompositeHighlight.
756
            return CAIRO_OPERATOR_OVER;
757
        case CompositePlusLighter:
758
            return CAIRO_OPERATOR_ADD;
759
        default:
760
            return CAIRO_OPERATOR_SOURCE;
761
    }
762
}
763
764
void GraphicsContext::setCompositeOperation(CompositeOperator op)
765
{
766
    if (paintingDisabled())
767
        return;
768
769
    cairo_set_operator(m_data->cr, toCairoOperator(op));
770
}
771
772
void GraphicsContext::beginPath()
773
{
774
    if (paintingDisabled())
775
        return;
776
777
    cairo_t* cr = m_data->cr;
778
    cairo_new_path(cr);
779
}
780
781
void GraphicsContext::addPath(const Path& path)
782
{
783
    if (paintingDisabled())
784
        return;
785
786
    cairo_t* cr = m_data->cr;
787
    cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
788
    cairo_append_path(cr, p);
789
    cairo_path_destroy(p);
790
}
791
792
void GraphicsContext::clip(const Path& path)
793
{
794
    if (paintingDisabled())
795
        return;
796
797
    cairo_t* cr = m_data->cr;
798
    cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
799
    cairo_append_path(cr, p);
800
    cairo_path_destroy(p);
801
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
802
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
803
    cairo_clip(cr);
804
    cairo_set_fill_rule(cr, savedFillRule);
805
}
806
807
void GraphicsContext::clipOut(const Path& path)
808
{
809
    if (paintingDisabled())
810
        return;
811
812
    cairo_t* cr = m_data->cr;
813
    double x1, y1, x2, y2;
814
    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
815
    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
816
    addPath(path);
817
818
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
819
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
820
    cairo_clip(cr);
821
    cairo_set_fill_rule(cr, savedFillRule);
822
}
823
824
void GraphicsContext::rotate(float radians)
825
{
826
    if (paintingDisabled())
827
        return;
828
829
    cairo_rotate(m_data->cr, radians);
830
}
831
832
void GraphicsContext::scale(const FloatSize& size)
833
{
834
    if (paintingDisabled())
835
        return;
836
837
    cairo_scale(m_data->cr, size.width(), size.height());
838
}
839
840
void GraphicsContext::clipOut(const IntRect& r)
841
{
842
    if (paintingDisabled())
843
        return;
844
845
    cairo_t* cr = m_data->cr;
846
    double x1, y1, x2, y2;
847
    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
848
    cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1);
849
    cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());
850
    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
851
    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
852
    cairo_clip(cr);
853
    cairo_set_fill_rule(cr, savedFillRule);
854
}
855
856
void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
857
{
858
    if (paintingDisabled())
859
        return;
860
861
    Path p;
862
    p.addEllipse(r);
863
    clipOut(p);
864
}
865
866
void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
867
{
868
    if (paintingDisabled())
869
        return;
870
871
    cairo_t* cr = m_data->cr;
872
    cairo_save(cr);
873
    beginPath();
874
    addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
875
    setColor(cr, color);
876
    cairo_fill(cr);
877
    cairo_restore(cr);
878
}
879
75
880
#if PLATFORM(GTK)
76
#if PLATFORM(GTK)
881
void GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose)
77
    GdkEventExpose* expose;
882
{
78
#elif PLATFORM(WIN)
883
    m_data->expose = expose;
79
    HDC m_hdc;
884
}
80
    unsigned m_transparencyCount;
885
886
GdkEventExpose* GraphicsContext::gdkExposeEvent() const
887
{
888
    return m_data->expose;
889
}
890
891
GdkDrawable* GraphicsContext::gdkDrawable() const
892
{
893
    if (!m_data->expose)
894
        return 0;
895
896
    return GDK_DRAWABLE(m_data->expose->window);
897
}
898
899
IntPoint GraphicsContext::translatePoint(const IntPoint& point) const
900
{
901
    cairo_matrix_t tm;
902
    cairo_get_matrix(m_data->cr, &tm);
903
    double x = point.x();
904
    double y = point.y();
905
906
    cairo_matrix_transform_point(&tm, &x, &y);
907
    return IntPoint(x, y);
908
}
909
#endif
81
#endif
910
82
};
911
void GraphicsContext::setUseAntialiasing(bool enable)
912
{
913
    if (paintingDisabled())
914
        return;
915
916
    // When true, use the default Cairo backend antialias mode (usually this
917
    // enables standard 'grayscale' antialiasing); false to explicitly disable
918
    // antialiasing. This is the same strategy as used in drawConvexPolygon().
919
    cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
920
}
921
83
922
} // namespace WebCore
84
} // namespace WebCore
923
85
- WebCore/platform/graphics/cg/GraphicsContextCG.cpp -6 / +3 lines
Lines 27-37 WebCore/platform/graphics/cg/GraphicsContextCG.cpp_sec1
27
#include "config.h"
27
#include "config.h"
28
#include "GraphicsContext.h"
28
#include "GraphicsContext.h"
29
29
30
#if PLATFORM(CG)
31
32
#include "AffineTransform.h"
30
#include "AffineTransform.h"
33
#include "FloatConversion.h"
31
#include "FloatConversion.h"
34
#include "GraphicsContextPlatformPrivate.h"
32
#include "GraphicsContextPlatformPrivateCG.h"
35
#include "KURL.h"
33
#include "KURL.h"
36
#include "Path.h"
34
#include "Path.h"
37
#include <CoreGraphics/CGPDFContext.h>
35
#include <CoreGraphics/CGPDFContext.h>
Lines 83-89 CGContextRef GraphicsContext::platformCo WebCore/platform/graphics/cg/GraphicsContextCG.cpp_sec2
83
void GraphicsContext::savePlatformState()
81
void GraphicsContext::savePlatformState()
84
{
82
{
85
    // Note: Do not use this function within this class implementation, since we want to avoid the extra
83
    // 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).
87
    CGContextSaveGState(platformContext());
85
    CGContextSaveGState(platformContext());
88
    m_data->save();
86
    m_data->save();
89
}
87
}
Lines 91-97 void GraphicsContext::savePlatformState( WebCore/platform/graphics/cg/GraphicsContextCG.cpp_sec3
91
void GraphicsContext::restorePlatformState()
89
void GraphicsContext::restorePlatformState()
92
{
90
{
93
    // Note: Do not use this function within this class implementation, since we want to avoid the extra
91
    // 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).
95
    CGContextRestoreGState(platformContext());
93
    CGContextRestoreGState(platformContext());
96
    m_data->restore();
94
    m_data->restore();
97
    m_data->m_userToDeviceTransformKnownToBeIdentity = false;
95
    m_data->m_userToDeviceTransformKnownToBeIdentity = false;
Lines 925-928 void GraphicsContext::setCompositeOperat WebCore/platform/graphics/cg/GraphicsContextCG.cpp_sec4
925
    
923
    
926
}
924
}
927
925
928
#endif // PLATFORM(CG)
- WebCore/platform/graphics/cg/GraphicsContextPlatformPrivate.h -85 lines
Lines 1-85 WebCore/platform/graphics/cg/GraphicsContextPlatformPrivate.h_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include <CoreGraphics/CGContext.h>
27
28
namespace WebCore {
29
30
class GraphicsContextPlatformPrivate {
31
public:
32
    GraphicsContextPlatformPrivate(CGContextRef cgContext)
33
        : m_cgContext(cgContext)
34
#if PLATFORM(WIN)
35
        , m_hdc(0)
36
        , m_transparencyCount(0)
37
#endif
38
        , m_userToDeviceTransformKnownToBeIdentity(false)
39
    {
40
        CGContextRetain(m_cgContext);
41
    }
42
    
43
    ~GraphicsContextPlatformPrivate()
44
    {
45
        CGContextRelease(m_cgContext);
46
    }
47
48
#if PLATFORM(MAC)
49
    // These methods do nothing on Mac.
50
    void save() {}
51
    void restore() {}
52
    void clip(const IntRect&) {}
53
    void clip(const Path&) {}
54
    void scale(const FloatSize&) {}
55
    void rotate(float) {}
56
    void translate(float, float) {}
57
    void concatCTM(const AffineTransform&) {}
58
    void beginTransparencyLayer() {}
59
    void endTransparencyLayer() {}
60
#endif
61
62
#if PLATFORM(WIN)
63
    // On Windows, we need to update the HDC for form controls to draw in the right place.
64
    void save();
65
    void restore();
66
    void clip(const IntRect&);
67
    void clip(const Path&);
68
    void scale(const FloatSize&);
69
    void rotate(float);
70
    void translate(float, float);
71
    void concatCTM(const AffineTransform&);
72
    void beginTransparencyLayer() { m_transparencyCount++; }
73
    void endTransparencyLayer() { m_transparencyCount--; }
74
#endif
75
76
#if PLATFORM(WIN)
77
    HDC m_hdc;
78
    unsigned m_transparencyCount;
79
#endif
80
81
    CGContextRef m_cgContext;
82
    bool m_userToDeviceTransformKnownToBeIdentity;
83
};
84
85
}
- WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +85 lines
Line 0 WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include <CoreGraphics/CGContext.h>
27
28
namespace WebCore {
29
30
class GraphicsContextPlatformPrivate {
31
public:
32
    GraphicsContextPlatformPrivate(CGContextRef cgContext)
33
        : m_cgContext(cgContext)
34
#if PLATFORM(WIN)
35
        , m_hdc(0)
36
        , m_transparencyCount(0)
37
#endif
38
        , m_userToDeviceTransformKnownToBeIdentity(false)
39
    {
40
        CGContextRetain(m_cgContext);
41
    }
42
    
43
    ~GraphicsContextPlatformPrivate()
44
    {
45
        CGContextRelease(m_cgContext);
46
    }
47
48
#if PLATFORM(MAC)
49
    // These methods do nothing on Mac.
50
    void save() {}
51
    void restore() {}
52
    void clip(const IntRect&) {}
53
    void clip(const Path&) {}
54
    void scale(const FloatSize&) {}
55
    void rotate(float) {}
56
    void translate(float, float) {}
57
    void concatCTM(const AffineTransform&) {}
58
    void beginTransparencyLayer() {}
59
    void endTransparencyLayer() {}
60
#endif
61
62
#if PLATFORM(WIN)
63
    // On Windows, we need to update the HDC for form controls to draw in the right place.
64
    void save();
65
    void restore();
66
    void clip(const IntRect&);
67
    void clip(const Path&);
68
    void scale(const FloatSize&);
69
    void rotate(float);
70
    void translate(float, float);
71
    void concatCTM(const AffineTransform&);
72
    void beginTransparencyLayer() { m_transparencyCount++; }
73
    void endTransparencyLayer() { m_transparencyCount--; }
74
#endif
75
76
#if PLATFORM(WIN)
77
    HDC m_hdc;
78
    unsigned m_transparencyCount;
79
#endif
80
81
    CGContextRef m_cgContext;
82
    bool m_userToDeviceTransformKnownToBeIdentity;
83
};
84
85
}
- WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +5 lines
Lines 23-28 WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h_sec1
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
24
 */
25
25
26
#include "config.h"
27
28
#if PLATFORM(CG)
29
26
#include <CoreGraphics/CGContext.h>
30
#include <CoreGraphics/CGContext.h>
27
31
28
namespace WebCore {
32
namespace WebCore {
Lines 82-85 public: WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h_sec2
82
    bool m_userToDeviceTransformKnownToBeIdentity;
86
    bool m_userToDeviceTransformKnownToBeIdentity;
83
};
87
};
84
88
89
#endif	// PLATFORM (CG)
85
}
90
}
- WebCore/platform/graphics/win/FontCGWin.cpp +227 lines
Line 0 WebCore/platform/graphics/win/FontCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "Font.h"
28
29
#include "FontFallbackList.h"
30
#include "GlyphBuffer.h"
31
#include "GraphicsContext.h"
32
#include "IntRect.h"
33
#include "NotImplemented.h"
34
#include "SimpleFontData.h"
35
#include "UniscribeController.h"
36
#include <ApplicationServices/ApplicationServices.h>
37
#include <WebKitSystemInterface/WebKitSystemInterface.h>
38
#include <wtf/MathExtras.h>
39
40
namespace 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
}
165
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);
183
}
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
}
- WebCore/platform/graphics/win/FontCGWin.cpp -104 / +4 lines
Lines 1-5 WebCore/platform/graphics/win/FontCGWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 26-36 WebCore/platform/graphics/win/FontCGWin.cpp_sec2
26
#include "config.h"
26
#include "config.h"
27
#include "Font.h"
27
#include "Font.h"
28
28
29
#include "FontFallbackList.h"
30
#include "GlyphBuffer.h"
29
#include "GlyphBuffer.h"
31
#include "GraphicsContext.h"
30
#include "GraphicsContext.h"
32
#include "IntRect.h"
31
#include "IntRect.h"
33
#include "NotImplemented.h"
34
#include "SimpleFontData.h"
32
#include "SimpleFontData.h"
35
#include "UniscribeController.h"
33
#include "UniscribeController.h"
36
#include <ApplicationServices/ApplicationServices.h>
34
#include <ApplicationServices/ApplicationServices.h>
Lines 68-82 void Font::drawGlyphs(GraphicsContext* g WebCore/platform/graphics/win/FontCGWin.cpp_sec3
68
66
69
        // Set the correct color.
67
        // Set the correct color.
70
        HDC textDrawingDC = hdc;
68
        HDC textDrawingDC = hdc;
71
        /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) {
69
        SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
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
70
81
        SetBkMode(hdc, TRANSPARENT);
71
        SetBkMode(hdc, TRANSPARENT);
82
        SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
72
        SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
Lines 95-128 void Font::drawGlyphs(GraphicsContext* g WebCore/platform/graphics/win/FontCGWin.cpp_sec4
95
        }
85
        }
96
        ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data());
86
        ExtTextOut(hdc, point.x(), point.y(), ETO_GLYPH_INDEX, 0, (WCHAR*)glyphBuffer.glyphs(from), numGlyphs, gdiAdvances.data());
97
87
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);
88
        graphicsContext->releaseWindowsContext(hdc, textRect);
127
        return;
89
        return;
128
    }
90
    }
Lines 139-147 void Font::drawGlyphs(GraphicsContext* g WebCore/platform/graphics/win/FontCGWin.cpp_sec5
139
    matrix.b = -matrix.b;
101
    matrix.b = -matrix.b;
140
    matrix.d = -matrix.d;
102
    matrix.d = -matrix.d;
141
103
142
    if (platformData.syntheticOblique())
104
    if (platformData.syntheticOblique()) {
143
    {
105
        static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90.0f);
144
        static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90);
145
        matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
106
        matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
146
    }
107
    }
147
108
Lines 163-227 void Font::drawGlyphs(GraphicsContext* g WebCore/platform/graphics/win/FontCGWin.cpp_sec6
163
    wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
124
    wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
164
}
125
}
165
126
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);
183
}
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
}
127
}
- WebCore/platform/graphics/win/FontCairoWin.cpp +42 lines
Line 0 WebCore/platform/graphics/win/FontCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "Font.h"
28
29
#include "GlyphBuffer.h"
30
#include "GraphicsContext.h"
31
#include "NotImplemented.h"
32
#include "SimpleFontData.h"
33
34
namespace WebCore {
35
36
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, 
37
                      int from, int numGlyphs, const FloatPoint& point) const
38
{
39
    notImplemented();
40
}
41
42
}
- WebCore/platform/graphics/win/FontWin.cpp -127 / +1 lines
Lines 1-5 WebCore/platform/graphics/win/FontWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 33-168 WebCore/platform/graphics/win/FontWin.cpp_sec2
33
#include "NotImplemented.h"
33
#include "NotImplemented.h"
34
#include "SimpleFontData.h"
34
#include "SimpleFontData.h"
35
#include "UniscribeController.h"
35
#include "UniscribeController.h"
36
#include <ApplicationServices/ApplicationServices.h>
37
#include <WebKitSystemInterface/WebKitSystemInterface.h>
38
#include <wtf/MathExtras.h>
36
#include <wtf/MathExtras.h>
39
37
40
namespace WebCore {
38
namespace WebCore {
41
39
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
}
165
166
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,
40
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,
167
                                            int from, int to) const
41
                                            int from, int to) const
168
{
42
{
- WebCore/platform/graphics/win/GraphicsContextCGWin.cpp +386 lines
Line 0 WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "GraphicsContext.h"
28
29
#include "AffineTransform.h"
30
#include "NotImplemented.h"
31
#include "Path.h"
32
#include <CoreGraphics/CGBitmapContext.h>
33
#include <WebKitSystemInterface/WebKitSystemInterface.h>
34
#include <wtf/MathExtras.h>
35
36
#include "GraphicsContextPlatformPrivate.h"
37
38
using namespace std;
39
40
namespace WebCore {
41
42
class 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
}
376
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
}
- WebCore/platform/graphics/win/GraphicsContextCGWin.cpp -43 / +33 lines
Lines 1-5 WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec1
1
/*
1
/*
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.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 29-49 WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec2
29
#include "AffineTransform.h"
29
#include "AffineTransform.h"
30
#include "NotImplemented.h"
30
#include "NotImplemented.h"
31
#include "Path.h"
31
#include "Path.h"
32
32
#include <CoreGraphics/CGBitmapContext.h>
33
#include <CoreGraphics/CGBitmapContext.h>
33
#include <WebKitSystemInterface/WebKitSystemInterface.h>
34
#include <WebKitSystemInterface/WebKitSystemInterface.h>
34
#include <wtf/MathExtras.h>
35
#include "GraphicsContextPlatformPrivateCG.h"
35
36
#include "GraphicsContextPlatformPrivate.h"
37
36
38
using namespace std;
37
using namespace std;
39
38
40
namespace WebCore {
39
namespace WebCore {
41
40
42
class SVGResourceImage;
43
44
static CGContextRef CGContextWithHDC(HDC hdc)
41
static CGContextRef CGContextWithHDC(HDC hdc)
45
{
42
{
46
    HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
43
    HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
47
    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
44
    CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB();
48
    BITMAP info;
45
    BITMAP info;
49
46
Lines 77-82 GraphicsContext::GraphicsContext(HDC hdc WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec3
77
    }
74
    }
78
}
75
}
79
76
77
bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
78
80
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
79
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
81
{
80
{
82
    if (inTransparencyLayer()) {
81
    if (inTransparencyLayer()) {
Lines 118-127 HDC GraphicsContext::getWindowsContext(c WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec4
118
117
119
        // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
118
        // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
120
        XFORM xform;
119
        XFORM xform;
121
        xform.eM11 = 1.0;
120
        xform.eM11 = 1.0f;
122
        xform.eM12 = 0;
121
        xform.eM12 = 0.0f;
123
        xform.eM21 = 0;
122
        xform.eM21 = 0.0f;
124
        xform.eM22 = 1.0;
123
        xform.eM22 = 1.0f;
125
        xform.eDx = -dstRect.x();
124
        xform.eDx = -dstRect.x();
126
        xform.eDy = -dstRect.y();
125
        xform.eDy = -dstRect.y();
127
        ::SetWorldTransform(bitmapDC, &xform);
126
        ::SetWorldTransform(bitmapDC, &xform);
Lines 134-148 HDC GraphicsContext::getWindowsContext(c WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec5
134
    return m_data->m_hdc;
133
    return m_data->m_hdc;
135
}
134
}
136
135
137
bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
138
139
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
136
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
140
{
137
{
141
    if (hdc && inTransparencyLayer()) {
138
    if (hdc && inTransparencyLayer()) {
142
        if (dstRect.isEmpty())
139
        if (dstRect.isEmpty())
143
            return;
140
            return;
144
141
145
        HBITMAP bitmap = (HBITMAP)GetCurrentObject(hdc, OBJ_BITMAP);
142
        HBITMAP bitmap = static_cast<HBITMAP>(GetCurrentObject(hdc, OBJ_BITMAP));
146
143
147
        // Need to make a CGImage out of the bitmap's pixel buffer and then draw
144
        // Need to make a CGImage out of the bitmap's pixel buffer and then draw
148
        // it into our context.
145
        // it into our context.
Lines 203-213 void GraphicsContextPlatformPrivate::sca WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec6
203
        return;
200
        return;
204
    XFORM xform;
201
    XFORM xform;
205
    xform.eM11 = size.width();
202
    xform.eM11 = size.width();
206
    xform.eM12 = 0;
203
    xform.eM12 = 0.0f;
207
    xform.eM21 = 0;
204
    xform.eM21 = 0.0f;
208
    xform.eM22 = size.height();
205
    xform.eM22 = size.height();
209
    xform.eDx = 0;
206
    xform.eDx = 0.0f;
210
    xform.eDy = 0;
207
    xform.eDy = 0.0f;
211
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
208
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
212
}
209
}
213
210
Lines 223-230 void GraphicsContextPlatformPrivate::rot WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec7
223
    xform.eM12 = -sinAngle;
220
    xform.eM12 = -sinAngle;
224
    xform.eM21 = sinAngle;
221
    xform.eM21 = sinAngle;
225
    xform.eM22 = cosAngle;
222
    xform.eM22 = cosAngle;
226
    xform.eDx = 0;
223
    xform.eDx = 0.0f;
227
    xform.eDy = 0;
224
    xform.eDy = 0.0f;
228
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
225
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
229
}
226
}
230
227
Lines 233-242 void GraphicsContextPlatformPrivate::tra WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec8
233
    if (!m_hdc)
230
    if (!m_hdc)
234
        return;
231
        return;
235
    XFORM xform;
232
    XFORM xform;
236
    xform.eM11 = 1.0;
233
    xform.eM11 = 1.0f;
237
    xform.eM12 = 0;
234
    xform.eM12 = 0.0f;
238
    xform.eM21 = 0;
235
    xform.eM21 = 0.0f;
239
    xform.eM22 = 1.0;
236
    xform.eM22 = 1.0f;
240
    xform.eDx = x;
237
    xform.eDx = x;
241
    xform.eDy = y;
238
    xform.eDy = y;
242
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
239
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
Lines 246-251 void GraphicsContextPlatformPrivate::con WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec9
246
{
243
{
247
    if (!m_hdc)
244
    if (!m_hdc)
248
        return;
245
        return;
246
249
    CGAffineTransform mat = transform;
247
    CGAffineTransform mat = transform;
250
    XFORM xform;
248
    XFORM xform;
251
    xform.eM11 = mat.a;
249
    xform.eM11 = mat.a;
Lines 254-259 void GraphicsContextPlatformPrivate::con WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec10
254
    xform.eM22 = mat.d;
252
    xform.eM22 = mat.d;
255
    xform.eDx = mat.tx;
253
    xform.eDx = mat.tx;
256
    xform.eDy = mat.ty;
254
    xform.eDy = mat.ty;
255
257
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
256
    ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
258
}
257
}
259
258
Lines 287-292 void GraphicsContext::drawFocusRing(cons WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec11
287
    CGContextRestoreGState(context);
286
    CGContextRestoreGState(context);
288
}
287
}
289
288
289
// Pulled from GraphicsContextCG
290
static 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
290
static const Color& spellingPatternColor() {
297
static const Color& spellingPatternColor() {
291
    static const Color spellingColor(255, 0, 0);
298
    static const Color spellingColor(255, 0, 0);
292
    return spellingColor;
299
    return spellingColor;
Lines 297-315 static const Color& grammarPatternColor( WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec12
297
    return grammarColor;
304
    return grammarColor;
298
}
305
}
299
306
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)
307
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
309
{
308
{
310
    if (paintingDisabled())
309
    if (paintingDisabled())
311
        return;
310
        return;
312
    
311
313
    // These are the same for misspelling or bad grammar
312
    // These are the same for misspelling or bad grammar
314
    const int patternHeight = 3; // 3 rows
313
    const int patternHeight = 3; // 3 rows
315
    ASSERT(cMisspellingLineThickness == patternHeight);
314
    ASSERT(cMisspellingLineThickness == patternHeight);
Lines 343-349 void GraphicsContext::drawLineForMisspel WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec13
343
    
342
    
344
    // Dash lengths for the top and bottom of the error underline are the same.
343
    // Dash lengths for the top and bottom of the error underline are the same.
345
    // These are magic.
344
    // These are magic.
346
    static const float edge_dash_lengths[] = {2, 2};
345
    static const float edge_dash_lengths[] = {2.0f, 2.0f};
347
    static const float middle_dash_lengths[] = {2.76f, 1.24f};
346
    static const float middle_dash_lengths[] = {2.76f, 1.24f};
348
    static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f;
347
    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;
348
    static const float middle_offset = -(middle_dash_lengths[1] - 1.0f) / 2.0f;
Lines 374-386 void GraphicsContext::drawLineForMisspel WebCore/platform/graphics/win/GraphicsContextCGWin.cpp_sec14
374
    CGContextRestoreGState(context);
373
    CGContextRestoreGState(context);
375
}
374
}
376
375
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
}
- WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp +114 lines
Line 0 WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "GraphicsContext.h"
28
29
#include "AffineTransform.h"
30
#include "NotImplemented.h"
31
#include "Path.h"
32
33
#include <cairo-win32.h>
34
#include "GraphicsContextPlatformPrivateCairo.h"
35
36
using namespace std;
37
38
namespace WebCore {
39
40
GraphicsContext::GraphicsContext(HDC dc)
41
    : m_common(createGraphicsContextPrivate())
42
    , m_data(new GraphicsContextPlatformPrivate)
43
{
44
    if (dc) {
45
        cairo_surface_t* surface = cairo_win32_surface_create(dc);
46
        m_data->cr = cairo_create(surface);
47
        m_data->m_hdc = dc;
48
    } else {
49
        setPaintingDisabled(true);
50
        m_data->cr = 0;
51
        m_data->m_hdc = 0;
52
    }
53
54
    if (m_data->cr) {
55
        // Make sure the context starts in sync with our state.
56
        setPlatformFillColor(fillColor());
57
        setPlatformStrokeColor(strokeColor());
58
    }
59
}
60
61
HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend)
62
{
63
    // This is probably wrong, and definitely out of date.  Pulled from old SVN
64
    cairo_surface_t* surface = cairo_get_target(platformContext());
65
    HDC hdc = cairo_win32_surface_get_dc(surface);   
66
    SaveDC(hdc);
67
68
    // FIXME: We need to make sure a clip is really set on the HDC.
69
    // Call SetWorldTransform to honor the current Cairo transform.
70
    SetGraphicsMode(hdc, GM_ADVANCED); // We need this call for themes to honor world transforms.
71
    cairo_matrix_t mat;
72
    cairo_get_matrix(platformContext(), &mat);
73
    XFORM xform;
74
    xform.eM11 = mat.xx;
75
    xform.eM12 = mat.xy;
76
    xform.eM21 = mat.yx;
77
    xform.eM22 = mat.yy;
78
    xform.eDx = mat.x0;
79
    xform.eDy = mat.y0;
80
    SetWorldTransform(hdc, &xform);
81
82
    return hdc;
83
}
84
85
bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
86
87
void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend)
88
{
89
    cairo_surface_t* surface = cairo_get_target(platformContext());
90
    HDC hdc2 = cairo_win32_surface_get_dc(surface);
91
    RestoreDC(hdc2, -1);
92
    cairo_surface_mark_dirty(surface);
93
}
94
95
void GraphicsContext::concatCTM(const AffineTransform& transform)
96
{
97
    cairo_surface_t* surface = cairo_get_target(platformContext());
98
    HDC hdc = cairo_win32_surface_get_dc(surface);   
99
    SaveDC(hdc);
100
101
    cairo_matrix_t mat;
102
    cairo_get_matrix(platformContext(), &mat);
103
    XFORM xform;
104
    xform.eM11 = mat.xx;
105
    xform.eM12 = mat.xy;
106
    xform.eM21 = mat.yx;
107
    xform.eM22 = mat.yy;
108
    xform.eDx = mat.x0;
109
    xform.eDy = mat.y0;
110
111
    ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
112
}
113
114
}
- WebCore/platform/graphics/win/GraphicsContextWin.cpp -338 / +1 lines
Lines 1-5 WebCore/platform/graphics/win/GraphicsContextWin.cpp_sec1
1
/*
1
/*
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.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 29-379 WebCore/platform/graphics/win/GraphicsContextWin.cpp_sec2
29
#include "AffineTransform.h"
29
#include "AffineTransform.h"
30
#include "NotImplemented.h"
30
#include "NotImplemented.h"
31
#include "Path.h"
31
#include "Path.h"
32
#include <CoreGraphics/CGBitmapContext.h>
33
#include <WebKitSystemInterface/WebKitSystemInterface.h>
34
#include <wtf/MathExtras.h>
32
#include <wtf/MathExtras.h>
35
33
36
#include "GraphicsContextPlatformPrivate.h"
37
38
using namespace std;
34
using namespace std;
39
35
40
namespace WebCore {
36
namespace WebCore {
41
37
42
class SVGResourceImage;
38
class SVGResourceImage;
43
39
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
}
376
377
#if ENABLE(SVG)
40
#if ENABLE(SVG)
378
GraphicsContext* contextForImage(SVGResourceImage*)
41
GraphicsContext* contextForImage(SVGResourceImage*)
379
{
42
{
- WebCore/platform/graphics/win/ImageCGWin.cpp +110 lines
Line 0 WebCore/platform/graphics/win/ImageCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "config.h"
27
#include "Image.h"
28
#include "BitmapImage.h"
29
#include "GraphicsContext.h"
30
#include <ApplicationServices/ApplicationServices.h>
31
32
#include <winsock2.h>
33
#include <windows.h>
34
#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*);
40
41
namespace 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
}
63
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
110
} // namespace WebCore
- WebCore/platform/graphics/win/ImageCGWin.cpp -33 / +8 lines
Lines 1-5 WebCore/platform/graphics/win/ImageCGWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 29-66 WebCore/platform/graphics/win/ImageCGWin.cpp_sec2
29
#include "GraphicsContext.h"
29
#include "GraphicsContext.h"
30
#include <ApplicationServices/ApplicationServices.h>
30
#include <ApplicationServices/ApplicationServices.h>
31
31
32
#include <winsock2.h>
33
#include <windows.h>
32
#include <windows.h>
34
#include "PlatformString.h"
33
#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*);
40
34
41
namespace WebCore {
35
namespace WebCore {
42
36
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
}
63
64
bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
37
bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
65
{
38
{
66
    ASSERT(bmp);
39
    ASSERT(bmp);
Lines 76-90 bool BitmapImage::getHBITMAPOfSize(HBITM WebCore/platform/graphics/win/ImageCGWin.cpp_sec3
76
        8, bmpInfo.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
49
        8, bmpInfo.bmWidthBytes, deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
77
  
50
  
78
    GraphicsContext gc(cgContext);
51
    GraphicsContext gc(cgContext);
52
79
    IntSize imageSize = BitmapImage::size();
53
    IntSize imageSize = BitmapImage::size();
80
    if (size)
54
    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);
82
    else
56
    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);
84
58
85
    // Do cleanup
59
    // Do cleanup
86
    CGContextRelease(cgContext);
60
    CGContextRelease(cgContext);
87
    CGColorSpaceRelease(deviceRGB);
61
    CGColorSpaceRelease(deviceRGB);
62
88
    return true;
63
    return true;
89
}
64
}
90
65
Lines 93-102 void BitmapImage::drawFrameMatchingSourc WebCore/platform/graphics/win/ImageCGWin.cpp_sec4
93
    int frames = frameCount();
68
    int frames = frameCount();
94
    for (int i = 0; i < frames; ++i) {
69
    for (int i = 0; i < frames; ++i) {
95
        CGImageRef image = frameAtIndex(i);
70
        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())) {
97
            size_t currentFrame = m_currentFrame;
72
            size_t currentFrame = m_currentFrame;
98
            m_currentFrame = i;
73
            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);
100
            m_currentFrame = currentFrame;
75
            m_currentFrame = currentFrame;
101
            return;
76
            return;
102
        }
77
        }
Lines 104-110 void BitmapImage::drawFrameMatchingSourc WebCore/platform/graphics/win/ImageCGWin.cpp_sec5
104
79
105
    // No image of the correct size was found, fallback to drawing the current frame
80
    // No image of the correct size was found, fallback to drawing the current frame
106
    IntSize imageSize = BitmapImage::size();
81
    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);
108
}
83
}
109
84
110
} // namespace WebCore
85
} // namespace WebCore
- WebCore/platform/graphics/win/ImageCairoWin.cpp +89 lines
Line 0 WebCore/platform/graphics/win/ImageCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#include "config.h"
27
#include "Image.h"
28
#include "BitmapImage.h"
29
#include "GraphicsContext.h"
30
#include <cairo.h>
31
32
#include <windows.h>
33
#include "PlatformString.h"
34
35
namespace WebCore {
36
37
bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
38
{
39
    ASSERT(bmp);
40
41
    BITMAP bmpInfo;
42
    GetObject(bmp, sizeof(BITMAP), &bmpInfo);
43
44
    // If this is a 32bpp bitmap, which it always should be, we'll clear it so alpha-wise it will be visible
45
    if (bmpInfo.bmBitsPixel == 32) {
46
        int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
47
        memset(bmpInfo.bmBits, 255, bufferSize);
48
    }
49
 	
50
    HDC tempDC = CreateCompatibleDC(0);
51
    if (!tempDC) {
52
        LOG_ERROR("Failed to create in-memory DC for Image::blit()");
53
        return false;
54
    }
55
    SelectObject(tempDC, bmp);
56
    GraphicsContext gc(tempDC);
57
58
    IntSize imageSize = BitmapImage::size();
59
    if (size)
60
        drawFrameMatchingSourceSize(&gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), CompositeCopy);
61
    else
62
        draw(&gc, FloatRect(0.0f, 0.0f, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), CompositeCopy);
63
64
    // Do cleanup
65
    DeleteDC(tempDC);
66
67
    return true;
68
}
69
70
void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, CompositeOperator compositeOp)
71
{
72
    int frames = frameCount();
73
    for (int i = 0; i < frames; ++i) {
74
        cairo_surface_t* image = frameAtIndex(i);
75
        if (cairo_image_surface_get_height(image) == static_cast<size_t>(srcSize.height()) && cairo_image_surface_get_width(image) == static_cast<size_t>(srcSize.width())) {
76
            size_t currentFrame = m_currentFrame;
77
            m_currentFrame = i;
78
            draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, srcSize.width(), srcSize.height()), compositeOp);
79
            m_currentFrame = currentFrame;
80
            return;
81
        }
82
    }
83
84
    // No image of the correct size was found, fallback to drawing the current frame
85
    IntSize imageSize = BitmapImage::size();
86
    draw(ctxt, dstRect, FloatRect(0.0f, 0.0f, imageSize.width(), imageSize.height()), compositeOp);
87
}
88
89
} // namespace WebCore
- WebCore/platform/graphics/win/ImageWin.cpp -53 / +1 lines
Lines 1-5 WebCore/platform/graphics/win/ImageWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 26-38 WebCore/platform/graphics/win/ImageWin.cpp_sec2
26
#include "config.h"
26
#include "config.h"
27
#include "Image.h"
27
#include "Image.h"
28
#include "BitmapImage.h"
28
#include "BitmapImage.h"
29
#include "GraphicsContext.h"
30
#include <ApplicationServices/ApplicationServices.h>
31
29
32
#include <winsock2.h>
33
#include <windows.h>
34
#include "PlatformString.h"
35
#include "MIMETypeRegistry.h"
36
#include "SharedBuffer.h"
30
#include "SharedBuffer.h"
37
31
38
// This function loads resources from WebKit
32
// This function loads resources from WebKit
Lines 61-110 bool BitmapImage::getHBITMAP(HBITMAP bmp WebCore/platform/graphics/win/ImageWin.cpp_sec3
61
    return getHBITMAPOfSize(bmp, 0);
55
    return getHBITMAPOfSize(bmp, 0);
62
}
56
}
63
57
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
110
} // namespace WebCore
58
} // namespace WebCore
- WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp +281 lines
Line 0 WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright
9
 *     notice, this list of conditions and the following disclaimer. 
10
 * 2.  Redistributions in binary form must reproduce the above copyright
11
 *     notice, this list of conditions and the following disclaimer in the
12
 *     documentation and/or other materials provided with the distribution. 
13
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14
 *     its contributors may be used to endorse or promote products derived
15
 *     from this software without specific prior written permission. 
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
#include "SimpleFontData.h"
31
32
#include <winsock2.h>
33
#include "Font.h"
34
#include "FontCache.h"
35
#include "FloatRect.h"
36
#include "FontDescription.h"
37
#include <wtf/MathExtras.h>
38
#include <unicode/uchar.h>
39
#include <unicode/unorm.h>
40
#include <ApplicationServices/ApplicationServices.h>
41
#include <mlang.h>
42
#include <tchar.h>
43
#include <WebKitSystemInterface/WebKitSystemInterface.h>
44
45
namespace WebCore {
46
47
using std::max;
48
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
}
59
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()
150
{
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;
161
}
162
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
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
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;
279
}
280
281
}
- WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp -110 / +7 lines
Lines 1-5 WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 38-64 WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec2
38
#include <unicode/uchar.h>
38
#include <unicode/uchar.h>
39
#include <unicode/unorm.h>
39
#include <unicode/unorm.h>
40
#include <ApplicationServices/ApplicationServices.h>
40
#include <ApplicationServices/ApplicationServices.h>
41
#include <WebKitSystemInterface/WebKitSystemInterface.h>
41
#include <mlang.h>
42
#include <mlang.h>
42
#include <tchar.h>
43
#include <tchar.h>
43
#include <WebKitSystemInterface/WebKitSystemInterface.h>
44
44
45
namespace WebCore {
45
namespace WebCore {
46
46
47
using std::max;
47
using std::max;
48
48
49
const float cSmallCapsFontSizeMultiplier = 0.7f;
49
static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / static_cast<float>(unitsPerEm) : x; }
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
}
59
50
60
void SimpleFontData::platformInit()
51
void SimpleFontData::platformInit()
61
{    
52
{
62
    m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
53
    m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f;
63
    m_scriptCache = 0;
54
    m_scriptCache = 0;
64
    m_scriptFontProperties = 0;
55
    m_scriptFontProperties = 0;
Lines 110-116 void SimpleFontData::platformInit() WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec3
110
        SelectObject(dc, oldFont);
101
        SelectObject(dc, oldFont);
111
        ReleaseDC(0, dc);
102
        ReleaseDC(0, dc);
112
103
113
        if (shouldApplyMacAscentHack) {
104
        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.
105
            // This code comes from FontDataMac.mm. We only ever do this when running regression tests so that our metrics will match Mac.
115
106
116
            // We need to adjust Times, Helvetica, and Courier to closely match the
107
            // We need to adjust Times, Helvetica, and Courier to closely match the
Lines 160-242 void SimpleFontData::platformDestroy() WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec4
160
    delete m_scriptFontProperties;
151
    delete m_scriptFontProperties;
161
}
152
}
162
153
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
240
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
154
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
241
{
155
{
242
    if (m_font.useGDI()) {
156
    if (m_font.useGDI()) {
Lines 253-281 float SimpleFontData::platformWidthForGl WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp_sec5
253
    float pointSize = m_font.size();
167
    float pointSize = m_font.size();
254
    CGSize advance;
168
    CGSize advance;
255
    CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
169
    CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
170
 
256
    // FIXME: Need to add real support for printer fonts.
171
    // FIXME: Need to add real support for printer fonts.
257
    bool isPrinterFont = false;
172
    bool isPrinterFont = false;
258
    wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
173
    wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance);
259
    return advance.width + m_syntheticBoldOffset;
260
}
261
174
262
SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
175
    return advance.width + m_syntheticBoldOffset;
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;
279
}
176
}
280
177
281
}
178
}
- WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp +102 lines
Line 0 WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 *
8
 * 1.  Redistributions of source code must retain the above copyright
9
 *     notice, this list of conditions and the following disclaimer. 
10
 * 2.  Redistributions in binary form must reproduce the above copyright
11
 *     notice, this list of conditions and the following disclaimer in the
12
 *     documentation and/or other materials provided with the distribution. 
13
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14
 *     its contributors may be used to endorse or promote products derived
15
 *     from this software without specific prior written permission. 
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
#include "SimpleFontData.h"
31
32
#include <windows.h>
33
34
#include "Font.h"
35
#include "FontCache.h"
36
#include "FontDescription.h"
37
#include "NotImplemented.h"
38
#include <mlang.h>
39
#include <tchar.h>
40
41
namespace WebCore {
42
43
void SimpleFontData::platformInit()
44
{
45
    m_scriptCache = 0;
46
    m_scriptFontProperties = 0;
47
    m_isSystemFont = false;
48
    
49
    if (m_font.useGDI()) {
50
        HDC hdc = GetDC(0);
51
        HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
52
        OUTLINETEXTMETRIC metrics;
53
        GetOutlineTextMetrics(hdc, sizeof(metrics), &metrics);
54
        TEXTMETRIC& textMetrics = metrics.otmTextMetrics;
55
        m_ascent = textMetrics.tmAscent;
56
        m_descent = textMetrics.tmDescent;
57
        m_lineGap = textMetrics.tmExternalLeading;
58
        m_lineSpacing = m_ascent + m_descent + m_lineGap;
59
        m_xHeight = m_ascent * 0.56f; // Best guess for xHeight if no x glyph is present.
60
61
        GLYPHMETRICS gm;
62
        MAT2 mat = { 1, 0, 0, 1 };
63
        DWORD len = GetGlyphOutline(hdc, 'x', GGO_METRICS, &gm, 0, 0, &mat);
64
        if (len != GDI_ERROR && gm.gmptGlyphOrigin.y > 0)
65
            m_xHeight = gm.gmptGlyphOrigin.y;
66
67
        m_unitsPerEm = metrics.otmEMSquare;
68
69
        SelectObject(hdc, oldFont);
70
        ReleaseDC(0, hdc);
71
72
        return;
73
    }
74
75
    // FIXME: This section should determine font dimensions (see CG implementation).
76
    notImplemented();
77
}
78
79
void SimpleFontData::platformDestroy()
80
{
81
    notImplemented();
82
}
83
84
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
85
{
86
    if (m_font.useGDI()) {
87
        HDC hdc = GetDC(0);
88
        HGDIOBJ oldFont = SelectObject(hdc, m_font.hfont());
89
        int width;
90
        GetCharWidthI(hdc, glyph, 1, 0, &width);
91
        SelectObject(hdc, oldFont);
92
        ReleaseDC(0, hdc);
93
        return width;
94
    }
95
96
    // FIXME: Flesh out with Cairo/win32 font implementation
97
    notImplemented();
98
99
    return 0;
100
}
101
102
}
- WebCore/platform/graphics/win/SimpleFontDataWin.cpp -127 / +5 lines
Lines 1-5 WebCore/platform/graphics/win/SimpleFontDataWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 48-163 using std::max; WebCore/platform/graphics/win/SimpleFontDataWin.cpp_sec2
48
48
49
const float cSmallCapsFontSizeMultiplier = 0.7f;
49
const float cSmallCapsFontSizeMultiplier = 0.7f;
50
50
51
static bool shouldApplyMacAscentHack;
51
static bool g_shouldApplyMacAscentHack;
52
53
static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / (float)unitsPerEm : x; }
54
52
55
void SimpleFontData::setShouldApplyMacAscentHack(bool b)
53
void SimpleFontData::setShouldApplyMacAscentHack(bool b)
56
{
54
{
57
    shouldApplyMacAscentHack = b;
55
    g_shouldApplyMacAscentHack = b;
58
}
59
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
}
56
}
148
57
149
void SimpleFontData::platformDestroy()
58
bool SimpleFontData::shouldApplyMacAscentHack()
150
{
59
{
151
    if (!isCustomFont()) {
60
    return g_shouldApplyMacAscentHack;
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;
161
}
61
}
162
62
163
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
63
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
Lines 237-264 void SimpleFontData::determinePitch() WebCore/platform/graphics/win/SimpleFontDataWin.cpp_sec3
237
    ReleaseDC(0, dc);
137
    ReleaseDC(0, dc);
238
}
138
}
239
139
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
262
SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
140
SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const
263
{
141
{
264
    if (!m_scriptFontProperties) {
142
    if (!m_scriptFontProperties) {
- WebCore/platform/win/DragImageCGWin.cpp +193 lines
Line 0 WebCore/platform/win/DragImageCGWin.cpp_sec1
1
/*
2
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "DragImage.h"
28
29
#include "CachedImage.h"
30
#include "GraphicsContext.h"
31
#include "Image.h"
32
#include "RetainPtr.h"
33
34
#include <CoreGraphics/CoreGraphics.h>
35
36
#include <windows.h>
37
38
namespace 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
}
54
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
    
142
DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
143
{
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
{    
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
    
187
DragImageRef createDragImageIconForCachedImage(CachedImage*)
188
{
189
    //FIXME: Provide icon for image type <rdar://problem/5015949>
190
    return 0;     
191
}
192
    
193
}
- WebCore/platform/win/DragImageCGWin.cpp -30 / +3 lines
Lines 1-5 WebCore/platform/win/DragImageCGWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 37-57 WebCore/platform/win/DragImageCGWin.cpp_sec2
37
37
38
namespace WebCore {
38
namespace WebCore {
39
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
}
54
55
HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
40
HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef)
56
{
41
{
57
    HBITMAP hbmp;
42
    HBITMAP hbmp;
Lines 106-112 DragImageRef scaleDragImage(DragImageRef WebCore/platform/win/DragImageCGWin.cpp_sec3
106
    CGContextRef srcContext;
91
    CGContextRef srcContext;
107
    CGImageRef srcImage;
92
    CGImageRef srcImage;
108
    IntSize srcSize = dragImageSize(image);
93
    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()));
110
    HBITMAP hbmp = 0;
95
    HBITMAP hbmp = 0;
111
    HDC dc = GetDC(0);
96
    HDC dc = GetDC(0);
112
    HDC dstDC = CreateCompatibleDC(dc);
97
    HDC dstDC = CreateCompatibleDC(dc);
Lines 139-152 exit: WebCore/platform/win/DragImageCGWin.cpp_sec4
139
    return hbmp;
124
    return hbmp;
140
}
125
}
141
    
126
    
142
DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
143
{
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)
127
DragImageRef createDragImageFromImage(Image* img)
149
{    
128
{
150
    HBITMAP hbmp = 0;
129
    HBITMAP hbmp = 0;
151
    HDC dc = GetDC(0);
130
    HDC dc = GetDC(0);
152
    HDC workingDC = CreateCompatibleDC(dc);
131
    HDC workingDC = CreateCompatibleDC(dc);
Lines 184-193 exit: WebCore/platform/win/DragImageCGWin.cpp_sec5
184
    return hbmp;
163
    return hbmp;
185
}
164
}
186
    
165
    
187
DragImageRef createDragImageIconForCachedImage(CachedImage*)
188
{
189
    //FIXME: Provide icon for image type <rdar://problem/5015949>
190
    return 0;     
191
}
192
    
193
}
166
}
- WebCore/platform/win/DragImageCairoWin.cpp +54 lines
Line 0 WebCore/platform/win/DragImageCairoWin.cpp_sec1
1
/*
2
 * Copyright (C) 2008 Apple Inc.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "DragImage.h"
28
29
#include "CachedImage.h"
30
#include "GraphicsContext.h"
31
#include "Image.h"
32
#include "NotImplemented.h"
33
#include "RetainPtr.h"
34
35
#include <windows.h>
36
37
namespace WebCore {
38
39
DragImageRef scaleDragImage(DragImageRef image, FloatSize scale)
40
{
41
    notImplemented();
42
43
    return image;
44
}
45
    
46
DragImageRef createDragImageFromImage(Image* img)
47
{
48
    notImplemented();
49
50
    DragImageRef temp;
51
    return temp;
52
}
53
    
54
}
- WebCore/platform/win/DragImageWin.cpp -129 / +1 lines
Lines 1-5 WebCore/platform/win/DragImageWin.cpp_sec1
1
/*
1
/*
2
 * Copyright (C) 2007 Apple Inc.  All rights reserved.
2
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
3
 *
3
 *
4
 * Redistribution and use in source and binary forms, with or without
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
5
 * modification, are permitted provided that the following conditions
Lines 31-38 WebCore/platform/win/DragImageWin.cpp_sec2
31
#include "Image.h"
31
#include "Image.h"
32
#include "RetainPtr.h"
32
#include "RetainPtr.h"
33
33
34
#include <CoreGraphics/CoreGraphics.h>
35
36
#include <windows.h>
34
#include <windows.h>
37
35
38
namespace WebCore {
36
namespace WebCore {
Lines 52-189 void deleteDragImage(DragImageRef image) WebCore/platform/win/DragImageWin.cpp_sec3
52
        ::DeleteObject(image);
50
        ::DeleteObject(image);
53
}
51
}
54
52
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
    
142
DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
53
DragImageRef dissolveDragImageToFraction(DragImageRef image, float)
143
{
54
{
144
    //We don't do this on windows as the dragimage is blended by the OS
55
    //We don't do this on windows as the dragimage is blended by the OS
145
    return image;
56
    return image;
146
}
57
}
147
        
58
        
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
    
187
DragImageRef createDragImageIconForCachedImage(CachedImage*)
59
DragImageRef createDragImageIconForCachedImage(CachedImage*)
188
{
60
{
189
    //FIXME: Provide icon for image type <rdar://problem/5015949>
61
    //FIXME: Provide icon for image type <rdar://problem/5015949>

Return to Bug 16979