summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/graphics/wx/GraphicsContextWx.cpp')
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp503
1 files changed, 503 insertions, 0 deletions
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
new file mode 100644
index 0000000..435e7ce
--- /dev/null
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "GraphicsContext.h"
+
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "Font.h"
+#include "IntRect.h"
+#include "NotImplemented.h"
+#include "Pen.h"
+#include <wtf/MathExtras.h>
+
+#include <math.h>
+#include <stdio.h>
+
+#include <wx/defs.h>
+#include <wx/window.h>
+#include <wx/dcclient.h>
+#include <wx/dcgraph.h>
+#include <wx/graphics.h>
+
+#if __WXMAC__
+#include <Carbon/Carbon.h>
+#elif __WXMSW__
+#include <windows.h>
+#endif
+
+namespace WebCore {
+
+int getWxCompositingOperation(CompositeOperator op, bool hasAlpha)
+{
+ // FIXME: Add support for more operators.
+ if (op == CompositeSourceOver && !hasAlpha)
+ op = CompositeCopy;
+
+ int function;
+ switch (op) {
+ case CompositeClear:
+ function = wxCLEAR;
+ case CompositeCopy:
+ function = wxCOPY;
+ break;
+ default:
+ function = wxCOPY;
+ }
+ return function;
+}
+
+static int strokeStyleToWxPenStyle(int p)
+{
+ if (p == SolidStroke)
+ return wxSOLID;
+ if (p == DottedStroke)
+ return wxDOT;
+ if (p == DashedStroke)
+ return wxLONG_DASH;
+ if (p == NoStroke)
+ return wxTRANSPARENT;
+
+ return wxSOLID;
+}
+
+class GraphicsContextPlatformPrivate {
+public:
+ GraphicsContextPlatformPrivate();
+ ~GraphicsContextPlatformPrivate();
+
+#if USE(WXGC)
+ wxGCDC* context;
+#else
+ wxWindowDC* context;
+#endif
+ int mswDCStateID;
+ wxRegion gtkCurrentClipRgn;
+ wxRegion gtkPaintClipRgn;
+};
+
+GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate() :
+ context(0),
+ mswDCStateID(0),
+ gtkCurrentClipRgn(wxRegion()),
+ gtkPaintClipRgn(wxRegion())
+{
+}
+
+GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
+{
+}
+
+
+GraphicsContext::GraphicsContext(PlatformGraphicsContext* context)
+ : m_common(createGraphicsContextPrivate())
+ , m_data(new GraphicsContextPlatformPrivate)
+{
+ setPaintingDisabled(!context);
+ if (context) {
+ // Make sure the context starts in sync with our state.
+ setPlatformFillColor(fillColor());
+ setPlatformStrokeColor(strokeColor());
+ }
+#if USE(WXGC)
+ m_data->context = (wxGCDC*)context;
+#else
+ m_data->context = (wxWindowDC*)context;
+#endif
+}
+
+GraphicsContext::~GraphicsContext()
+{
+ destroyGraphicsContextPrivate(m_common);
+ delete m_data;
+}
+
+PlatformGraphicsContext* GraphicsContext::platformContext() const
+{
+ return (PlatformGraphicsContext*)m_data->context;
+}
+
+void GraphicsContext::savePlatformState()
+{
+ if (m_data->context)
+ {
+#if USE(WXGC)
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ gc->PushState();
+#else
+ // when everything is working with USE_WXGC, we can remove this
+ #if __WXMAC__
+ CGContextRef context;
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ if (gc)
+ context = (CGContextRef)gc->GetNativeContext();
+ if (context)
+ CGContextSaveGState(context);
+ #elif __WXMSW__
+ HDC dc = (HDC)m_data->context->GetHDC();
+ m_data->mswDCStateID = ::SaveDC(dc);
+ #elif __WXGTK__
+ m_data->gtkCurrentClipRgn = m_data->context->m_currentClippingRegion;
+ m_data->gtkPaintClipRgn = m_data->context->m_paintClippingRegion;
+ #endif
+#endif // __WXMAC__
+ }
+}
+
+void GraphicsContext::restorePlatformState()
+{
+ if (m_data->context)
+ {
+#if USE(WXGC)
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ gc->PopState();
+#else
+ #if __WXMAC__
+ CGContextRef context;
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ if (gc)
+ context = (CGContextRef)gc->GetNativeContext();
+ if (context)
+ CGContextRestoreGState(context);
+ #elif __WXMSW__
+ HDC dc = (HDC)m_data->context->GetHDC();
+ ::RestoreDC(dc, m_data->mswDCStateID);
+ #elif __WXGTK__
+ m_data->context->m_currentClippingRegion = m_data->gtkCurrentClipRgn;
+ m_data->context->m_paintClippingRegion = m_data->gtkPaintClipRgn;
+ #endif
+
+#endif // USE_WXGC
+ }
+}
+
+// Draws a filled rectangle with a stroked border.
+void GraphicsContext::drawRect(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+ m_data->context->DrawRectangle(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+// This is only used to draw borders.
+void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
+{
+ if (paintingDisabled())
+ return;
+
+ FloatPoint p1 = point1;
+ FloatPoint p2 = point2;
+
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+ m_data->context->DrawLine(point1.x(), point1.y(), point2.x(), point2.y());
+}
+
+// This method is only used to draw the little circles used in lists.
+void GraphicsContext::drawEllipse(const IntRect& rect)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+ m_data->context->DrawEllipse(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+ m_data->context->DrawEllipticArc(rect.x(), rect.y(), rect.width(), rect.height(), startAngle, angleSpan);
+}
+
+void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points, bool shouldAntialias)
+{
+ if (paintingDisabled())
+ return;
+
+ if (npoints <= 1)
+ return;
+
+ wxPoint* polygon = new wxPoint[npoints];
+ for (size_t i = 0; i < npoints; i++)
+ polygon[i] = wxPoint(points[i].x(), points[i].y());
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+ m_data->context->DrawPolygon((int)npoints, polygon);
+ delete [] polygon;
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ m_data->context->SetPen(*wxTRANSPARENT_PEN);
+ m_data->context->SetBrush(wxBrush(color));
+ m_data->context->DrawRectangle(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::drawFocusRing(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+}
+
+void GraphicsContext::clip(const FloatRect& r)
+{
+ wxWindowDC* windc = dynamic_cast<wxWindowDC*>(m_data->context);
+ wxPoint pos(0, 0);
+
+ if (windc) {
+#ifndef __WXGTK__
+ wxWindow* window = windc->GetWindow();
+#else
+ wxWindow* window = windc->m_owner;
+#endif
+ if (window) {
+ wxWindow* parent = window->GetParent();
+ // we need to convert from WebView "global" to WebFrame "local" coords.
+ // FIXME: We only want to go to the top WebView.
+ while (parent) {
+ pos += window->GetPosition();
+ parent = parent->GetParent();
+ }
+ }
+ }
+
+ m_data->context->SetClippingRegion(r.x() - pos.x, r.y() - pos.y, r.width() + pos.x, r.height() + pos.y);
+}
+
+void GraphicsContext::clipOut(const Path&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::clipOut(const IntRect&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::clipOutEllipseInRect(const IntRect&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
+{
+ if (paintingDisabled())
+ return;
+
+ IntPoint endPoint = origin + IntSize(width, 0);
+ m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), wxSOLID));
+ m_data->context->DrawLine(origin.x(), origin.y(), endPoint.x(), endPoint.y());
+}
+
+
+void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+{
+ if (grammar)
+ m_data->context->SetPen(wxPen(*wxGREEN, 2, wxLONG_DASH));
+ else
+ m_data->context->SetPen(wxPen(*wxRED, 2, wxLONG_DASH));
+
+ m_data->context->DrawLine(origin.x(), origin.y(), origin.x() + width, origin.y());
+}
+
+void GraphicsContext::clip(const Path&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
+{
+ notImplemented();
+}
+
+AffineTransform GraphicsContext::getCTM() const
+{
+ notImplemented();
+ return AffineTransform();
+}
+
+void GraphicsContext::translate(float tx, float ty)
+{
+#if USE(WXGC)
+ if (m_data->context) {
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ gc->Translate(tx, ty);
+ }
+#endif
+}
+
+void GraphicsContext::rotate(float angle)
+{
+#if USE(WXGC)
+ if (m_data->context) {
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ gc->Rotate(angle);
+ }
+#endif
+}
+
+void GraphicsContext::scale(const FloatSize& scale)
+{
+#if USE(WXGC)
+ if (m_data->context) {
+ wxGraphicsContext* gc = m_data->context->GetGraphicsContext();
+ gc->Scale(scale.width(), scale.height());
+ }
+#endif
+}
+
+
+FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
+{
+ FloatRect result;
+
+ wxCoord x = (wxCoord)frect.x();
+ wxCoord y = (wxCoord)frect.y();
+
+ x = m_data->context->LogicalToDeviceX(x);
+ y = m_data->context->LogicalToDeviceY(y);
+ result.setX((float)x);
+ result.setY((float)y);
+ x = (wxCoord)frect.width();
+ y = (wxCoord)frect.height();
+ x = m_data->context->LogicalToDeviceXRel(x);
+ y = m_data->context->LogicalToDeviceYRel(y);
+ result.setWidth((float)x);
+ result.setHeight((float)y);
+ return result;
+}
+
+void GraphicsContext::setURLForRect(const KURL&, const IntRect&)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setCompositeOperation(CompositeOperator op)
+{
+ if (m_data->context)
+ m_data->context->SetLogicalFunction(getWxCompositingOperation(op, false));
+}
+
+void GraphicsContext::beginPath()
+{
+ notImplemented();
+}
+
+void GraphicsContext::addPath(const Path& path)
+{
+ notImplemented();
+}
+
+void GraphicsContext::setPlatformStrokeColor(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ if (m_data->context)
+ m_data->context->SetPen(wxPen(color, strokeThickness(), strokeStyleToWxPenStyle(strokeStyle())));
+}
+
+void GraphicsContext::setPlatformStrokeThickness(float thickness)
+{
+ if (paintingDisabled())
+ return;
+
+ if (m_data->context)
+ m_data->context->SetPen(wxPen(strokeColor(), thickness, strokeStyleToWxPenStyle(strokeStyle())));
+
+}
+
+void GraphicsContext::setPlatformFillColor(const Color& color)
+{
+ if (paintingDisabled())
+ return;
+
+ if (m_data->context)
+ m_data->context->SetBrush(wxBrush(color));
+}
+
+void GraphicsContext::concatCTM(const AffineTransform& transform)
+{
+ if (paintingDisabled())
+ return;
+
+ notImplemented();
+ return;
+}
+
+void GraphicsContext::setUseAntialiasing(bool enable)
+{
+ if (paintingDisabled())
+ return;
+ notImplemented();
+}
+
+void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
+{
+}
+
+InterpolationQuality GraphicsContext::imageInterpolationQuality() const
+{
+ return InterpolationDefault;
+}
+
+void GraphicsContext::fillPath()
+{
+}
+
+void GraphicsContext::strokePath()
+{
+}
+
+void GraphicsContext::drawPath()
+{
+ fillPath();
+ strokePath();
+}
+
+void GraphicsContext::fillRect(const FloatRect& rect)
+{
+ if (paintingDisabled())
+ return;
+}
+
+}