LCOV - code coverage report
Current view: top level - gfx/2d - HelpersCairo.h (source / functions) Hit Total Coverage
Test: output.info Lines: 7 114 6.1 %
Date: 2017-07-14 16:53:18 Functions: 2 13 15.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MOZILLA_GFX_HELPERSCAIRO_H_
       7             : #define MOZILLA_GFX_HELPERSCAIRO_H_
       8             : 
       9             : #include "2D.h"
      10             : #include "cairo.h"
      11             : #include "Logging.h"
      12             : 
      13             : namespace mozilla {
      14             : namespace gfx {
      15             : 
      16             : static inline cairo_operator_t
      17           0 : GfxOpToCairoOp(CompositionOp op)
      18             : {
      19           0 :   switch (op)
      20             :   {
      21             :     case CompositionOp::OP_OVER:
      22           0 :       return CAIRO_OPERATOR_OVER;
      23             :     case CompositionOp::OP_ADD:
      24           0 :       return CAIRO_OPERATOR_ADD;
      25             :     case CompositionOp::OP_ATOP:
      26           0 :       return CAIRO_OPERATOR_ATOP;
      27             :     case CompositionOp::OP_OUT:
      28           0 :       return CAIRO_OPERATOR_OUT;
      29             :     case CompositionOp::OP_IN:
      30           0 :       return CAIRO_OPERATOR_IN;
      31             :     case CompositionOp::OP_SOURCE:
      32           0 :       return CAIRO_OPERATOR_SOURCE;
      33             :     case CompositionOp::OP_DEST_IN:
      34           0 :       return CAIRO_OPERATOR_DEST_IN;
      35             :     case CompositionOp::OP_DEST_OUT:
      36           0 :       return CAIRO_OPERATOR_DEST_OUT;
      37             :     case CompositionOp::OP_DEST_OVER:
      38           0 :       return CAIRO_OPERATOR_DEST_OVER;
      39             :     case CompositionOp::OP_DEST_ATOP:
      40           0 :       return CAIRO_OPERATOR_DEST_ATOP;
      41             :     case CompositionOp::OP_XOR:
      42           0 :       return CAIRO_OPERATOR_XOR;
      43             :     case CompositionOp::OP_MULTIPLY:
      44           0 :       return CAIRO_OPERATOR_MULTIPLY;
      45             :     case CompositionOp::OP_SCREEN:
      46           0 :       return CAIRO_OPERATOR_SCREEN;
      47             :     case CompositionOp::OP_OVERLAY:
      48           0 :       return CAIRO_OPERATOR_OVERLAY;
      49             :     case CompositionOp::OP_DARKEN:
      50           0 :       return CAIRO_OPERATOR_DARKEN;
      51             :     case CompositionOp::OP_LIGHTEN:
      52           0 :       return CAIRO_OPERATOR_LIGHTEN;
      53             :     case CompositionOp::OP_COLOR_DODGE:
      54           0 :       return CAIRO_OPERATOR_COLOR_DODGE;
      55             :     case CompositionOp::OP_COLOR_BURN:
      56           0 :       return CAIRO_OPERATOR_COLOR_BURN;
      57             :     case CompositionOp::OP_HARD_LIGHT:
      58           0 :       return CAIRO_OPERATOR_HARD_LIGHT;
      59             :     case CompositionOp::OP_SOFT_LIGHT:
      60           0 :       return CAIRO_OPERATOR_SOFT_LIGHT;
      61             :     case CompositionOp::OP_DIFFERENCE:
      62           0 :       return CAIRO_OPERATOR_DIFFERENCE;
      63             :     case CompositionOp::OP_EXCLUSION:
      64           0 :       return CAIRO_OPERATOR_EXCLUSION;
      65             :     case CompositionOp::OP_HUE:
      66           0 :       return CAIRO_OPERATOR_HSL_HUE;
      67             :     case CompositionOp::OP_SATURATION:
      68           0 :       return CAIRO_OPERATOR_HSL_SATURATION;
      69             :     case CompositionOp::OP_COLOR:
      70           0 :       return CAIRO_OPERATOR_HSL_COLOR;
      71             :     case CompositionOp::OP_LUMINOSITY:
      72           0 :       return CAIRO_OPERATOR_HSL_LUMINOSITY;
      73             :     case CompositionOp::OP_COUNT:
      74           0 :       break;
      75             :   }
      76             : 
      77           0 :   return CAIRO_OPERATOR_OVER;
      78             : }
      79             : 
      80             : static inline cairo_antialias_t
      81           0 : GfxAntialiasToCairoAntialias(AntialiasMode antialias)
      82             : {
      83           0 :   switch (antialias)
      84             :   {
      85             :     case AntialiasMode::NONE:
      86           0 :       return CAIRO_ANTIALIAS_NONE;
      87             :     case AntialiasMode::GRAY:
      88           0 :       return CAIRO_ANTIALIAS_GRAY;
      89             :     case AntialiasMode::SUBPIXEL:
      90           0 :       return CAIRO_ANTIALIAS_SUBPIXEL;
      91             :     default:
      92           0 :       return CAIRO_ANTIALIAS_DEFAULT;
      93             :   }
      94             : }
      95             : 
      96             : static inline AntialiasMode
      97             : CairoAntialiasToGfxAntialias(cairo_antialias_t aAntialias)
      98             : {
      99             :   switch(aAntialias) {
     100             :     case CAIRO_ANTIALIAS_NONE:
     101             :       return AntialiasMode::NONE;
     102             :     case CAIRO_ANTIALIAS_GRAY:
     103             :       return AntialiasMode::GRAY;
     104             :     case CAIRO_ANTIALIAS_SUBPIXEL:
     105             :       return AntialiasMode::SUBPIXEL;
     106             :     default:
     107             :       return AntialiasMode::DEFAULT;
     108             :   }
     109             : }
     110             : 
     111             : static inline cairo_filter_t
     112           0 : GfxSamplingFilterToCairoFilter(SamplingFilter filter)
     113             : {
     114           0 :   switch (filter)
     115             :   {
     116             :     case SamplingFilter::GOOD:
     117           0 :       return CAIRO_FILTER_GOOD;
     118             :     case SamplingFilter::LINEAR:
     119           0 :       return CAIRO_FILTER_BILINEAR;
     120             :     case SamplingFilter::POINT:
     121           0 :       return CAIRO_FILTER_NEAREST;
     122             :     default:
     123           0 :       MOZ_CRASH("GFX: bad Cairo filter");
     124             :   }
     125             : 
     126             :   return CAIRO_FILTER_BILINEAR;
     127             : }
     128             : 
     129             : static inline cairo_extend_t
     130           0 : GfxExtendToCairoExtend(ExtendMode extend)
     131             : {
     132           0 :   switch (extend)
     133             :   {
     134             :     case ExtendMode::CLAMP:
     135           0 :       return CAIRO_EXTEND_PAD;
     136             :     // Cairo doesn't support tiling in only 1 direction,
     137             :     // So we have to fallback and tile in both.
     138             :     case ExtendMode::REPEAT_X:
     139             :     case ExtendMode::REPEAT_Y:
     140             :     case ExtendMode::REPEAT:
     141           0 :       return CAIRO_EXTEND_REPEAT;
     142             :     case ExtendMode::REFLECT:
     143           0 :       return CAIRO_EXTEND_REFLECT;
     144             :   }
     145             : 
     146           0 :   return CAIRO_EXTEND_PAD;
     147             : }
     148             : 
     149             : static inline cairo_format_t
     150          21 : GfxFormatToCairoFormat(SurfaceFormat format)
     151             : {
     152          21 :   switch (format)
     153             :   {
     154             :     case SurfaceFormat::A8R8G8B8_UINT32:
     155           3 :       return CAIRO_FORMAT_ARGB32;
     156             :     case SurfaceFormat::X8R8G8B8_UINT32:
     157          18 :       return CAIRO_FORMAT_RGB24;
     158             :     case SurfaceFormat::A8:
     159           0 :       return CAIRO_FORMAT_A8;
     160             :     case SurfaceFormat::R5G6B5_UINT16:
     161           0 :       return CAIRO_FORMAT_RGB16_565;
     162             :     default:
     163           0 :       gfxCriticalError() << "Unknown image format " << (int)format;
     164           0 :       return CAIRO_FORMAT_ARGB32;
     165             :   }
     166             : }
     167             : 
     168             : static inline cairo_format_t
     169             : CairoContentToCairoFormat(cairo_content_t content)
     170             : {
     171             :   switch (content)
     172             :   {
     173             :     case CAIRO_CONTENT_COLOR:
     174             :       return CAIRO_FORMAT_RGB24;
     175             :     case CAIRO_CONTENT_ALPHA:
     176             :       return CAIRO_FORMAT_A8;
     177             :     case CAIRO_CONTENT_COLOR_ALPHA:
     178             :       return CAIRO_FORMAT_ARGB32;
     179             :     default:
     180             :       gfxCriticalError() << "Unknown cairo content type " << (int)content;
     181             :       return CAIRO_FORMAT_A8; // least likely to cause OOB reads
     182             :   }
     183             : }
     184             : 
     185             : static inline cairo_content_t
     186           0 : GfxFormatToCairoContent(SurfaceFormat format)
     187             : {
     188           0 :   switch (format)
     189             :   {
     190             :     case SurfaceFormat::A8R8G8B8_UINT32:
     191           0 :       return CAIRO_CONTENT_COLOR_ALPHA;
     192             :     case SurfaceFormat::X8R8G8B8_UINT32:
     193             :     case SurfaceFormat::R5G6B5_UINT16:  //fall through
     194           0 :       return CAIRO_CONTENT_COLOR;
     195             :     case SurfaceFormat::A8:
     196           0 :       return CAIRO_CONTENT_ALPHA;
     197             :     default:
     198           0 :       gfxCriticalError() << "Unknown image content format " << (int)format;
     199           0 :       return CAIRO_CONTENT_COLOR_ALPHA;
     200             :   }
     201             : }
     202             : 
     203             : static inline cairo_line_join_t
     204           0 : GfxLineJoinToCairoLineJoin(JoinStyle style)
     205             : {
     206           0 :   switch (style)
     207             :   {
     208             :     case JoinStyle::BEVEL:
     209           0 :       return CAIRO_LINE_JOIN_BEVEL;
     210             :     case JoinStyle::ROUND:
     211           0 :       return CAIRO_LINE_JOIN_ROUND;
     212             :     case JoinStyle::MITER:
     213           0 :       return CAIRO_LINE_JOIN_MITER;
     214             :     case JoinStyle::MITER_OR_BEVEL:
     215           0 :       return CAIRO_LINE_JOIN_MITER;
     216             :   }
     217             : 
     218           0 :   return CAIRO_LINE_JOIN_MITER;
     219             : }
     220             : 
     221             : static inline cairo_line_cap_t
     222           0 : GfxLineCapToCairoLineCap(CapStyle style)
     223             : {
     224           0 :   switch (style)
     225             :   {
     226             :     case CapStyle::BUTT:
     227           0 :       return CAIRO_LINE_CAP_BUTT;
     228             :     case CapStyle::ROUND:
     229           0 :       return CAIRO_LINE_CAP_ROUND;
     230             :     case CapStyle::SQUARE:
     231           0 :       return CAIRO_LINE_CAP_SQUARE;
     232             :   }
     233             : 
     234           0 :   return CAIRO_LINE_CAP_BUTT;
     235             : }
     236             : 
     237             : static inline SurfaceFormat
     238           0 : CairoContentToGfxFormat(cairo_content_t content)
     239             : {
     240           0 :   switch (content)
     241             :   {
     242             :     case CAIRO_CONTENT_COLOR_ALPHA:
     243           0 :       return SurfaceFormat::A8R8G8B8_UINT32;
     244             :     case CAIRO_CONTENT_COLOR:
     245             :       // BEWARE! format may be 565
     246           0 :       return SurfaceFormat::X8R8G8B8_UINT32;
     247             :     case CAIRO_CONTENT_ALPHA:
     248           0 :       return SurfaceFormat::A8;
     249             :   }
     250             : 
     251           0 :   return SurfaceFormat::B8G8R8A8;
     252             : }
     253             : 
     254             : static inline SurfaceFormat
     255           0 : CairoFormatToGfxFormat(cairo_format_t format)
     256             : {
     257           0 :   switch (format) {
     258             :     case CAIRO_FORMAT_ARGB32:
     259           0 :       return SurfaceFormat::A8R8G8B8_UINT32;
     260             :     case CAIRO_FORMAT_RGB24:
     261           0 :       return SurfaceFormat::X8R8G8B8_UINT32;
     262             :     case CAIRO_FORMAT_A8:
     263           0 :       return SurfaceFormat::A8;
     264             :     case CAIRO_FORMAT_RGB16_565:
     265           0 :       return SurfaceFormat::R5G6B5_UINT16;
     266             :     default:
     267           0 :       gfxCriticalError() << "Unknown cairo format " << format;
     268           0 :       return SurfaceFormat::UNKNOWN;
     269             :   }
     270             : }
     271             : 
     272             : static inline FontHinting
     273             : CairoHintingToGfxHinting(cairo_hint_style_t aHintStyle)
     274             : {
     275             :   switch (aHintStyle) {
     276             :     case CAIRO_HINT_STYLE_NONE:
     277             :       return FontHinting::NONE;
     278             :     case CAIRO_HINT_STYLE_SLIGHT:
     279             :       return FontHinting::LIGHT;
     280             :     case CAIRO_HINT_STYLE_MEDIUM:
     281             :       return FontHinting::NORMAL;
     282             :     case CAIRO_HINT_STYLE_FULL:
     283             :       return FontHinting::FULL;
     284             :     default:
     285             :       return FontHinting::NORMAL;
     286             :   }
     287             : }
     288             : 
     289             : SurfaceFormat GfxFormatForCairoSurface(cairo_surface_t* surface);
     290             : 
     291             : static inline void
     292          45 : GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
     293             : {
     294          45 :   cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
     295          45 : }
     296             : 
     297             : static inline void
     298           0 : SetCairoStrokeOptions(cairo_t* aCtx, const StrokeOptions& aStrokeOptions)
     299             : {
     300           0 :   cairo_set_line_width(aCtx, aStrokeOptions.mLineWidth);
     301             : 
     302           0 :   cairo_set_miter_limit(aCtx, aStrokeOptions.mMiterLimit);
     303             : 
     304           0 :   if (aStrokeOptions.mDashPattern) {
     305             :     // Convert array of floats to array of doubles
     306           0 :     std::vector<double> dashes(aStrokeOptions.mDashLength);
     307           0 :     bool nonZero = false;
     308           0 :     for (size_t i = 0; i < aStrokeOptions.mDashLength; ++i) {
     309           0 :       if (aStrokeOptions.mDashPattern[i] != 0) {
     310           0 :         nonZero = true;
     311             :       }
     312           0 :       dashes[i] = aStrokeOptions.mDashPattern[i];
     313             :     }
     314             :     // Avoid all-zero patterns that would trigger the CAIRO_STATUS_INVALID_DASH context error state.
     315           0 :     if (nonZero) {
     316           0 :       cairo_set_dash(aCtx, &dashes[0], aStrokeOptions.mDashLength,
     317           0 :                      aStrokeOptions.mDashOffset);
     318             :     }
     319             :   }
     320             : 
     321           0 :   cairo_set_line_join(aCtx, GfxLineJoinToCairoLineJoin(aStrokeOptions.mLineJoin));
     322             : 
     323           0 :   cairo_set_line_cap(aCtx, GfxLineCapToCairoLineCap(aStrokeOptions.mLineCap));
     324           0 : }
     325             : 
     326             : static inline cairo_fill_rule_t
     327           0 : GfxFillRuleToCairoFillRule(FillRule rule)
     328             : {
     329           0 :   switch (rule)
     330             :   {
     331             :     case FillRule::FILL_WINDING:
     332           0 :       return CAIRO_FILL_RULE_WINDING;
     333             :     case FillRule::FILL_EVEN_ODD:
     334           0 :       return CAIRO_FILL_RULE_EVEN_ODD;
     335             :   }
     336             : 
     337           0 :   return CAIRO_FILL_RULE_WINDING;
     338             : }
     339             : 
     340             : // RAII class for temporarily changing the cairo matrix transform. It will use
     341             : // the given matrix transform while it is in scope. When it goes out of scope
     342             : // it will put the cairo context back the way it was.
     343             : 
     344             : class CairoTempMatrix
     345             : {
     346             : public:
     347             :   CairoTempMatrix(cairo_t* aCtx, const Matrix& aMatrix)
     348             :     : mCtx(aCtx)
     349             :   {
     350             :     cairo_get_matrix(aCtx, &mSaveMatrix);
     351             :     cairo_matrix_t matrix;
     352             :     GfxMatrixToCairoMatrix(aMatrix, matrix);
     353             :     cairo_set_matrix(aCtx, &matrix);
     354             :   }
     355             : 
     356             :   ~CairoTempMatrix()
     357             :   {
     358             :     cairo_set_matrix(mCtx, &mSaveMatrix);
     359             :   }
     360             : 
     361             : private:
     362             :   cairo_t* mCtx;
     363             :   cairo_matrix_t mSaveMatrix;
     364             : };
     365             : 
     366             : } // namespace gfx
     367             : } // namespace mozilla
     368             : 
     369             : #endif /* MOZILLA_GFX_HELPERSCAIRO_H_ */

Generated by: LCOV version 1.13