• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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 #if USE(CG)
30 #include "GraphicsContextPlatformPrivateCG.h"
31 #elif USE(CAIRO)
32 #include "GraphicsContextPlatformPrivateCairo.h"
33 #endif
34 
35 #include "AffineTransform.h"
36 #include "BitmapInfo.h"
37 #include "TransformationMatrix.h"
38 #include "NotImplemented.h"
39 #include "Path.h"
40 #include <wtf/MathExtras.h>
41 
42 using namespace std;
43 
44 namespace WebCore {
45 
fillWithClearColor(HBITMAP bitmap)46 static void fillWithClearColor(HBITMAP bitmap)
47 {
48     BITMAP bmpInfo;
49     GetObject(bitmap, sizeof(bmpInfo), &bmpInfo);
50     int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
51     memset(bmpInfo.bmBits, 0, bufferSize);
52 }
53 
inTransparencyLayer() const54 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }
55 
setShouldIncludeChildWindows(bool include)56 void GraphicsContext::setShouldIncludeChildWindows(bool include)
57 {
58     m_data->m_shouldIncludeChildWindows = include;
59 }
60 
shouldIncludeChildWindows() const61 bool GraphicsContext::shouldIncludeChildWindows() const
62 {
63     return m_data->m_shouldIncludeChildWindows;
64 }
65 
WindowsBitmap(HDC hdc,IntSize size)66 GraphicsContext::WindowsBitmap::WindowsBitmap(HDC hdc, IntSize size)
67     : m_hdc(0)
68 {
69     BitmapInfo bitmapInfo = BitmapInfo::create(size);
70 
71     void* storage = 0;
72     m_bitmap = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &storage, 0, 0);
73     if (!m_bitmap)
74         return;
75 
76     m_hdc = CreateCompatibleDC(hdc);
77     SelectObject(m_hdc, m_bitmap);
78 
79     m_pixelData.initialize(m_bitmap);
80 
81     ASSERT(storage == m_pixelData.buffer());
82 
83     SetGraphicsMode(m_hdc, GM_ADVANCED);
84 }
85 
~WindowsBitmap()86 GraphicsContext::WindowsBitmap::~WindowsBitmap()
87 {
88     if (!m_bitmap)
89         return;
90 
91     DeleteDC(m_hdc);
92     DeleteObject(m_bitmap);
93 }
94 
createWindowsBitmap(IntSize size)95 GraphicsContext::WindowsBitmap* GraphicsContext::createWindowsBitmap(IntSize size)
96 {
97     return new WindowsBitmap(m_data->m_hdc, size);
98 }
99 
getWindowsContext(const IntRect & dstRect,bool supportAlphaBlend,bool mayCreateBitmap)100 HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend, bool mayCreateBitmap)
101 {
102     // FIXME: Should a bitmap be created also when a shadow is set?
103     if (mayCreateBitmap && (!m_data->m_hdc || inTransparencyLayer())) {
104         if (dstRect.isEmpty())
105             return 0;
106 
107         // Create a bitmap DC in which to draw.
108         BitmapInfo bitmapInfo = BitmapInfo::create(dstRect.size());
109 
110         void* pixels = 0;
111         HBITMAP bitmap = ::CreateDIBSection(NULL, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0);
112         if (!bitmap)
113             return 0;
114 
115         HDC bitmapDC = ::CreateCompatibleDC(m_data->m_hdc);
116         ::SelectObject(bitmapDC, bitmap);
117 
118         // Fill our buffer with clear if we're going to alpha blend.
119         if (supportAlphaBlend)
120            fillWithClearColor(bitmap);
121 
122         // Make sure we can do world transforms.
123         SetGraphicsMode(bitmapDC, GM_ADVANCED);
124 
125         // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap.
126         XFORM xform = TransformationMatrix().translate(-dstRect.x(), -dstRect.y());
127 
128         ::SetWorldTransform(bitmapDC, &xform);
129 
130         return bitmapDC;
131     }
132 
133     m_data->flush();
134     m_data->save();
135     return m_data->m_hdc;
136 }
137 
save()138 void GraphicsContextPlatformPrivate::save()
139 {
140     if (!m_hdc)
141         return;
142     SaveDC(m_hdc);
143 }
144 
restore()145 void GraphicsContextPlatformPrivate::restore()
146 {
147     if (!m_hdc)
148         return;
149     RestoreDC(m_hdc, -1);
150 }
151 
clip(const FloatRect & clipRect)152 void GraphicsContextPlatformPrivate::clip(const FloatRect& clipRect)
153 {
154     if (!m_hdc)
155         return;
156     IntersectClipRect(m_hdc, clipRect.x(), clipRect.y(), clipRect.maxX(), clipRect.maxY());
157 }
158 
clip(const Path &)159 void GraphicsContextPlatformPrivate::clip(const Path&)
160 {
161     notImplemented();
162 }
163 
scale(const FloatSize & size)164 void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
165 {
166     if (!m_hdc)
167         return;
168 
169     XFORM xform = TransformationMatrix().scaleNonUniform(size.width(), size.height());
170     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
171 }
172 
173 static const double deg2rad = 0.017453292519943295769; // pi/180
174 
rotate(float degreesAngle)175 void GraphicsContextPlatformPrivate::rotate(float degreesAngle)
176 {
177     XFORM xform = TransformationMatrix().rotate(degreesAngle);
178     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
179 }
180 
translate(float x,float y)181 void GraphicsContextPlatformPrivate::translate(float x , float y)
182 {
183     if (!m_hdc)
184         return;
185 
186     XFORM xform = TransformationMatrix().translate(x, y);
187     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
188 }
189 
concatCTM(const AffineTransform & transform)190 void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform)
191 {
192     if (!m_hdc)
193         return;
194 
195     XFORM xform = transform.toTransformationMatrix();
196     ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY);
197 }
198 
setCTM(const AffineTransform & transform)199 void GraphicsContextPlatformPrivate::setCTM(const AffineTransform& transform)
200 {
201     if (!m_hdc)
202         return;
203 
204     XFORM xform = transform.toTransformationMatrix();
205     SetWorldTransform(m_hdc, &xform);
206 }
207 
208 }
209