Flutter Engine
The Flutter Engine
skdiff_html.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
11
12/// Make layout more consistent by scaling image to 240 height, 360 width,
13/// or natural size, whichever is smallest.
14static int compute_image_height(int height, int width) {
15 int retval = 240;
16 if (height < retval) {
17 retval = height;
18 }
19 float scale = (float) retval / height;
20 if (width * scale > 360) {
21 scale = (float) 360 / width;
22 retval = static_cast<int>(height * scale);
23 }
24 return retval;
25}
26
28 const int matchCount,
29 const int colorThreshold,
30 const RecordArray& differences,
31 const SkString &baseDir,
32 const SkString &comparisonDir) {
33 stream->writeText("<table>\n");
34 stream->writeText("<tr><th>");
35 stream->writeText("select image</th>\n<th>");
36 stream->writeDecAsText(matchCount);
37 stream->writeText(" of ");
38 stream->writeDecAsText(differences.size());
39 stream->writeText(" diffs matched ");
40 if (colorThreshold == 0) {
41 stream->writeText("exactly");
42 } else {
43 stream->writeText("within ");
44 stream->writeDecAsText(colorThreshold);
45 stream->writeText(" color units per component");
46 }
47 stream->writeText(".<br>");
48 stream->writeText("</th>\n<th>");
49 stream->writeText("every different pixel shown in white");
50 stream->writeText("</th>\n<th>");
51 stream->writeText("color difference at each pixel");
52 stream->writeText("</th>\n<th>baseDir: ");
53 stream->writeText(baseDir.c_str());
54 stream->writeText("</th>\n<th>comparisonDir: ");
55 stream->writeText(comparisonDir.c_str());
56 stream->writeText("</th>\n");
57 stream->writeText("</tr>\n");
58}
59
61 stream->writeText("<br>(");
62 stream->writeDecAsText(static_cast<int>(diff.fFractionDifference *
63 diff.fBase.fBitmap.width() *
64 diff.fBase.fBitmap.height()));
65 stream->writeText(" pixels)");
66/*
67 stream->writeDecAsText(diff.fWeightedFraction *
68 diff.fBaseWidth *
69 diff.fBaseHeight);
70 stream->writeText(" weighted pixels)");
71*/
72}
73
75 stream->writeText("<td><input type=\"checkbox\" name=\"");
76 stream->writeText(diff.fBase.fFilename.c_str());
77 stream->writeText("\" checked=\"yes\"></td>");
78}
79
80static void print_label_cell(SkFILEWStream* stream, const DiffRecord& diff) {
81 char metricBuf [20];
82
83 stream->writeText("<td><b>");
84 stream->writeText(diff.fBase.fFilename.c_str());
85 stream->writeText("</b><br>");
86 switch (diff.fResult) {
88 SkDEBUGFAIL("should not encounter DiffRecord with kEqualBits here");
89 return;
91 SkDEBUGFAIL("should not encounter DiffRecord with kEqualPixels here");
92 return;
94 stream->writeText("Image sizes differ</td>");
95 return;
97 sprintf(metricBuf, "%.4f%%", 100 * diff.fFractionDifference);
98 stream->writeText(metricBuf);
99 stream->writeText(" of pixels differ");
100 stream->writeText("\n (");
101 sprintf(metricBuf, "%.4f%%", 100 * diff.fWeightedFraction);
102 stream->writeText(metricBuf);
103 stream->writeText(" weighted)");
104 // Write the actual number of pixels that differ if it's < 1%
105 if (diff.fFractionDifference < 0.01) {
107 }
108 stream->writeText("<br>");
110 stream->writeText("<br>Average alpha channel mismatch ");
111 stream->writeDecAsText(SkScalarRoundToInt(diff.fAverageMismatchA));
112 }
113
114 stream->writeText("<br>Max alpha channel mismatch ");
115 stream->writeDecAsText(SkScalarRoundToInt(diff.fMaxMismatchA));
116
117 stream->writeText("<br>Total alpha channel mismatch ");
118 stream->writeDecAsText(static_cast<int>(diff.fTotalMismatchA));
119
120 stream->writeText("<br>");
121 stream->writeText("<br>Average color mismatch ");
122 stream->writeDecAsText(SkScalarRoundToInt(MAX3(diff.fAverageMismatchR,
124 diff.fAverageMismatchB)));
125 stream->writeText("<br>Max color mismatch ");
126 stream->writeDecAsText(MAX3(diff.fMaxMismatchR,
127 diff.fMaxMismatchG,
128 diff.fMaxMismatchB));
129 stream->writeText("</td>");
130 break;
132 stream->writeText("Could not compare.<br>base: ");
134 stream->writeText("<br>comparison: ");
136 stream->writeText("</td>");
137 return;
138 default:
139 SkDEBUGFAIL("encountered DiffRecord with unknown result type");
140 return;
141 }
142}
143
145 stream->writeText("<td><a href=\"");
146 stream->writeText(path.c_str());
147 stream->writeText("\"><img src=\"");
148 stream->writeText(path.c_str());
149 stream->writeText("\" height=\"");
150 stream->writeDecAsText(height);
151 stream->writeText("px\"></a></td>");
152}
153
154static void print_link_cell(SkFILEWStream* stream, const SkString& path, const char* text) {
155 stream->writeText("<td><a href=\"");
156 stream->writeText(path.c_str());
157 stream->writeText("\">");
158 stream->writeText(text);
159 stream->writeText("</a></td>");
160}
161
163 const SkString& relativePath, bool local) {
164 SkString fullPath = resource.fFullPath;
165 if (resource.fBitmap.empty()) {
167 if (local && !resource.fFilename.isEmpty()) {
168 print_link_cell(stream, resource.fFilename, "N/A");
169 return;
170 }
171 if (!fullPath.isEmpty()) {
172 if (!fullPath.startsWith(PATH_DIV_STR)) {
173 fullPath.prepend(relativePath);
174 }
175 print_link_cell(stream, fullPath, "N/A");
176 return;
177 }
178 }
179 stream->writeText("<td>N/A</td>");
180 return;
181 }
182
183 int height = compute_image_height(resource.fBitmap.height(), resource.fBitmap.width());
184 if (local) {
186 return;
187 }
188 if (!fullPath.startsWith(PATH_DIV_STR)) {
189 fullPath.prepend(relativePath);
190 }
191 print_image_cell(stream, fullPath, height);
192}
193
194static void print_diff_row(SkFILEWStream* stream, const DiffRecord& diff, const SkString& relativePath) {
195 stream->writeText("<tr>\n");
198 print_diff_resource_cell(stream, diff.fWhite, relativePath, true);
199 print_diff_resource_cell(stream, diff.fDifference, relativePath, true);
200 print_diff_resource_cell(stream, diff.fBase, relativePath, false);
201 print_diff_resource_cell(stream, diff.fComparison, relativePath, false);
202 stream->writeText("</tr>\n");
203 stream->flush();
204}
205
206void print_diff_page(const int matchCount,
207 const int colorThreshold,
208 const RecordArray& differences,
209 const SkString& baseDir,
210 const SkString& comparisonDir,
211 const SkString& outputDir) {
212
213 SkASSERT(!baseDir.isEmpty());
214 SkASSERT(!comparisonDir.isEmpty());
215 SkASSERT(!outputDir.isEmpty());
216
217 SkString outputPath(outputDir);
218 outputPath.append("index.html");
219 //SkFILEWStream outputStream ("index.html");
220 SkFILEWStream outputStream(outputPath.c_str());
221
222 // Need to convert paths from relative-to-cwd to relative-to-outputDir
223 // FIXME this doesn't work if there are '..' inside the outputDir
224
225 bool isPathAbsolute = false;
226 // On Windows or Linux, a path starting with PATH_DIV_CHAR is absolute.
227 if (outputDir.size() > 0 && PATH_DIV_CHAR == outputDir[0]) {
228 isPathAbsolute = true;
229 }
230#ifdef SK_BUILD_FOR_WIN
231 // On Windows, absolute paths can also start with "x:", where x is any
232 // drive letter.
233 if (outputDir.size() > 1 && ':' == outputDir[1]) {
234 isPathAbsolute = true;
235 }
236#endif
237
238 SkString relativePath;
239 if (!isPathAbsolute) {
240 unsigned int ui;
241 for (ui = 0; ui < outputDir.size(); ui++) {
242 if (outputDir[ui] == PATH_DIV_CHAR) {
243 relativePath.append(".." PATH_DIV_STR);
244 }
245 }
246 }
247
248 outputStream.writeText(
249 "<html>\n<head>\n"
250 "<script type=\"text/javascript\">\n"
251 "function generateCheckedList() {\n"
252 " const boxes = document.querySelectorAll('input[type=checkbox]:checked');\n"
253 " let fileCmdLineString = '';\n"
254 " let fileMultiLineString = '';\n"
255 " for (let i = 0; i < boxes.length; i++) {\n"
256 " fileMultiLineString += boxes[i].name + '<br>';\n"
257 " fileCmdLineString += boxes[i].name + '&nbsp;';\n"
258 " }\n"
259 " const checkedList = document.querySelector('#checkedList');\n"
260 " checkedList.innerHTML = fileCmdLineString + '<br><br>' + fileMultiLineString;\n"
261 "}\n"
262 "</script>\n</head>\n<body>\n");
263 print_table_header(&outputStream, matchCount, colorThreshold, differences,
264 baseDir, comparisonDir);
265 int i;
266 for (i = 0; i < differences.size(); i++) {
267 const DiffRecord& diff = differences[i];
268
269 switch (diff.fResult) {
270 // Cases in which there is no diff to report.
273 continue;
274 // Cases in which we want a detailed pixel diff.
278 print_diff_row(&outputStream, diff, relativePath);
279 continue;
280 default:
281 SkDEBUGFAIL("encountered DiffRecord with unknown result type");
282 continue;
283 }
284 }
285 outputStream.writeText(
286 "</table>\n"
287 "<input type=\"button\" "
288 "onclick=\"generateCheckedList()\" "
289 "value=\"Create Rebaseline List\">\n"
290 "<div id=\"checkedList\"></div>\n"
291 "</body>\n</html>\n");
292 outputStream.flush();
293}
#define SkDEBUGFAIL(message)
Definition: SkAssert.h:118
#define SkASSERT(cond)
Definition: SkAssert.h:116
static SkString resource(SkPDFResourceType type, int index)
#define SkScalarRoundToInt(x)
Definition: SkScalar.h:37
int width() const
Definition: SkBitmap.h:149
int height() const
Definition: SkBitmap.h:158
void flush() override
Definition: SkStream.cpp:442
bool startsWith(const char prefixStr[]) const
Definition: SkString.h:140
size_t size() const
Definition: SkString.h:131
bool isEmpty() const
Definition: SkString.h:130
void append(const char text[])
Definition: SkString.h:203
void prepend(const char text[])
Definition: SkString.h:215
const char * c_str() const
Definition: SkString.h:133
bool writeText(const char text[])
Definition: SkStream.h:247
int size() const
Definition: SkTArray.h:421
std::u16string text
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
int32_t height
int32_t width
#define MAX3(a, b, c)
Definition: skdiff.h:26
#define PATH_DIV_STR
Definition: skdiff.h:21
#define PATH_DIV_CHAR
Definition: skdiff.h:22
void print_diff_page(const int matchCount, const int colorThreshold, const RecordArray &differences, const SkString &baseDir, const SkString &comparisonDir, const SkString &outputDir)
static void print_link_cell(SkFILEWStream *stream, const SkString &path, const char *text)
static void print_pixel_count(SkFILEWStream *stream, const DiffRecord &diff)
Definition: skdiff_html.cpp:60
static void print_label_cell(SkFILEWStream *stream, const DiffRecord &diff)
Definition: skdiff_html.cpp:80
static void print_diff_row(SkFILEWStream *stream, const DiffRecord &diff, const SkString &relativePath)
static void print_table_header(SkFILEWStream *stream, const int matchCount, const int colorThreshold, const RecordArray &differences, const SkString &baseDir, const SkString &comparisonDir)
Definition: skdiff_html.cpp:27
static void print_image_cell(SkFILEWStream *stream, const SkString &path, int height)
static int compute_image_height(int height, int width)
Definition: skdiff_html.cpp:14
static void print_diff_resource_cell(SkFILEWStream *stream, const DiffResource &resource, const SkString &relativePath, bool local)
static void print_checkbox_cell(SkFILEWStream *stream, const DiffRecord &diff)
Definition: skdiff_html.cpp:74
const Scalar scale
DiffResource fDifference
Definition: skdiff.h:132
DiffResource fComparison
Definition: skdiff.h:131
float fAverageMismatchG
Definition: skdiff.h:143
Result fResult
Which category of diff result.
Definition: skdiff.h:154
@ kEqualBits_Result
Definition: skdiff.h:92
@ kCouldNotCompare_Result
Definition: skdiff.h:96
@ kDifferentSizes_Result
Definition: skdiff.h:95
@ kDifferentPixels_Result
Definition: skdiff.h:94
@ kEqualPixels_Result
Definition: skdiff.h:93
DiffResource fBase
Definition: skdiff.h:130
float fAverageMismatchA
Definition: skdiff.h:141
uint32_t fMaxMismatchB
Definition: skdiff.h:151
uint32_t fMaxMismatchR
Definition: skdiff.h:149
float fFractionDifference
Definition: skdiff.h:138
uint32_t fMaxMismatchG
Definition: skdiff.h:150
float fAverageMismatchB
Definition: skdiff.h:144
float fWeightedFraction
Definition: skdiff.h:139
uint32_t fMaxMismatchA
Definition: skdiff.h:148
float fAverageMismatchR
Definition: skdiff.h:142
uint32_t fTotalMismatchA
Definition: skdiff.h:146
DiffResource fWhite
Definition: skdiff.h:133
SkBitmap fBitmap
Definition: skdiff.h:83
static const char * getStatusDescription(Status status)
Definition: skdiff.cpp:86
@ kCouldNotDecode_Status
Definition: skdiff.h:34
Status fStatus
Definition: skdiff.h:84
SkString fFilename
Definition: skdiff.h:79