Home | History | Annotate | Download | only in haiku
      1 /*
      2  * Copyright (C) 2007 Ryan Leavengood <leavengood (at) gmail.com>
      3  *
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "config.h"
     29 #include "GraphicsContext.h"
     30 
     31 #include "AffineTransform.h"
     32 #include "CString.h"
     33 #include "Color.h"
     34 #include "Font.h"
     35 #include "FontData.h"
     36 #include "NotImplemented.h"
     37 #include "Path.h"
     38 #include "Pen.h"
     39 #include <GraphicsDefs.h>
     40 #include <Region.h>
     41 #include <View.h>
     42 #include <Window.h>
     43 #include <stdio.h>
     44 
     45 
     46 namespace WebCore {
     47 
     48 class GraphicsContextPlatformPrivate {
     49 public:
     50     GraphicsContextPlatformPrivate(BView* view);
     51     ~GraphicsContextPlatformPrivate();
     52 
     53     BView* m_view;
     54 };
     55 
     56 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate(BView* view)
     57     : m_view(view)
     58 {
     59 }
     60 
     61 GraphicsContextPlatformPrivate::~GraphicsContextPlatformPrivate()
     62 {
     63 }
     64 
     65 GraphicsContext::GraphicsContext(PlatformGraphicsContext* context)
     66     : m_common(createGraphicsContextPrivate())
     67     , m_data(new GraphicsContextPlatformPrivate(context))
     68 {
     69     setPaintingDisabled(!context);
     70 }
     71 
     72 GraphicsContext::~GraphicsContext()
     73 {
     74     destroyGraphicsContextPrivate(m_common);
     75     delete m_data;
     76 }
     77 
     78 PlatformGraphicsContext* GraphicsContext::platformContext() const
     79 {
     80     return m_data->m_view;
     81 }
     82 
     83 void GraphicsContext::savePlatformState()
     84 {
     85     m_data->m_view->PushState();
     86 }
     87 
     88 void GraphicsContext::restorePlatformState()
     89 {
     90     m_data->m_view->PopState();
     91 }
     92 
     93 // Draws a filled rectangle with a stroked border.
     94 void GraphicsContext::drawRect(const IntRect& rect)
     95 {
     96     if (paintingDisabled())
     97         return;
     98 
     99     m_data->m_view->FillRect(rect);
    100     if (strokeStyle() != NoStroke)
    101         m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
    102 }
    103 
    104 // This is only used to draw borders.
    105 void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
    106 {
    107     if (paintingDisabled())
    108         return;
    109 
    110     if (strokeStyle() == NoStroke)
    111         return;
    112 
    113     m_data->m_view->StrokeLine(point1, point2, getHaikuStrokeStyle());
    114 }
    115 
    116 // This method is only used to draw the little circles used in lists.
    117 void GraphicsContext::drawEllipse(const IntRect& rect)
    118 {
    119     if (paintingDisabled())
    120         return;
    121 
    122     m_data->m_view->FillEllipse(rect);
    123     if (strokeStyle() != NoStroke)
    124         m_data->m_view->StrokeEllipse(rect, getHaikuStrokeStyle());
    125 }
    126 
    127 void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSpan)
    128 {
    129     if (paintingDisabled())
    130         return;
    131 
    132     m_data->m_view->StrokeArc(rect, startAngle, angleSpan, getHaikuStrokeStyle());
    133 }
    134 
    135 void GraphicsContext::strokePath()
    136 {
    137     notImplemented();
    138 }
    139 
    140 void GraphicsContext::drawConvexPolygon(size_t pointsLength, const FloatPoint* points, bool shouldAntialias)
    141 {
    142     if (paintingDisabled())
    143         return;
    144 
    145     BPoint bPoints[pointsLength];
    146     for (size_t i = 0; i < pointsLength; i++)
    147         bPoints[i] = points[i];
    148 
    149     m_data->m_view->FillPolygon(bPoints, pointsLength);
    150     if (strokeStyle() != NoStroke)
    151         // Stroke with low color
    152         m_data->m_view->StrokePolygon(bPoints, pointsLength, true, getHaikuStrokeStyle());
    153 }
    154 
    155 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace)
    156 {
    157     if (paintingDisabled())
    158         return;
    159 
    160     rgb_color oldColor = m_data->m_view->HighColor();
    161     m_data->m_view->SetHighColor(color);
    162     m_data->m_view->FillRect(rect);
    163     m_data->m_view->SetHighColor(oldColor);
    164 }
    165 
    166 void GraphicsContext::fillRect(const FloatRect& rect)
    167 {
    168     if (paintingDisabled())
    169         return;
    170 }
    171 
    172 void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
    173 {
    174     if (paintingDisabled() || !color.alpha())
    175         return;
    176 
    177     notImplemented();
    178     // FIXME: A simple implementation could just use FillRoundRect if all
    179     // the sizes are the same, or even if they are not. Otherwise several
    180     // FillRect and FillArc calls are needed.
    181 }
    182 
    183 void GraphicsContext::fillPath()
    184 {
    185     notImplemented();
    186 }
    187 
    188 void GraphicsContext::beginPath()
    189 {
    190     notImplemented();
    191 }
    192 
    193 void GraphicsContext::addPath(const Path& path)
    194 {
    195     notImplemented();
    196 }
    197 
    198 void GraphicsContext::clip(const FloatRect& rect)
    199 {
    200     if (paintingDisabled())
    201         return;
    202 
    203     BRegion region(rect);
    204     m_data->m_view->ConstrainClippingRegion(&region);
    205 }
    206 
    207 void GraphicsContext::drawFocusRing(const Vector<Path>& paths, int width, int offset, const Color& color)
    208 {
    209     // FIXME: implement
    210 }
    211 
    212 void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int /* width */, int /* offset */, const Color& color)
    213 {
    214     if (paintingDisabled())
    215         return;
    216 
    217     unsigned rectCount = rects.size();
    218 
    219     // FIXME: maybe we should implement this with BShape?
    220 
    221     if (rects.size() > 1) {
    222         BRegion    region;
    223         for (int i = 0; i < rectCount; ++i)
    224             region.Include(BRect(rects[i]));
    225 
    226         m_data->m_view->SetHighColor(color);
    227         m_data->m_view->StrokeRect(region.Frame(), B_MIXED_COLORS);
    228     }
    229 }
    230 
    231 void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing)
    232 {
    233     if (paintingDisabled())
    234         return;
    235 
    236     IntPoint endPoint = origin + IntSize(width, 0);
    237     drawLine(origin, endPoint);
    238 }
    239 
    240 void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar)
    241 {
    242     if (paintingDisabled())
    243         return;
    244 
    245     notImplemented();
    246 }
    247 
    248 FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
    249 {
    250     notImplemented();
    251     return rect;
    252 }
    253 
    254 void GraphicsContext::beginTransparencyLayer(float opacity)
    255 {
    256     if (paintingDisabled())
    257         return;
    258 
    259     notImplemented();
    260 }
    261 
    262 void GraphicsContext::endTransparencyLayer()
    263 {
    264     if (paintingDisabled())
    265         return;
    266 
    267     notImplemented();
    268 }
    269 
    270 void GraphicsContext::clearRect(const FloatRect& rect)
    271 {
    272     if (paintingDisabled())
    273         return;
    274 
    275     notImplemented();
    276 }
    277 
    278 void GraphicsContext::strokeRect(const FloatRect& rect, float width)
    279 {
    280     if (paintingDisabled())
    281         return;
    282 
    283     float oldSize = m_data->m_view->PenSize();
    284     m_data->m_view->SetPenSize(width);
    285     m_data->m_view->StrokeRect(rect, getHaikuStrokeStyle());
    286     m_data->m_view->SetPenSize(oldSize);
    287 }
    288 
    289 void GraphicsContext::setLineCap(LineCap lineCap)
    290 {
    291     if (paintingDisabled())
    292         return;
    293 
    294     cap_mode mode = B_BUTT_CAP;
    295     switch (lineCap) {
    296     case RoundCap:
    297         mode = B_ROUND_CAP;
    298         break;
    299     case SquareCap:
    300         mode = B_SQUARE_CAP;
    301         break;
    302     case ButtCap:
    303     default:
    304         break;
    305     }
    306 
    307     m_data->m_view->SetLineMode(mode, m_data->m_view->LineJoinMode(), m_data->m_view->LineMiterLimit());
    308 }
    309 
    310 void GraphicsContext::setLineJoin(LineJoin lineJoin)
    311 {
    312     if (paintingDisabled())
    313         return;
    314 
    315     join_mode mode = B_MITER_JOIN;
    316     switch (lineJoin) {
    317     case RoundJoin:
    318         mode = B_ROUND_JOIN;
    319         break;
    320     case BevelJoin:
    321         mode = B_BEVEL_JOIN;
    322         break;
    323     case MiterJoin:
    324     default:
    325         break;
    326     }
    327 
    328     m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), mode, m_data->m_view->LineMiterLimit());
    329 }
    330 
    331 void GraphicsContext::setMiterLimit(float limit)
    332 {
    333     if (paintingDisabled())
    334         return;
    335 
    336     m_data->m_view->SetLineMode(m_data->m_view->LineCapMode(), m_data->m_view->LineJoinMode(), limit);
    337 }
    338 
    339 void GraphicsContext::setAlpha(float opacity)
    340 {
    341     if (paintingDisabled())
    342         return;
    343 
    344     notImplemented();
    345 }
    346 
    347 void GraphicsContext::setCompositeOperation(CompositeOperator op)
    348 {
    349     if (paintingDisabled())
    350         return;
    351 
    352     drawing_mode mode = B_OP_COPY;
    353     switch (op) {
    354     case CompositeClear:
    355     case CompositeCopy:
    356         // Use the default above
    357         break;
    358     case CompositeSourceOver:
    359         mode = B_OP_OVER;
    360         break;
    361     default:
    362         printf("GraphicsContext::setCompositeOperation: Unsupported composite operation %s\n",
    363                 compositeOperatorName(op).utf8().data());
    364     }
    365     m_data->m_view->SetDrawingMode(mode);
    366 }
    367 
    368 void GraphicsContext::clip(const Path& path)
    369 {
    370     if (paintingDisabled())
    371         return;
    372 
    373     m_data->m_view->ConstrainClippingRegion(path.platformPath());
    374 }
    375 
    376 void GraphicsContext::canvasClip(const Path& path)
    377 {
    378     clip(path);
    379 }
    380 
    381 void GraphicsContext::clipOut(const Path& path)
    382 {
    383     if (paintingDisabled())
    384         return;
    385 
    386     notImplemented();
    387 }
    388 
    389 void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
    390 {
    391     notImplemented();
    392 }
    393 
    394 AffineTransform GraphicsContext::getCTM() const
    395 {
    396     notImplemented();
    397     return AffineTransform();
    398 }
    399 
    400 void GraphicsContext::translate(float x, float y)
    401 {
    402     if (paintingDisabled())
    403         return;
    404 
    405     notImplemented();
    406 }
    407 
    408 IntPoint GraphicsContext::origin()
    409 {
    410     notImplemented();
    411     return IntPoint(0, 0);
    412 }
    413 
    414 void GraphicsContext::rotate(float radians)
    415 {
    416     if (paintingDisabled())
    417         return;
    418 
    419     notImplemented();
    420 }
    421 
    422 void GraphicsContext::scale(const FloatSize& size)
    423 {
    424     if (paintingDisabled())
    425         return;
    426 
    427     notImplemented();
    428 }
    429 
    430 void GraphicsContext::clipOut(const IntRect& rect)
    431 {
    432     if (paintingDisabled())
    433         return;
    434 
    435     notImplemented();
    436 }
    437 
    438 void GraphicsContext::clipOutEllipseInRect(const IntRect& rect)
    439 {
    440     if (paintingDisabled())
    441         return;
    442 
    443     notImplemented();
    444 }
    445 
    446 void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness)
    447 {
    448     if (paintingDisabled())
    449         return;
    450 
    451     notImplemented();
    452 }
    453 
    454 void GraphicsContext::concatCTM(const AffineTransform& transform)
    455 {
    456     if (paintingDisabled())
    457         return;
    458 
    459     notImplemented();
    460 }
    461 
    462 void GraphicsContext::setPlatformShouldAntialias(bool enable)
    463 {
    464     if (paintingDisabled())
    465         return;
    466 
    467     notImplemented();
    468 }
    469 
    470 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
    471 {
    472 }
    473 
    474 void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect)
    475 {
    476     notImplemented();
    477 }
    478 
    479 void GraphicsContext::setPlatformFont(const Font& font)
    480 {
    481     m_data->m_view->SetFont(font.primaryFont()->platformData().font());
    482 }
    483 
    484 void GraphicsContext::setPlatformStrokeColor(const Color& color, ColorSpace colorSpace)
    485 {
    486     if (paintingDisabled())
    487         return;
    488 
    489     m_data->m_view->SetHighColor(color);
    490 }
    491 
    492 pattern GraphicsContext::getHaikuStrokeStyle()
    493 {
    494     switch (strokeStyle()) {
    495     case SolidStroke:
    496         return B_SOLID_HIGH;
    497         break;
    498     case DottedStroke:
    499         return B_MIXED_COLORS;
    500         break;
    501     case DashedStroke:
    502         // FIXME: use a better dashed stroke!
    503         notImplemented();
    504         return B_MIXED_COLORS;
    505         break;
    506     default:
    507         return B_SOLID_LOW;
    508         break;
    509     }
    510 }
    511 
    512 void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& strokeStyle)
    513 {
    514     // FIXME: see getHaikuStrokeStyle.
    515     notImplemented();
    516 }
    517 
    518 void GraphicsContext::setPlatformStrokeThickness(float thickness)
    519 {
    520     if (paintingDisabled())
    521         return;
    522 
    523     m_data->m_view->SetPenSize(thickness);
    524 }
    525 
    526 void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorSpace)
    527 {
    528     if (paintingDisabled())
    529         return;
    530 
    531     m_data->m_view->SetHighColor(color);
    532 }
    533 
    534 void GraphicsContext::clearPlatformShadow()
    535 {
    536     notImplemented();
    537 }
    538 
    539 void GraphicsContext::setPlatformShadow(IntSize const&, int, Color const&, ColorSpace)
    540 {
    541     notImplemented();
    542 }
    543 
    544 } // namespace WebCore
    545 
    546