Changeset 30056 in webkit
- Timestamp:
- Feb 6, 2008 5:52:05 PM (16 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 6 added
- 11 edited
- 7 copied
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r30055 r30056 1 2008-02-06 Brent Fulgham <bfulgham@gmail.com> 2 3 Reviewed by Adam Roben. 4 5 http://bugs.webkit.org/show_bug.cgi?id=16979 6 Conditionalize CoreGraphics vs Cairo support in Windows port. 7 8 * WebCore.vcproj/WebCore.vcproj: 9 * bridge/win/FrameCGWin.cpp: Copied from WebCore/bridge/win/FrameWin.cpp. 10 (WebCore::imageFromSelection): 11 * bridge/win/FrameCairoWin.cpp: Added. 12 (WebCore::imageFromSelection): 13 * bridge/win/FrameWin.cpp: 14 (WebCore::computePageRectsForFrame): 15 * platform/graphics/SimpleFontData.h: 16 * platform/graphics/cairo/GraphicsContextCairo.cpp: 17 * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Copied from WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp. 18 (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate): 19 (WebCore::GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate): 20 (WebCore::GraphicsContextPlatformPrivate::beginTransparencyLayer): 21 (WebCore::GraphicsContextPlatformPrivate::endTransparencyLayer): 22 * platform/graphics/cg/GraphicsContextCG.cpp: 23 (WebCore::GraphicsContext::savePlatformState): 24 (WebCore::GraphicsContext::restorePlatformState): 25 * platform/graphics/cg/GraphicsContextPlatformPrivate.h: Removed. 26 * platform/graphics/cg/GraphicsContextPlatformPrivateCG.h: Copied from WebCore/platform/graphics/cg/GraphicsContextPlatformPrivate.h. 27 * platform/graphics/win/FontCGWin.cpp: Copied from WebCore/platform/graphics/win/FontWin.cpp. 28 (WebCore::Font::drawGlyphs): 29 * platform/graphics/win/FontCairoWin.cpp: Added. 30 (WebCore::Font::drawGlyphs): 31 * platform/graphics/win/FontWin.cpp: 32 * platform/graphics/win/GraphicsContextCGWin.cpp: Copied from WebCore/platform/graphics/win/GraphicsContextWin.cpp. 33 (WebCore::CGContextWithHDC): 34 (WebCore::GraphicsContext::inTransparencyLayer): 35 (WebCore::GraphicsContext::getWindowsContext): 36 (WebCore::GraphicsContext::releaseWindowsContext): 37 (WebCore::GraphicsContextPlatformPrivate::scale): 38 (WebCore::GraphicsContextPlatformPrivate::rotate): 39 (WebCore::GraphicsContextPlatformPrivate::translate): 40 (WebCore::GraphicsContextPlatformPrivate::concatCTM): 41 (WebCore::setCGStrokeColor): 42 (WebCore::GraphicsContext::drawLineForMisspellingOrBadGrammar): 43 * platform/graphics/win/GraphicsContextCairoWin.cpp: Added. 44 (WebCore::GraphicsContext::GraphicsContext): 45 (WebCore::GraphicsContext::getWindowsContext): 46 (WebCore::GraphicsContext::inTransparencyLayer): 47 (WebCore::GraphicsContext::releaseWindowsContext): 48 (WebCore::GraphicsContext::concatCTM): 49 * platform/graphics/win/GraphicsContextWin.cpp: 50 * platform/graphics/win/ImageCGWin.cpp: Copied from WebCore/platform/graphics/win/ImageWin.cpp. 51 (WebCore::BitmapImage::getHBITMAPOfSize): 52 (WebCore::BitmapImage::drawFrameMatchingSourceSize): 53 * platform/graphics/win/ImageCairoWin.cpp: Added. 54 (WebCore::BitmapImage::getHBITMAPOfSize): 55 (WebCore::BitmapImage::drawFrameMatchingSourceSize): 56 * platform/graphics/win/ImageWin.cpp: 57 * platform/graphics/win/SimpleFontDataCGWin.cpp: Copied from WebCore/platform/graphics/win/SimpleFontDataWin.cpp. 58 (WebCore::scaleEmToUnits): 59 (WebCore::SimpleFontData::platformInit): 60 (WebCore::SimpleFontData::platformWidthForGlyph): 61 * platform/graphics/win/SimpleFontDataCairoWin.cpp: Added. 62 (WebCore::SimpleFontData::platformInit): 63 (WebCore::SimpleFontData::platformDestroy): 64 (WebCore::SimpleFontData::platformWidthForGlyph): 65 * platform/graphics/win/SimpleFontDataWin.cpp: 66 (WebCore::SimpleFontData::setShouldApplyMacAscentHack): 67 (WebCore::SimpleFontData::shouldApplyMacAscentHack): 68 * platform/win/DragImageCGWin.cpp: Copied from WebCore/platform/win/DragImageWin.cpp. 69 (WebCore::scaleDragImage): 70 (WebCore::createDragImageFromImage): 71 * platform/win/DragImageCairoWin.cpp: Added. 72 (WebCore::scaleDragImage): 73 (WebCore::createDragImageFromImage): 74 * platform/win/DragImageWin.cpp: 75 1 76 2008-02-06 Anders Carlsson <andersca@apple.com> 2 77 -
trunk/WebCore/WebCore.vcproj/WebCore.vcproj
r30035 r30056 3418 3418 > 3419 3419 </File> 3420 RelativePath="..\platform\win\DragImageCGWin.cpp" 3421 > 3422 </File> 3420 3423 <File 3421 3424 RelativePath="..\platform\win\DragImageWin.cpp" … … 3874 3877 <File 3875 3878 RelativePath="..\platform\graphics\win\FontCacheWin.cpp" 3879 > 3880 </File> 3881 <File 3882 RelativePath="..\platform\graphics\win\FontCGWin.cpp" 3876 3883 > 3877 3884 </File> … … 3933 3940 </File> 3934 3941 <File 3942 RelativePath="..\platform\graphics\win\GraphicsContextCGWin.cpp" 3943 > 3944 </File> 3945 <File 3935 3946 RelativePath="..\platform\graphics\win\GraphicsContextWin.cpp" 3936 3947 > … … 3941 3952 </File> 3942 3953 <File 3954 RelativePath="..\platform\graphics\win\ImageCGWin.cpp" 3955 > 3956 </File> 3957 <File 3943 3958 RelativePath="..\platform\graphics\win\ImageWin.cpp" 3944 3959 > … … 3962 3977 <File 3963 3978 RelativePath="..\platform\graphics\win\MediaPlayerPrivateQuickTimeWin.h" 3979 > 3980 </File> 3981 <File 3982 RelativePath="..\platform\graphics\win\SimpleFontDataCGWin.cpp" 3964 3983 > 3965 3984 </File> … … 6408 6427 Name="win" 6409 6428 > 6429 <File 6430 RelativePath="..\bridge\win\FrameCGWin.cpp" 6431 > 6432 </File> 6410 6433 <File 6411 6434 RelativePath="..\bridge\win\FrameWin.cpp" -
trunk/WebCore/bridge/win/FrameCGWin.cpp
r30053 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "FrameWin.h" 28 28 29 #include <winsock2.h>30 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 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 "PluginDatabase.h"49 #include "PluginView.h"50 #include "RegularExpression.h"51 #include "RenderFrame.h"52 #include "RenderTableCell.h"53 #include "RenderView.h"54 #include "ResourceHandle.h"55 #include "TextResourceDecoder.h"56 #include "kjs_proxy.h"57 #include "kjs_window.h"58 #include "npruntime_impl.h"59 #include "runtime_root.h"60 32 #include "GraphicsContext.h" 61 33 #include "Settings.h" 62 34 63 #if PLATFORM(CG)64 35 #include <CoreGraphics/CoreGraphics.h> 65 #endif66 36 67 37 using std::min; 68 using namespace KJS::Bindings;69 38 70 39 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<PluginView*>(widget)->bindingInstance();85 }86 87 88 void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight)89 {90 ASSERT(frame);91 92 pages.clear();93 outPageHeight = 0;94 95 if (!frame->document() || !frame->view() || !frame->document()->renderer())96 return;97 98 RenderView* root = static_cast<RenderView *>(frame->document()->renderer());99 100 if (!root) {101 LOG_ERROR("document to be printed has no renderer");102 return;103 }104 105 if (userScaleFactor <= 0) {106 LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor);107 return;108 }109 110 float ratio = (float)printRect.height() / (float)printRect.width();111 112 float pageWidth = (float) root->docWidth();113 float pageHeight = pageWidth * ratio;114 outPageHeight = (int) pageHeight; // this is the height of the page adjusted by margins115 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 page129 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 40 140 41 static void drawRectIntoContext(IntRect rect, FrameView* view, GraphicsContext* gc) … … 153 54 frame->setPaintRestriction(forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly); 154 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 59 void* bits; … … 161 63 BITMAPINFO bmp = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32 } }; 162 64 163 HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, (void**)&bits, 0, 0);164 HBITMAP hbmpOld = (HBITMAP)SelectObject(hdc, hbmp);65 HBITMAP hbmp = CreateDIBSection(0, &bmp, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0); 66 HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp)); 165 67 CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); 166 CGContextRef context = CGBitmapContextCreate( (void*)bits, w, h,68 CGContextRef context = CGBitmapContextCreate(static_cast<void*>(bits), w, h, 167 69 8, w * sizeof(RGBQUAD), deviceRGB, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst); 168 70 CGColorSpaceRelease(deviceRGB); … … 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 87 } // namespace WebCore -
trunk/WebCore/bridge/win/FrameWin.cpp
r30015 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 61 61 #include "Settings.h" 62 62 63 #if PLATFORM(CG)64 #include <CoreGraphics/CoreGraphics.h>65 #endif66 67 63 using std::min; 68 64 using namespace KJS::Bindings; … … 84 80 return static_cast<PluginView*>(widget)->bindingInstance(); 85 81 } 86 87 82 88 83 void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor,Vector<IntRect>& pages, int& outPageHeight) … … 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 108 float pageHeight = pageWidth * ratio; 114 outPageHeight = (int) pageHeight; // this is the height of the page adjusted by margins109 outPageHeight = static_cast<int>(pageHeight); // this is the height of the page adjusted by margins 115 110 pageHeight -= (headerHeight + footerHeight); 116 111 … … 127 122 128 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 125 do { 131 126 float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); … … 133 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 131 printedPagesHeight += currPageHeight; 137 132 } 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 133 } 184 134 -
trunk/WebCore/platform/graphics/SimpleFontData.h
r29940 r30056 104 104 105 105 static void setShouldApplyMacAscentHack(bool); 106 static bool shouldApplyMacAscentHack(); 106 107 #endif 107 108 -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r29961 r30056 43 43 #include <wtf/MathExtras.h> 44 44 45 #if PLATFORM(WIN)46 #include <cairo-win32.h>47 #endif48 49 45 #if PLATFORM(GTK) 50 46 #include <gdk/gdk.h> 51 47 #include <pango/pango.h> 48 #elif PLATFORM(WIN) 49 #include <cairo-win32.h> 52 50 #endif 53 51 #include "GraphicsContextPlatformPrivateCairo.h" 54 52 55 53 #ifndef M_PI … … 58 56 59 57 namespace WebCore { 60 61 class GraphicsContextPlatformPrivate {62 public:63 GraphicsContextPlatformPrivate();64 ~GraphicsContextPlatformPrivate();65 66 cairo_t* cr;67 Vector<float> layers;68 69 #if PLATFORM(GTK)70 GdkEventExpose* expose;71 #endif72 };73 58 74 59 static inline void setColor(cairo_t* cr, const Color& col) … … 87 72 cairo_fill(cr); 88 73 } 89 90 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()91 : cr(0)92 #if PLATFORM(GTK)93 , expose(0)94 #endif95 {96 }97 98 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()99 {100 cairo_destroy(cr);101 }102 103 #if PLATFORM(WIN)104 GraphicsContext::GraphicsContext(HDC dc)105 : m_common(createGraphicsContextPrivate())106 , m_data(new GraphicsContextPlatformPrivate)107 {108 if (dc) {109 cairo_surface_t* surface = cairo_win32_surface_create(dc);110 m_data->cr = cairo_create(surface);111 } else {112 setPaintingDisabled(true);113 m_data->cr = 0;114 }115 }116 #endif117 74 118 75 GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr) … … 587 544 } 588 545 546 #if PLATFORM(GTK) 547 // FIXME: This should be moved to something like GraphicsContextCairoGTK.cpp, 548 // as there is a Windows implementation in platform/graphics/win/GraphicsContextCairoWin.cpp 589 549 void GraphicsContext::concatCTM(const AffineTransform& transform) 590 550 { … … 596 556 cairo_transform(cr, matrix); 597 557 } 558 #endif 598 559 599 560 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) -
trunk/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
r30053 r30056 2 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. 3 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> 4 * Copyright (C) 2008 Brent Fulgham <bfulgham@gmail.com> 4 5 * 5 6 * Redistribution and use in source and binary forms, with or without … … 22 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 26 */ 26 27 27 #include "config.h"28 28 #include "GraphicsContext.h" 29 29 30 #if PLATFORM(CAIRO)31 32 #include "AffineTransform.h"33 #include "CairoPath.h"34 #include "FloatRect.h"35 #include "Font.h"36 #include "IntRect.h"37 #include "NotImplemented.h"38 #include "Path.h"39 #include "SimpleFontData.h"40 30 #include <cairo.h> 41 31 #include <math.h> … … 43 33 #include <wtf/MathExtras.h> 44 34 45 #if PLATFORM(WIN)46 #include <cairo-win32.h>47 #endif48 49 35 #if PLATFORM(GTK) 50 36 #include <gdk/gdk.h> 51 37 #include <pango/pango.h> 52 #endif 53 54 55 #ifndef M_PI 56 #define M_PI 3.14159265358979323846 38 #elif PLATFORM(WIN) 39 #include <cairo-win32.h> 57 40 #endif 58 41 … … 61 44 class GraphicsContextPlatformPrivate { 62 45 public: 63 GraphicsContextPlatformPrivate(); 64 ~GraphicsContextPlatformPrivate(); 46 GraphicsContextPlatformPrivate() 47 : cr(0) 48 #if PLATFORM(GTK) 49 , expose(0) 50 #elif PLATFORM(WIN) 51 // NOTE: These may note be needed: review and remove once Cairo implementation is complete 52 , m_hdc(0) 53 , m_transparencyCount(0) 54 #endif 55 { 56 } 57 58 ~GraphicsContextPlatformPrivate() 59 { 60 cairo_destroy(cr); 61 } 62 63 #if PLATFORM(WIN) 64 // On Windows, we need to update the HDC for form controls to draw in the right place. 65 void beginTransparencyLayer() { m_transparencyCount++; } 66 void endTransparencyLayer() { m_transparencyCount--; } 67 #endif 65 68 66 69 cairo_t* cr; … … 69 72 #if PLATFORM(GTK) 70 73 GdkEventExpose* expose; 74 #elif PLATFORM(WIN) 75 HDC m_hdc; 76 unsigned m_transparencyCount; 71 77 #endif 72 78 }; 73 79 74 static inline void setColor(cairo_t* cr, const Color& col)75 {76 float red, green, blue, alpha;77 col.getRGBA(red, green, blue, alpha);78 cairo_set_source_rgba(cr, red, green, blue, alpha);79 }80 81 // A fillRect helper82 static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const Color& col)83 {84 setColor(cr, col);85 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());86 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);87 cairo_fill(cr);88 }89 90 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()91 : cr(0)92 #if PLATFORM(GTK)93 , expose(0)94 #endif95 {96 }97 98 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()99 {100 cairo_destroy(cr);101 }102 103 #if PLATFORM(WIN)104 GraphicsContext::GraphicsContext(HDC dc)105 : m_common(createGraphicsContextPrivate())106 , m_data(new GraphicsContextPlatformPrivate)107 {108 if (dc) {109 cairo_surface_t* surface = cairo_win32_surface_create(dc);110 m_data->cr = cairo_create(surface);111 } else {112 setPaintingDisabled(true);113 m_data->cr = 0;114 }115 }116 #endif117 118 GraphicsContext::GraphicsContext(PlatformGraphicsContext* cr)119 : m_common(createGraphicsContextPrivate())120 , m_data(new GraphicsContextPlatformPrivate)121 {122 m_data->cr = cairo_reference(cr);123 setPaintingDisabled(!cr);124 }125 126 GraphicsContext::~GraphicsContext()127 {128 destroyGraphicsContextPrivate(m_common);129 delete m_data;130 }131 132 AffineTransform GraphicsContext::getCTM() const133 {134 cairo_t* cr = platformContext();135 cairo_matrix_t m;136 cairo_get_matrix(cr, &m);137 return m;138 }139 140 cairo_t* GraphicsContext::platformContext() const141 {142 return m_data->cr;143 }144 145 void GraphicsContext::savePlatformState()146 {147 cairo_save(m_data->cr);148 }149 150 void GraphicsContext::restorePlatformState()151 {152 cairo_restore(m_data->cr);153 }154 155 // Draws a filled rectangle with a stroked border.156 void GraphicsContext::drawRect(const IntRect& rect)157 {158 if (paintingDisabled())159 return;160 161 cairo_t* cr = m_data->cr;162 cairo_save(cr);163 164 if (fillColor().alpha())165 fillRectSourceOver(cr, rect, fillColor());166 167 if (strokeStyle() != NoStroke) {168 setColor(cr, strokeColor());169 FloatRect r(rect);170 r.inflate(-.5f);171 cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());172 cairo_set_line_width(cr, 1.0);173 cairo_stroke(cr);174 }175 176 cairo_restore(cr);177 }178 179 // FIXME: Now that this is refactored, it should be shared by all contexts.180 static void adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2, float strokeWidth, StrokeStyle style)181 {182 // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic183 // works out. For example, with a border width of 3, KHTML will pass us (y1+y2)/2, e.g.,184 // (50+53)/2 = 103/2 = 51 when we want 51.5. It is always true that an even width gave185 // us a perfect position, but an odd width gave us a position that is off by exactly 0.5.186 if (style == DottedStroke || style == DashedStroke) {187 if (p1.x() == p2.x()) {188 p1.setY(p1.y() + strokeWidth);189 p2.setY(p2.y() - strokeWidth);190 }191 else {192 p1.setX(p1.x() + strokeWidth);193 p2.setX(p2.x() - strokeWidth);194 }195 }196 197 if (static_cast<int>(strokeWidth) % 2) {198 if (p1.x() == p2.x()) {199 // We're a vertical line. Adjust our x.200 p1.setX(p1.x() + 0.5);201 p2.setX(p2.x() + 0.5);202 }203 else {204 // We're a horizontal line. Adjust our y.205 p1.setY(p1.y() + 0.5);206 p2.setY(p2.y() + 0.5);207 }208 }209 }210 211 // This is only used to draw borders.212 void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)213 {214 if (paintingDisabled())215 return;216 217 StrokeStyle style = strokeStyle();218 if (style == NoStroke)219 return;220 221 cairo_t* cr = m_data->cr;222 cairo_save(cr);223 224 float width = strokeThickness();225 if (width < 1)226 width = 1;227 228 FloatPoint p1 = point1;229 FloatPoint p2 = point2;230 bool isVerticalLine = (p1.x() == p2.x());231 232 adjustLineToPixelBoundaries(p1, p2, width, style);233 cairo_set_line_width(cr, width);234 235 int patWidth = 0;236 switch (style) {237 case NoStroke:238 case SolidStroke:239 break;240 case DottedStroke:241 patWidth = static_cast<int>(width);242 break;243 case DashedStroke:244 patWidth = 3*static_cast<int>(width);245 break;246 }247 248 setColor(cr, strokeColor());249 250 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);251 252 if (patWidth) {253 // Do a rect fill of our endpoints. This ensures we always have the254 // appearance of being a border. We then draw the actual dotted/dashed line.255 if (isVerticalLine) {256 fillRectSourceOver(cr, FloatRect(p1.x() - width/2, p1.y() - width, width, width), strokeColor());257 fillRectSourceOver(cr, FloatRect(p2.x() - width/2, p2.y(), width, width), strokeColor());258 } else {259 fillRectSourceOver(cr, FloatRect(p1.x() - width, p1.y() - width/2, width, width), strokeColor());260 fillRectSourceOver(cr, FloatRect(p2.x(), p2.y() - width/2, width, width), strokeColor());261 }262 263 // Example: 80 pixels with a width of 30 pixels.264 // Remainder is 20. The maximum pixels of line we could paint265 // will be 50 pixels.266 int distance = (isVerticalLine ? (point2.y() - point1.y()) : (point2.x() - point1.x())) - 2*static_cast<int>(width);267 int remainder = distance%patWidth;268 int coverage = distance-remainder;269 int numSegments = coverage/patWidth;270 271 float patternOffset = 0;272 // Special case 1px dotted borders for speed.273 if (patWidth == 1)274 patternOffset = 1.0;275 else {276 bool evenNumberOfSegments = numSegments%2 == 0;277 if (remainder)278 evenNumberOfSegments = !evenNumberOfSegments;279 if (evenNumberOfSegments) {280 if (remainder) {281 patternOffset += patWidth - remainder;282 patternOffset += remainder/2;283 }284 else285 patternOffset = patWidth/2;286 }287 else if (!evenNumberOfSegments) {288 if (remainder)289 patternOffset = (patWidth - remainder)/2;290 }291 }292 293 double dash = patWidth;294 cairo_set_dash(cr, &dash, 1, patternOffset);295 }296 297 cairo_move_to(cr, p1.x(), p1.y());298 cairo_line_to(cr, p2.x(), p2.y());299 300 cairo_stroke(cr);301 cairo_restore(cr);302 }303 304 // This method is only used to draw the little circles used in lists.305 void GraphicsContext::drawEllipse(const IntRect& rect)306 {307 if (paintingDisabled())308 return;309 310 cairo_t* cr = m_data->cr;311 cairo_save(cr);312 float yRadius = .5 * rect.height();313 float xRadius = .5 * rect.width();314 cairo_translate(cr, rect.x() + xRadius, rect.y() + yRadius);315 cairo_scale(cr, xRadius, yRadius);316 cairo_arc(cr, 0., 0., 1., 0., 2 * M_PI);317 cairo_restore(cr);318 319 if (fillColor().alpha()) {320 setColor(cr, fillColor());321 cairo_fill_preserve(cr);322 }323 324 if (strokeStyle() != NoStroke) {325 setColor(cr, strokeColor());326 cairo_set_line_width(cr, strokeThickness());327 cairo_stroke(cr);328 }329 330 cairo_new_path(cr);331 }332 333 // FIXME: This function needs to be adjusted to match the functionality on the Mac side.334 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)335 {336 if (paintingDisabled())337 return;338 339 if (strokeStyle() == NoStroke)340 return;341 342 int x = rect.x();343 int y = rect.y();344 float w = rect.width();345 #if 0 // FIXME: unused so far346 float h = rect.height();347 float scaleFactor = h / w;348 float reverseScaleFactor = w / h;349 #endif350 float r = w / 2;351 float fa = startAngle;352 float falen = fa + angleSpan;353 354 cairo_t* cr = m_data->cr;355 cairo_save(cr);356 cairo_arc_negative(cr, x + r, y + r, r, -fa * M_PI/180, -falen * M_PI/180);357 setColor(cr, strokeColor());358 cairo_set_line_width(cr, strokeThickness());359 cairo_stroke(cr);360 cairo_restore(cr);361 }362 363 void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)364 {365 if (paintingDisabled())366 return;367 368 if (npoints <= 1)369 return;370 371 cairo_t* cr = m_data->cr;372 373 cairo_save(cr);374 cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);375 cairo_move_to(cr, points[0].x(), points[0].y());376 for (size_t i = 1; i < npoints; i++)377 cairo_line_to(cr, points[i].x(), points[i].y());378 cairo_close_path(cr);379 380 if (fillColor().alpha()) {381 setColor(cr, fillColor());382 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);383 cairo_fill_preserve(cr);384 }385 386 if (strokeStyle() != NoStroke) {387 setColor(cr, strokeColor());388 cairo_set_line_width(cr, strokeThickness());389 cairo_stroke(cr);390 }391 392 cairo_new_path(cr);393 cairo_restore(cr);394 }395 396 void GraphicsContext::fillRect(const IntRect& rect, const Color& color)397 {398 if (paintingDisabled())399 return;400 401 if (color.alpha())402 fillRectSourceOver(m_data->cr, rect, color);403 }404 405 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)406 {407 if (paintingDisabled())408 return;409 410 if (color.alpha())411 fillRectSourceOver(m_data->cr, rect, color);412 }413 414 void GraphicsContext::clip(const IntRect& rect)415 {416 if (paintingDisabled())417 return;418 419 cairo_t* cr = m_data->cr;420 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());421 cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);422 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);423 cairo_clip(cr);424 cairo_set_fill_rule(cr, savedFillRule);425 }426 427 void GraphicsContext::drawFocusRing(const Color& color)428 {429 if (paintingDisabled())430 return;431 432 int radius = (focusRingWidth() - 1) / 2;433 int offset = radius + focusRingOffset();434 435 const Vector<IntRect>& rects = focusRingRects();436 unsigned rectCount = rects.size();437 IntRect finalFocusRect;438 for (unsigned i = 0; i < rectCount; i++) {439 IntRect focusRect = rects[i];440 focusRect.inflate(offset);441 finalFocusRect.unite(focusRect);442 }443 444 cairo_t* cr = m_data->cr;445 cairo_save(cr);446 // FIXME: These rects should be rounded447 cairo_rectangle(cr, finalFocusRect.x(), finalFocusRect.y(), finalFocusRect.width(), finalFocusRect.height());448 449 // Force the alpha to 50%. This matches what the Mac does with outline rings.450 Color ringColor(color.red(), color.green(), color.blue(), 127);451 setColor(cr, ringColor);452 cairo_stroke(cr);453 cairo_restore(cr);454 }455 456 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)457 {458 if (paintingDisabled())459 return;460 461 // This is a workaround for http://bugs.webkit.org/show_bug.cgi?id=15659462 StrokeStyle savedStrokeStyle = strokeStyle();463 setStrokeStyle(SolidStroke);464 465 IntPoint endPoint = origin + IntSize(width, 0);466 drawLine(origin, endPoint);467 468 setStrokeStyle(savedStrokeStyle);469 }470 471 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)472 {473 if (paintingDisabled())474 return;475 476 #if PLATFORM(GTK)477 cairo_t* cr = m_data->cr;478 cairo_save(cr);479 480 // Convention is green for grammar, red for spelling481 // These need to become configurable482 if (grammar)483 cairo_set_source_rgb(cr, 0, 1, 0);484 else485 cairo_set_source_rgb(cr, 1, 0, 0);486 487 // We ignore most of the provided constants in favour of the platform style488 pango_cairo_show_error_underline(cr, origin.x(), origin.y(), width, cMisspellingLineThickness);489 490 cairo_restore(cr);491 #else492 notImplemented();493 #endif494 }495 496 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)497 {498 FloatRect result;499 double x = frect.x();500 double y = frect.y();501 cairo_t* cr = m_data->cr;502 cairo_user_to_device(cr, &x, &y);503 x = round(x);504 y = round(y);505 cairo_device_to_user(cr, &x, &y);506 result.setX(static_cast<float>(x));507 result.setY(static_cast<float>(y));508 x = frect.width();509 y = frect.height();510 cairo_user_to_device_distance(cr, &x, &y);511 x = round(x);512 y = round(y);513 cairo_device_to_user_distance(cr, &x, &y);514 result.setWidth(static_cast<float>(x));515 result.setHeight(static_cast<float>(y));516 return result;517 }518 519 void GraphicsContext::translate(float x, float y)520 {521 if (paintingDisabled())522 return;523 524 cairo_t* cr = m_data->cr;525 cairo_translate(cr, x, y);526 }527 528 IntPoint GraphicsContext::origin()529 {530 cairo_matrix_t matrix;531 cairo_t* cr = m_data->cr;532 cairo_get_matrix(cr, &matrix);533 return IntPoint(static_cast<int>(matrix.x0), static_cast<int>(matrix.y0));534 }535 536 void GraphicsContext::setPlatformFillColor(const Color& col)537 {538 // FIXME: this is probably a no-op but I'm not sure539 // notImplemented(); // commented-out because it's chatty and clutters output540 }541 542 void GraphicsContext::setPlatformStrokeColor(const Color& col)543 {544 // FIXME: this is probably a no-op but I'm not sure545 //notImplemented(); // commented-out because it's chatty and clutters output546 }547 548 void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)549 {550 if (paintingDisabled())551 return;552 553 cairo_set_line_width(m_data->cr, strokeThickness);554 }555 556 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)557 {558 static double dashPattern[] = {5.0, 5.0};559 static double dotPattern[] = {1.0, 1.0};560 561 if (paintingDisabled())562 return;563 564 switch (strokeStyle) {565 case NoStroke:566 // FIXME: is it the right way to emulate NoStroke?567 cairo_set_line_width(m_data->cr, 0);568 break;569 case SolidStroke:570 cairo_set_dash(m_data->cr, 0, 0, 0);571 break;572 case DottedStroke:573 cairo_set_dash(m_data->cr, dotPattern, 2, 0);574 break;575 case DashedStroke:576 cairo_set_dash(m_data->cr, dashPattern, 2, 0);577 break;578 default:579 notImplemented();580 break;581 }582 }583 584 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)585 {586 notImplemented();587 }588 589 void GraphicsContext::concatCTM(const AffineTransform& transform)590 {591 if (paintingDisabled())592 return;593 594 cairo_t* cr = m_data->cr;595 const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform);596 cairo_transform(cr, matrix);597 }598 599 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)600 {601 if (paintingDisabled())602 return;603 604 clip(rect);605 606 Path p;607 FloatRect r(rect);608 // Add outer ellipse609 p.addEllipse(r);610 // Add inner ellipse611 r.inflate(-thickness);612 p.addEllipse(r);613 addPath(p);614 615 cairo_t* cr = m_data->cr;616 cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);617 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);618 cairo_clip(cr);619 cairo_set_fill_rule(cr, savedFillRule);620 }621 622 623 void GraphicsContext::setShadow(IntSize const&, int, Color const&)624 {625 notImplemented();626 }627 628 void GraphicsContext::clearShadow()629 {630 notImplemented();631 }632 633 void GraphicsContext::beginTransparencyLayer(float opacity)634 {635 if (paintingDisabled())636 return;637 638 cairo_t* cr = m_data->cr;639 cairo_push_group(cr);640 m_data->layers.append(opacity);641 }642 643 void GraphicsContext::endTransparencyLayer()644 {645 if (paintingDisabled())646 return;647 648 cairo_t* cr = m_data->cr;649 650 cairo_pop_group_to_source(cr);651 cairo_paint_with_alpha(cr, m_data->layers.last());652 m_data->layers.removeLast();653 }654 655 void GraphicsContext::clearRect(const FloatRect& rect)656 {657 if (paintingDisabled())658 return;659 660 cairo_t* cr = m_data->cr;661 662 cairo_save(cr);663 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());664 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);665 cairo_fill(cr);666 cairo_restore(cr);667 }668 669 void GraphicsContext::strokeRect(const FloatRect& rect, float width)670 {671 if (paintingDisabled())672 return;673 674 cairo_t* cr = m_data->cr;675 cairo_save(cr);676 cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());677 setColor(cr, strokeColor());678 cairo_set_line_width(cr, width);679 cairo_stroke(cr);680 cairo_restore(cr);681 }682 683 void GraphicsContext::setLineCap(LineCap lineCap)684 {685 if (paintingDisabled())686 return;687 688 cairo_line_cap_t cairoCap = CAIRO_LINE_CAP_BUTT;689 switch (lineCap) {690 case ButtCap:691 // no-op692 break;693 case RoundCap:694 cairoCap = CAIRO_LINE_CAP_ROUND;695 break;696 case SquareCap:697 cairoCap = CAIRO_LINE_CAP_SQUARE;698 break;699 }700 cairo_set_line_cap(m_data->cr, cairoCap);701 }702 703 void GraphicsContext::setLineJoin(LineJoin lineJoin)704 {705 if (paintingDisabled())706 return;707 708 cairo_line_join_t cairoJoin = CAIRO_LINE_JOIN_MITER;709 switch (lineJoin) {710 case MiterJoin:711 // no-op712 break;713 case RoundJoin:714 cairoJoin = CAIRO_LINE_JOIN_ROUND;715 break;716 case BevelJoin:717 cairoJoin = CAIRO_LINE_JOIN_BEVEL;718 break;719 }720 cairo_set_line_join(m_data->cr, cairoJoin);721 }722 723 void GraphicsContext::setMiterLimit(float miter)724 {725 if (paintingDisabled())726 return;727 728 cairo_set_miter_limit(m_data->cr, miter);729 }730 731 void GraphicsContext::setAlpha(float)732 {733 notImplemented();734 }735 736 static inline cairo_operator_t toCairoOperator(CompositeOperator op)737 {738 switch (op) {739 case CompositeClear:740 return CAIRO_OPERATOR_CLEAR;741 case CompositeCopy:742 return CAIRO_OPERATOR_SOURCE;743 case CompositeSourceOver:744 return CAIRO_OPERATOR_OVER;745 case CompositeSourceIn:746 return CAIRO_OPERATOR_IN;747 case CompositeSourceOut:748 return CAIRO_OPERATOR_OUT;749 case CompositeSourceAtop:750 return CAIRO_OPERATOR_ATOP;751 case CompositeDestinationOver:752 return CAIRO_OPERATOR_DEST_OVER;753 case CompositeDestinationIn:754 return CAIRO_OPERATOR_DEST_IN;755 case CompositeDestinationOut:756 return CAIRO_OPERATOR_DEST_OUT;757 case CompositeDestinationAtop:758 return CAIRO_OPERATOR_DEST_ATOP;759 case CompositeXOR:760 return CAIRO_OPERATOR_XOR;761 case CompositePlusDarker:762 return CAIRO_OPERATOR_SATURATE;763 case CompositeHighlight:764 // There is no Cairo equivalent for CompositeHighlight.765 return CAIRO_OPERATOR_OVER;766 case CompositePlusLighter:767 return CAIRO_OPERATOR_ADD;768 default:769 return CAIRO_OPERATOR_SOURCE;770 }771 }772 773 void GraphicsContext::setCompositeOperation(CompositeOperator op)774 {775 if (paintingDisabled())776 return;777 778 cairo_set_operator(m_data->cr, toCairoOperator(op));779 }780 781 void GraphicsContext::beginPath()782 {783 if (paintingDisabled())784 return;785 786 cairo_t* cr = m_data->cr;787 cairo_new_path(cr);788 }789 790 void GraphicsContext::addPath(const Path& path)791 {792 if (paintingDisabled())793 return;794 795 cairo_t* cr = m_data->cr;796 cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);797 cairo_append_path(cr, p);798 cairo_path_destroy(p);799 }800 801 void GraphicsContext::clip(const Path& path)802 {803 if (paintingDisabled())804 return;805 806 cairo_t* cr = m_data->cr;807 cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);808 cairo_append_path(cr, p);809 cairo_path_destroy(p);810 cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);811 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);812 cairo_clip(cr);813 cairo_set_fill_rule(cr, savedFillRule);814 }815 816 void GraphicsContext::clipOut(const Path& path)817 {818 if (paintingDisabled())819 return;820 821 cairo_t* cr = m_data->cr;822 double x1, y1, x2, y2;823 cairo_clip_extents(cr, &x1, &y1, &x2, &y2);824 cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);825 addPath(path);826 827 cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);828 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);829 cairo_clip(cr);830 cairo_set_fill_rule(cr, savedFillRule);831 }832 833 void GraphicsContext::rotate(float radians)834 {835 if (paintingDisabled())836 return;837 838 cairo_rotate(m_data->cr, radians);839 }840 841 void GraphicsContext::scale(const FloatSize& size)842 {843 if (paintingDisabled())844 return;845 846 cairo_scale(m_data->cr, size.width(), size.height());847 }848 849 void GraphicsContext::clipOut(const IntRect& r)850 {851 if (paintingDisabled())852 return;853 854 cairo_t* cr = m_data->cr;855 double x1, y1, x2, y2;856 cairo_clip_extents(cr, &x1, &y1, &x2, &y2);857 cairo_rectangle(cr, x1, x2, x2 - x1, y2 - y1);858 cairo_rectangle(cr, r.x(), r.y(), r.width(), r.height());859 cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);860 cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);861 cairo_clip(cr);862 cairo_set_fill_rule(cr, savedFillRule);863 }864 865 void GraphicsContext::clipOutEllipseInRect(const IntRect& r)866 {867 if (paintingDisabled())868 return;869 870 Path p;871 p.addEllipse(r);872 clipOut(p);873 }874 875 void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)876 {877 if (paintingDisabled())878 return;879 880 cairo_t* cr = m_data->cr;881 cairo_save(cr);882 beginPath();883 addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));884 setColor(cr, color);885 cairo_fill(cr);886 cairo_restore(cr);887 }888 889 #if PLATFORM(GTK)890 void GraphicsContext::setGdkExposeEvent(GdkEventExpose* expose)891 {892 m_data->expose = expose;893 }894 895 GdkEventExpose* GraphicsContext::gdkExposeEvent() const896 {897 return m_data->expose;898 }899 900 GdkDrawable* GraphicsContext::gdkDrawable() const901 {902 if (!m_data->expose)903 return 0;904 905 return GDK_DRAWABLE(m_data->expose->window);906 }907 908 IntPoint GraphicsContext::translatePoint(const IntPoint& point) const909 {910 cairo_matrix_t tm;911 cairo_get_matrix(m_data->cr, &tm);912 double x = point.x();913 double y = point.y();914 915 cairo_matrix_transform_point(&tm, &x, &y);916 return IntPoint(x, y);917 }918 #endif919 920 void GraphicsContext::setUseAntialiasing(bool enable)921 {922 if (paintingDisabled())923 return;924 925 // When true, use the default Cairo backend antialias mode (usually this926 // enables standard 'grayscale' antialiasing); false to explicitly disable927 // antialiasing. This is the same strategy as used in drawConvexPolygon().928 cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);929 }930 931 80 } // namespace WebCore 932 81 933 #endif // PLATFORM(CAIRO) -
trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r29827 r30056 28 28 #include "GraphicsContext.h" 29 29 30 #if PLATFORM(CG)31 32 30 #include "AffineTransform.h" 33 31 #include "FloatConversion.h" 34 #include "GraphicsContextPlatformPrivate .h"32 #include "GraphicsContextPlatformPrivateCG.h" 35 33 #include "KURL.h" 36 34 #include "Path.h" … … 84 82 { 85 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 85 CGContextSaveGState(platformContext()); 88 86 m_data->save(); … … 92 90 { 93 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 93 CGContextRestoreGState(platformContext()); 96 94 m_data->restore(); … … 931 929 } 932 930 933 #endif // PLATFORM(CG) -
trunk/WebCore/platform/graphics/win/FontCGWin.cpp
r30053 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "Font.h" 28 28 29 #include "FontFallbackList.h"30 29 #include "GlyphBuffer.h" 31 30 #include "GraphicsContext.h" 32 31 #include "IntRect.h" 33 #include "NotImplemented.h"34 32 #include "SimpleFontData.h" 35 33 #include "UniscribeController.h" … … 69 67 // Set the correct color. 70 68 HDC textDrawingDC = hdc; 71 /*if (fillColor.hasAlpha() || graphicsContext->inTransparencyLayer()) { 72 // GDI can't handle drawing transparent text. We have to draw into a mask. We draw black text on a white-filled background. 73 // We also do this when inside transparency layers, since GDI also can't draw onto a surface with alpha. 74 graphicsContext->save(); 75 graphicsContext->setFillColor(Color::white); 76 textDrawingDC = graphicsContext->getWindowsBitmapContext(textRect); 77 SetTextColor(hdc, RGB(0, 0, 0)); 78 } else*/ 79 SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); 69 SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); 80 70 81 71 SetBkMode(hdc, TRANSPARENT); … … 96 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 value100 // 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 88 graphicsContext->releaseWindowsContext(hdc, textRect); 127 89 return; … … 140 102 matrix.d = -matrix.d; 141 103 142 if (platformData.syntheticOblique()) 143 { 144 static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90); 104 if (platformData.syntheticOblique()) { 105 static float skew = -tanf(syntheticObliqueAngle * acosf(0) / 90.0f); 145 106 matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0)); 146 107 } … … 164 125 } 165 126 166 FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h,167 int from, int to) const168 {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 positioning176 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 127 } 184 185 void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point,186 int from, int to) const187 {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 } else207 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) const215 {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) const222 {223 UniscribeController controller(this, run);224 return controller.offsetForPosition(x, includePartialGlyphs);225 }226 227 } -
trunk/WebCore/platform/graphics/win/FontWin.cpp
r29706 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 34 34 #include "SimpleFontData.h" 35 35 #include "UniscribeController.h" 36 #include <ApplicationServices/ApplicationServices.h>37 #include <WebKitSystemInterface/WebKitSystemInterface.h>38 36 #include <wtf/MathExtras.h> 39 37 40 38 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) const46 {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 value100 // 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 39 166 40 FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, -
trunk/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
r30053 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "NotImplemented.h" 31 31 #include "Path.h" 32 32 33 #include <CoreGraphics/CGBitmapContext.h> 33 34 #include <WebKitSystemInterface/WebKitSystemInterface.h> 34 #include <wtf/MathExtras.h> 35 36 #include "GraphicsContextPlatformPrivate.h" 35 #include "GraphicsContextPlatformPrivateCG.h" 37 36 38 37 using namespace std; … … 40 39 namespace WebCore { 41 40 42 class SVGResourceImage;43 44 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 44 CGColorSpaceRef deviceRGB = CGColorSpaceCreateDeviceRGB(); 48 45 BITMAP info; … … 77 74 } 78 75 } 76 77 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; } 79 78 80 79 HDC GraphicsContext::getWindowsContext(const IntRect& dstRect, bool supportAlphaBlend) … … 119 118 // Apply a translation to our context so that the drawing done will be at (0,0) of the bitmap. 120 119 XFORM xform; 121 xform.eM11 = 1.0 ;122 xform.eM12 = 0 ;123 xform.eM21 = 0 ;124 xform.eM22 = 1.0 ;120 xform.eM11 = 1.0f; 121 xform.eM12 = 0.0f; 122 xform.eM21 = 0.0f; 123 xform.eM22 = 1.0f; 125 124 xform.eDx = -dstRect.x(); 126 125 xform.eDy = -dstRect.y(); … … 135 134 } 136 135 137 bool GraphicsContext::inTransparencyLayer() const { return m_data->m_transparencyCount; }138 139 136 void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, bool supportAlphaBlend) 140 137 { … … 143 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 144 // Need to make a CGImage out of the bitmap's pixel buffer and then draw … … 204 201 XFORM xform; 205 202 xform.eM11 = size.width(); 206 xform.eM12 = 0 ;207 xform.eM21 = 0 ;203 xform.eM12 = 0.0f; 204 xform.eM21 = 0.0f; 208 205 xform.eM22 = size.height(); 209 xform.eDx = 0 ;210 xform.eDy = 0 ;206 xform.eDx = 0.0f; 207 xform.eDy = 0.0f; 211 208 ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); 212 209 } … … 224 221 xform.eM21 = sinAngle; 225 222 xform.eM22 = cosAngle; 226 xform.eDx = 0 ;227 xform.eDy = 0 ;223 xform.eDx = 0.0f; 224 xform.eDy = 0.0f; 228 225 ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); 229 226 } … … 234 231 return; 235 232 XFORM xform; 236 xform.eM11 = 1.0 ;237 xform.eM12 = 0 ;238 xform.eM21 = 0 ;239 xform.eM22 = 1.0 ;233 xform.eM11 = 1.0f; 234 xform.eM12 = 0.0f; 235 xform.eM21 = 0.0f; 236 xform.eM22 = 1.0f; 240 237 xform.eDx = x; 241 238 xform.eDy = y; … … 247 244 if (!m_hdc) 248 245 return; 246 249 247 CGAffineTransform mat = transform; 250 248 XFORM xform; … … 255 253 xform.eDx = mat.tx; 256 254 xform.eDy = mat.ty; 255 257 256 ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); 258 257 } … … 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 297 static const Color& spellingPatternColor() { 291 298 static const Color spellingColor(255, 0, 0); … … 298 305 } 299 306 300 // Pulled from GraphicsContextCG301 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 307 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar) 309 308 { 310 309 if (paintingDisabled()) 311 310 return; 312 311 313 312 // These are the same for misspelling or bad grammar 314 313 const int patternHeight = 3; // 3 rows … … 344 343 // Dash lengths for the top and bottom of the error underline are the same. 345 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 346 static const float middle_dash_lengths[] = {2.76f, 1.24f}; 348 347 static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f; … … 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 } -
trunk/WebCore/platform/graphics/win/GraphicsContextWin.cpp
r29479 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "NotImplemented.h" 31 31 #include "Path.h" 32 #include <CoreGraphics/CGBitmapContext.h>33 #include <WebKitSystemInterface/WebKitSystemInterface.h>34 32 #include <wtf/MathExtras.h> 35 36 #include "GraphicsContextPlatformPrivate.h"37 33 38 34 using namespace std; … … 41 37 42 38 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 coords57 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 draw148 // 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/180215 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 GraphicsContextCG301 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 grammar314 const int patternHeight = 3; // 3 rows315 ASSERT(cMisspellingLineThickness == patternHeight);316 const int patternWidth = 4; // 4 pixels317 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 width321 // to make sure everything gets underlined, but that results in drawing out of322 // bounds (e.g. when at the edge of a view) and could make it appear that the323 // space between adjacent misspelled words was underlined.324 // allow slightly more considering that the pattern ends with a transparent pixel325 int widthMod = width % patternWidth;326 if (patternWidth - widthMod > cMisspellingLinePatternGapWidth)327 width -= widthMod;328 329 // Draw the underline330 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 purposes340 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 line357 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 line363 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 line369 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 39 377 40 #if ENABLE(SVG) -
trunk/WebCore/platform/graphics/win/ImageCGWin.cpp
r30053 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include <ApplicationServices/ApplicationServices.h> 31 31 32 #include <winsock2.h>33 32 #include <windows.h> 34 33 #include "PlatformString.h" 35 #include "MIMETypeRegistry.h"36 #include "SharedBuffer.h"37 38 // This function loads resources from WebKit39 PassRefPtr<WebCore::SharedBuffer> loadResourceIntoBuffer(const char*);40 34 41 35 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 36 64 37 bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) … … 77 50 78 51 GraphicsContext gc(cgContext); 52 79 53 IntSize imageSize = BitmapImage::size(); 80 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 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 59 // Do cleanup 86 60 CGContextRelease(cgContext); 87 61 CGColorSpaceRelease(deviceRGB); 62 88 63 return true; 89 64 } … … 94 69 for (int i = 0; i < frames; ++i) { 95 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 72 size_t currentFrame = m_currentFrame; 98 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 75 m_currentFrame = currentFrame; 101 76 return; … … 105 80 // No image of the correct size was found, fallback to drawing the current frame 106 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 -
trunk/WebCore/platform/graphics/win/ImageWin.cpp
r25674 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "Image.h" 28 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 30 #include "SharedBuffer.h" 37 31 … … 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 else83 draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), CompositeCopy);84 85 // Do cleanup86 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 frame106 IntSize imageSize = BitmapImage::size();107 draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), compositeOp);108 }109 110 58 } // namespace WebCore -
trunk/WebCore/platform/graphics/win/SimpleFontDataCGWin.cpp
r30053 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 39 39 #include <unicode/unorm.h> 40 40 #include <ApplicationServices/ApplicationServices.h> 41 #include <WebKitSystemInterface/WebKitSystemInterface.h> 41 42 #include <mlang.h> 42 43 #include <tchar.h> 43 #include <WebKitSystemInterface/WebKitSystemInterface.h>44 44 45 45 namespace WebCore { … … 47 47 using std::max; 48 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 } 49 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / static_cast<float>(unitsPerEm) : x; } 59 50 60 51 void SimpleFontData::platformInit() 61 { 52 { 62 53 m_syntheticBoldOffset = m_font.syntheticBold() ? 1.0f : 0.f; 63 54 m_scriptCache = 0; … … 111 102 ReleaseDC(0, dc); 112 103 113 if (shouldApplyMacAscentHack ) {104 if (shouldApplyMacAscentHack()) { 114 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 … … 161 152 } 162 153 163 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const164 {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) const183 {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 DC189 // merely by testing code page intersection. This seems suspect though. Can't a font only partially190 // 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 font231 // 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 154 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const 241 155 { … … 254 168 CGSize advance; 255 169 CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); 170 256 171 // FIXME: Need to add real support for printer fonts. 257 172 bool isPrinterFont = false; 258 173 wkGetGlyphAdvances(font, m, m_isSystemFont, isPrinterFont, glyph, advance); 174 259 175 return advance.width + m_syntheticBoldOffset; 260 176 } 261 177 262 SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const263 {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 178 } 280 281 } -
trunk/WebCore/platform/graphics/win/SimpleFontDataWin.cpp
r29250 r30056 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 4 * Redistribution and use in source and binary forms, with or without … … 49 49 const float cSmallCapsFontSizeMultiplier = 0.7f; 50 50 51 static bool shouldApplyMacAscentHack; 52 53 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return unitsPerEm ? x / (float)unitsPerEm : x; } 51 static bool g_shouldApplyMacAscentHack; 54 52 55 53 void SimpleFontData::setShouldApplyMacAscentHack(bool b) 56 54 { 57 shouldApplyMacAscentHack = b;55 g_shouldApplyMacAscentHack = b; 58 56 } 59 57 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() 58 bool SimpleFontData::shouldApplyMacAscentHack() 150 59 { 151 if (!isCustomFont()) { 152 DeleteObject(m_font.hfont()); 153 CGFontRelease(m_font.cgFont()); 154 } 155 156 // We don't hash this on Win32, so it's effectively owned by us. 157 delete m_smallCapsFontData; 158 159 ScriptFreeCache(&m_scriptCache); 160 delete m_scriptFontProperties; 60 return g_shouldApplyMacAscentHack; 161 61 } 162 62 … … 238 138 } 239 139 240 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const241 {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 140 SCRIPT_FONTPROPERTIES* SimpleFontData::scriptFontProperties() const 263 141 { -
trunk/WebCore/platform/win/DragImageCGWin.cpp
r30053 r30056 1 1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 37 37 38 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 39 55 40 HBITMAP allocImage(HDC dc, IntSize size, CGContextRef *targetRef) … … 107 92 CGImageRef srcImage; 108 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 95 HBITMAP hbmp = 0; 111 96 HDC dc = GetDC(0); … … 140 125 } 141 126 142 DragImageRef dissolveDragImageToFraction(DragImageRef image, float)127 DragImageRef createDragImageFromImage(Image* img) 143 128 { 144 //We don't do this on windows as the dragimage is blended by the OS145 return image;146 }147 148 DragImageRef createDragImageFromImage(Image* img)149 {150 129 HBITMAP hbmp = 0; 151 130 HDC dc = GetDC(0); … … 185 164 } 186 165 187 DragImageRef createDragImageIconForCachedImage(CachedImage*)188 {189 //FIXME: Provide icon for image type <rdar://problem/5015949>190 return 0;191 166 } 192 193 } -
trunk/WebCore/platform/win/DragImageWin.cpp
r29663 r30056 1 1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "RetainPtr.h" 33 33 34 #include <CoreGraphics/CoreGraphics.h>35 36 34 #include <windows.h> 37 35 … … 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 need101 // 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 53 DragImageRef dissolveDragImageToFraction(DragImageRef image, float) 143 54 { … … 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 59 DragImageRef createDragImageIconForCachedImage(CachedImage*) 188 60 {
Note: See TracChangeset
for help on using the changeset viewer.