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