summaryrefslogtreecommitdiffstats
path: root/gfx/2d/HelpersCairo.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/2d/HelpersCairo.h
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/2d/HelpersCairo.h')
-rw-r--r--gfx/2d/HelpersCairo.h352
1 files changed, 352 insertions, 0 deletions
diff --git a/gfx/2d/HelpersCairo.h b/gfx/2d/HelpersCairo.h
new file mode 100644
index 000000000..bbcce274e
--- /dev/null
+++ b/gfx/2d/HelpersCairo.h
@@ -0,0 +1,352 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_HELPERSCAIRO_H_
+#define MOZILLA_GFX_HELPERSCAIRO_H_
+
+#include "2D.h"
+#include "cairo.h"
+#include "Logging.h"
+
+namespace mozilla {
+namespace gfx {
+
+static inline cairo_operator_t
+GfxOpToCairoOp(CompositionOp op)
+{
+ switch (op)
+ {
+ case CompositionOp::OP_OVER:
+ return CAIRO_OPERATOR_OVER;
+ case CompositionOp::OP_ADD:
+ return CAIRO_OPERATOR_ADD;
+ case CompositionOp::OP_ATOP:
+ return CAIRO_OPERATOR_ATOP;
+ case CompositionOp::OP_OUT:
+ return CAIRO_OPERATOR_OUT;
+ case CompositionOp::OP_IN:
+ return CAIRO_OPERATOR_IN;
+ case CompositionOp::OP_SOURCE:
+ return CAIRO_OPERATOR_SOURCE;
+ case CompositionOp::OP_DEST_IN:
+ return CAIRO_OPERATOR_DEST_IN;
+ case CompositionOp::OP_DEST_OUT:
+ return CAIRO_OPERATOR_DEST_OUT;
+ case CompositionOp::OP_DEST_OVER:
+ return CAIRO_OPERATOR_DEST_OVER;
+ case CompositionOp::OP_DEST_ATOP:
+ return CAIRO_OPERATOR_DEST_ATOP;
+ case CompositionOp::OP_XOR:
+ return CAIRO_OPERATOR_XOR;
+ case CompositionOp::OP_MULTIPLY:
+ return CAIRO_OPERATOR_MULTIPLY;
+ case CompositionOp::OP_SCREEN:
+ return CAIRO_OPERATOR_SCREEN;
+ case CompositionOp::OP_OVERLAY:
+ return CAIRO_OPERATOR_OVERLAY;
+ case CompositionOp::OP_DARKEN:
+ return CAIRO_OPERATOR_DARKEN;
+ case CompositionOp::OP_LIGHTEN:
+ return CAIRO_OPERATOR_LIGHTEN;
+ case CompositionOp::OP_COLOR_DODGE:
+ return CAIRO_OPERATOR_COLOR_DODGE;
+ case CompositionOp::OP_COLOR_BURN:
+ return CAIRO_OPERATOR_COLOR_BURN;
+ case CompositionOp::OP_HARD_LIGHT:
+ return CAIRO_OPERATOR_HARD_LIGHT;
+ case CompositionOp::OP_SOFT_LIGHT:
+ return CAIRO_OPERATOR_SOFT_LIGHT;
+ case CompositionOp::OP_DIFFERENCE:
+ return CAIRO_OPERATOR_DIFFERENCE;
+ case CompositionOp::OP_EXCLUSION:
+ return CAIRO_OPERATOR_EXCLUSION;
+ case CompositionOp::OP_HUE:
+ return CAIRO_OPERATOR_HSL_HUE;
+ case CompositionOp::OP_SATURATION:
+ return CAIRO_OPERATOR_HSL_SATURATION;
+ case CompositionOp::OP_COLOR:
+ return CAIRO_OPERATOR_HSL_COLOR;
+ case CompositionOp::OP_LUMINOSITY:
+ return CAIRO_OPERATOR_HSL_LUMINOSITY;
+ case CompositionOp::OP_COUNT:
+ break;
+ }
+
+ return CAIRO_OPERATOR_OVER;
+}
+
+static inline cairo_antialias_t
+GfxAntialiasToCairoAntialias(AntialiasMode antialias)
+{
+ switch (antialias)
+ {
+ case AntialiasMode::NONE:
+ return CAIRO_ANTIALIAS_NONE;
+ case AntialiasMode::GRAY:
+ return CAIRO_ANTIALIAS_GRAY;
+ case AntialiasMode::SUBPIXEL:
+ return CAIRO_ANTIALIAS_SUBPIXEL;
+ default:
+ return CAIRO_ANTIALIAS_DEFAULT;
+ }
+}
+
+static inline AntialiasMode
+CairoAntialiasToGfxAntialias(cairo_antialias_t aAntialias)
+{
+ switch(aAntialias) {
+ case CAIRO_ANTIALIAS_NONE:
+ return AntialiasMode::NONE;
+ case CAIRO_ANTIALIAS_GRAY:
+ return AntialiasMode::GRAY;
+ case CAIRO_ANTIALIAS_SUBPIXEL:
+ return AntialiasMode::SUBPIXEL;
+ default:
+ return AntialiasMode::DEFAULT;
+ }
+}
+
+static inline cairo_filter_t
+GfxSamplingFilterToCairoFilter(SamplingFilter filter)
+{
+ switch (filter)
+ {
+ case SamplingFilter::GOOD:
+ return CAIRO_FILTER_GOOD;
+ case SamplingFilter::LINEAR:
+ return CAIRO_FILTER_BILINEAR;
+ case SamplingFilter::POINT:
+ return CAIRO_FILTER_NEAREST;
+ default:
+ MOZ_CRASH("GFX: bad Cairo filter");
+ }
+
+ return CAIRO_FILTER_BILINEAR;
+}
+
+static inline cairo_extend_t
+GfxExtendToCairoExtend(ExtendMode extend)
+{
+ switch (extend)
+ {
+ case ExtendMode::CLAMP:
+ return CAIRO_EXTEND_PAD;
+ // Cairo doesn't support tiling in only 1 direction,
+ // So we have to fallback and tile in both.
+ case ExtendMode::REPEAT_X:
+ case ExtendMode::REPEAT_Y:
+ case ExtendMode::REPEAT:
+ return CAIRO_EXTEND_REPEAT;
+ case ExtendMode::REFLECT:
+ return CAIRO_EXTEND_REFLECT;
+ }
+
+ return CAIRO_EXTEND_PAD;
+}
+
+static inline cairo_format_t
+GfxFormatToCairoFormat(SurfaceFormat format)
+{
+ switch (format)
+ {
+ case SurfaceFormat::A8R8G8B8_UINT32:
+ return CAIRO_FORMAT_ARGB32;
+ case SurfaceFormat::X8R8G8B8_UINT32:
+ return CAIRO_FORMAT_RGB24;
+ case SurfaceFormat::A8:
+ return CAIRO_FORMAT_A8;
+ case SurfaceFormat::R5G6B5_UINT16:
+ return CAIRO_FORMAT_RGB16_565;
+ default:
+ gfxCriticalError() << "Unknown image format " << (int)format;
+ return CAIRO_FORMAT_ARGB32;
+ }
+}
+
+static inline cairo_content_t
+GfxFormatToCairoContent(SurfaceFormat format)
+{
+ switch (format)
+ {
+ case SurfaceFormat::A8R8G8B8_UINT32:
+ return CAIRO_CONTENT_COLOR_ALPHA;
+ case SurfaceFormat::X8R8G8B8_UINT32:
+ case SurfaceFormat::R5G6B5_UINT16: //fall through
+ return CAIRO_CONTENT_COLOR;
+ case SurfaceFormat::A8:
+ return CAIRO_CONTENT_ALPHA;
+ default:
+ gfxCriticalError() << "Unknown image content format " << (int)format;
+ return CAIRO_CONTENT_COLOR_ALPHA;
+ }
+}
+
+static inline cairo_line_join_t
+GfxLineJoinToCairoLineJoin(JoinStyle style)
+{
+ switch (style)
+ {
+ case JoinStyle::BEVEL:
+ return CAIRO_LINE_JOIN_BEVEL;
+ case JoinStyle::ROUND:
+ return CAIRO_LINE_JOIN_ROUND;
+ case JoinStyle::MITER:
+ return CAIRO_LINE_JOIN_MITER;
+ case JoinStyle::MITER_OR_BEVEL:
+ return CAIRO_LINE_JOIN_MITER;
+ }
+
+ return CAIRO_LINE_JOIN_MITER;
+}
+
+static inline cairo_line_cap_t
+GfxLineCapToCairoLineCap(CapStyle style)
+{
+ switch (style)
+ {
+ case CapStyle::BUTT:
+ return CAIRO_LINE_CAP_BUTT;
+ case CapStyle::ROUND:
+ return CAIRO_LINE_CAP_ROUND;
+ case CapStyle::SQUARE:
+ return CAIRO_LINE_CAP_SQUARE;
+ }
+
+ return CAIRO_LINE_CAP_BUTT;
+}
+
+static inline SurfaceFormat
+CairoContentToGfxFormat(cairo_content_t content)
+{
+ switch (content)
+ {
+ case CAIRO_CONTENT_COLOR_ALPHA:
+ return SurfaceFormat::A8R8G8B8_UINT32;
+ case CAIRO_CONTENT_COLOR:
+ // BEWARE! format may be 565
+ return SurfaceFormat::X8R8G8B8_UINT32;
+ case CAIRO_CONTENT_ALPHA:
+ return SurfaceFormat::A8;
+ }
+
+ return SurfaceFormat::B8G8R8A8;
+}
+
+static inline SurfaceFormat
+CairoFormatToGfxFormat(cairo_format_t format)
+{
+ switch (format) {
+ case CAIRO_FORMAT_ARGB32:
+ return SurfaceFormat::A8R8G8B8_UINT32;
+ case CAIRO_FORMAT_RGB24:
+ return SurfaceFormat::X8R8G8B8_UINT32;
+ case CAIRO_FORMAT_A8:
+ return SurfaceFormat::A8;
+ case CAIRO_FORMAT_RGB16_565:
+ return SurfaceFormat::R5G6B5_UINT16;
+ default:
+ gfxCriticalError() << "Unknown cairo format " << format;
+ return SurfaceFormat::UNKNOWN;
+ }
+}
+
+static inline FontHinting
+CairoHintingToGfxHinting(cairo_hint_style_t aHintStyle)
+{
+ switch (aHintStyle) {
+ case CAIRO_HINT_STYLE_NONE:
+ return FontHinting::NONE;
+ case CAIRO_HINT_STYLE_SLIGHT:
+ return FontHinting::LIGHT;
+ case CAIRO_HINT_STYLE_MEDIUM:
+ return FontHinting::NORMAL;
+ case CAIRO_HINT_STYLE_FULL:
+ return FontHinting::FULL;
+ default:
+ return FontHinting::NORMAL;
+ }
+}
+
+SurfaceFormat GfxFormatForCairoSurface(cairo_surface_t* surface);
+
+static inline void
+GfxMatrixToCairoMatrix(const Matrix& mat, cairo_matrix_t& retval)
+{
+ cairo_matrix_init(&retval, mat._11, mat._12, mat._21, mat._22, mat._31, mat._32);
+}
+
+static inline void
+SetCairoStrokeOptions(cairo_t* aCtx, const StrokeOptions& aStrokeOptions)
+{
+ cairo_set_line_width(aCtx, aStrokeOptions.mLineWidth);
+
+ cairo_set_miter_limit(aCtx, aStrokeOptions.mMiterLimit);
+
+ if (aStrokeOptions.mDashPattern) {
+ // Convert array of floats to array of doubles
+ std::vector<double> dashes(aStrokeOptions.mDashLength);
+ bool nonZero = false;
+ for (size_t i = 0; i < aStrokeOptions.mDashLength; ++i) {
+ if (aStrokeOptions.mDashPattern[i] != 0) {
+ nonZero = true;
+ }
+ dashes[i] = aStrokeOptions.mDashPattern[i];
+ }
+ // Avoid all-zero patterns that would trigger the CAIRO_STATUS_INVALID_DASH context error state.
+ if (nonZero) {
+ cairo_set_dash(aCtx, &dashes[0], aStrokeOptions.mDashLength,
+ aStrokeOptions.mDashOffset);
+ }
+ }
+
+ cairo_set_line_join(aCtx, GfxLineJoinToCairoLineJoin(aStrokeOptions.mLineJoin));
+
+ cairo_set_line_cap(aCtx, GfxLineCapToCairoLineCap(aStrokeOptions.mLineCap));
+}
+
+static inline cairo_fill_rule_t
+GfxFillRuleToCairoFillRule(FillRule rule)
+{
+ switch (rule)
+ {
+ case FillRule::FILL_WINDING:
+ return CAIRO_FILL_RULE_WINDING;
+ case FillRule::FILL_EVEN_ODD:
+ return CAIRO_FILL_RULE_EVEN_ODD;
+ }
+
+ return CAIRO_FILL_RULE_WINDING;
+}
+
+// RAII class for temporarily changing the cairo matrix transform. It will use
+// the given matrix transform while it is in scope. When it goes out of scope
+// it will put the cairo context back the way it was.
+
+class CairoTempMatrix
+{
+public:
+ CairoTempMatrix(cairo_t* aCtx, const Matrix& aMatrix)
+ : mCtx(aCtx)
+ {
+ cairo_get_matrix(aCtx, &mSaveMatrix);
+ cairo_matrix_t matrix;
+ GfxMatrixToCairoMatrix(aMatrix, matrix);
+ cairo_set_matrix(aCtx, &matrix);
+ }
+
+ ~CairoTempMatrix()
+ {
+ cairo_set_matrix(mCtx, &mSaveMatrix);
+ }
+
+private:
+ cairo_t* mCtx;
+ cairo_matrix_t mSaveMatrix;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* MOZILLA_GFX_HELPERSCAIRO_H_ */