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/. */
6 #ifndef MOZILLA_GFX_LOGGING_H_
7 #define MOZILLA_GFX_LOGGING_H_
17 #include "mozilla/TypedEnum.h"
20 // This file gets included from nsGlobalWindow.cpp, which doesn't like
21 // having windows.h included in it. Since OutputDebugStringA is the only
22 // thing we need from windows.h, we just declare it here directly.
23 // Note: the function's documented signature is
24 // WINBASEAPI void WINAPI OutputDebugStringA(LPCSTR lpOutputString)
25 // but if we don't include windows.h, the macros WINBASEAPI, WINAPI, and
26 // LPCSTR are not defined, so we need to replace them with their expansions.
27 extern "C" __declspec(dllimport
) void __stdcall
OutputDebugStringA(const char* lpOutputString
);
30 #if defined(DEBUG) || defined(PR_LOGGING)
33 extern GFX2D_API PRLogModuleInfo
*GetGFX2DLog();
39 const int LOG_DEBUG
= 1;
40 const int LOG_WARNING
= 2;
42 #if defined(DEBUG) || defined(PR_LOGGING)
44 inline PRLogModuleLevel
PRLogLevelForLevel(int aLevel
) {
49 return PR_LOG_WARNING
;
56 extern GFX2D_API
int sGfxLogLevel
;
58 static inline void OutputMessage(const std::string
&aString
, int aLevel
) {
59 #if defined(WIN32) && !defined(PR_LOGGING)
60 if (aLevel
>= sGfxLogLevel
) {
61 ::OutputDebugStringA(aString
.c_str());
63 #elif defined(PR_LOGGING) && !(defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID))
64 if (PR_LOG_TEST(GetGFX2DLog(), PRLogLevelForLevel(aLevel
))) {
65 PR_LogPrint(aString
.c_str());
68 if (aLevel
>= sGfxLogLevel
) {
69 printf_stderr("%s", aString
.c_str());
81 NoLog
&operator <<(const T
&aLogText
) { return *this; }
84 MOZ_BEGIN_ENUM_CLASS(LogOptions
, int)
86 MOZ_END_ENUM_CLASS(LogOptions
)
92 explicit Log(LogOptions aOptions
= LogOptions(0)) : mOptions(aOptions
) {}
98 if (!(int(mOptions
) & int(LogOptions::NoNewline
))) {
101 std::string str
= mMessage
.str();
109 Log
&operator <<(char aChar
) { mMessage
<< aChar
; return *this; }
110 Log
&operator <<(const std::string
&aLogText
) { mMessage
<< aLogText
; return *this; }
111 Log
&operator <<(const char aStr
[]) { mMessage
<< static_cast<const char*>(aStr
); return *this; }
112 Log
&operator <<(bool aBool
) { mMessage
<< (aBool
? "true" : "false"); return *this; }
113 Log
&operator <<(int aInt
) { mMessage
<< aInt
; return *this; }
114 Log
&operator <<(unsigned int aInt
) { mMessage
<< aInt
; return *this; }
115 Log
&operator <<(long aLong
) { mMessage
<< aLong
; return *this; }
116 Log
&operator <<(unsigned long aLong
) { mMessage
<< aLong
; return *this; }
117 Log
&operator <<(long long aLong
) { mMessage
<< aLong
; return *this; }
118 Log
&operator <<(unsigned long long aLong
) { mMessage
<< aLong
; return *this; }
119 Log
&operator <<(Float aFloat
) { mMessage
<< aFloat
; return *this; }
120 Log
&operator <<(double aDouble
) { mMessage
<< aDouble
; return *this; }
121 template <typename T
, typename Sub
>
122 Log
&operator <<(const BasePoint
<T
, Sub
>& aPoint
)
123 { mMessage
<< "Point" << aPoint
; return *this; }
124 template <typename T
, typename Sub
>
125 Log
&operator <<(const BaseSize
<T
, Sub
>& aSize
)
126 { mMessage
<< "Size(" << aSize
.width
<< "," << aSize
.height
<< ")"; return *this; }
127 template <typename T
, typename Sub
, typename Point
, typename SizeT
, typename Margin
>
128 Log
&operator <<(const BaseRect
<T
, Sub
, Point
, SizeT
, Margin
>& aRect
)
129 { mMessage
<< "Rect" << aRect
; return *this; }
130 Log
&operator<<(const Matrix
& aMatrix
)
131 { mMessage
<< "Matrix(" << aMatrix
._11
<< " " << aMatrix
._12
<< " ; " << aMatrix
._21
<< " " << aMatrix
._22
<< " ; " << aMatrix
._31
<< " " << aMatrix
._32
<< ")"; return *this; }
136 void WriteLog(const std::string
&aString
) {
137 OutputMessage(aString
, L
);
140 std::stringstream mMessage
;
144 typedef Log
<LOG_DEBUG
> DebugLog
;
145 typedef Log
<LOG_WARNING
> WarningLog
;
148 #define gfxDebug DebugLog
150 #define gfxDebug if (1) ; else NoLog
152 #ifdef GFX_LOG_WARNING
153 #define gfxWarning WarningLog
155 #define gfxWarning if (1) ; else NoLog
158 // See nsDebug.h and the NS_WARN_IF macro
162 inline bool MOZ2D_warn_if_impl(bool aCondition
, const char* aExpr
,
163 const char* aFile
, int32_t aLine
)
165 if (MOZ_UNLIKELY(aCondition
)) {
166 gfxWarning() << aExpr
<< " at " << aFile
<< ":" << aLine
;
170 #define MOZ2D_WARN_IF(condition) \
171 MOZ2D_warn_if_impl(condition, #condition, __FILE__, __LINE__)
173 #define MOZ2D_WARN_IF(condition) (bool)(condition)
177 const int INDENT_PER_LEVEL
= 2;
182 explicit TreeLog(const std::string
& aPrefix
= "")
183 : mLog(LogOptions::NoNewline
),
187 mConditionedOnPref(false),
188 mPrefFunction(nullptr) {}
190 template <typename T
>
191 TreeLog
& operator<<(const T
& aObject
) {
192 if (mConditionedOnPref
&& !mPrefFunction()) {
196 mLog
<< '[' << mPrefix
<< "] " << std::string(mDepth
* INDENT_PER_LEVEL
, ' ');
197 mStartOfLine
= false;
200 if (EndsInNewline(aObject
)) {
201 // Don't indent right here as the user may change the indent
202 // between now and the first output to the next line.
209 void IncreaseIndent() { ++mDepth
; }
210 void DecreaseIndent() { --mDepth
; }
212 void ConditionOnPrefFunction(bool(*aPrefFunction
)()) {
213 mConditionedOnPref
= true;
214 mPrefFunction
= aPrefFunction
;
221 bool mConditionedOnPref
;
222 bool (*mPrefFunction
)();
224 template <typename T
>
225 static bool EndsInNewline(const T
& aObject
) {
229 static bool EndsInNewline(const std::string
& aString
) {
230 return !aString
.empty() && aString
[aString
.length() - 1] == '\n';
233 static bool EndsInNewline(char aChar
) {
234 return aChar
== '\n';
237 static bool EndsInNewline(const char* aString
) {
238 return EndsInNewline(std::string(aString
));
245 explicit TreeAutoIndent(TreeLog
& aTreeLog
) : mTreeLog(aTreeLog
) {
246 mTreeLog
.IncreaseIndent();
249 mTreeLog
.DecreaseIndent();
258 #endif /* MOZILLA_GFX_LOGGING_H_ */