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