| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2010 The Android Open Source Project | 2 * Copyright 2010 The Android Open Source Project |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkData.h" | 10 #include "SkData.h" |
| 11 #include "SkDocument.h" | 11 #include "SkDocument.h" |
| 12 #include "SkFlate.h" | 12 #include "SkFlate.h" |
| 13 #include "SkImageEncoder.h" | 13 #include "SkImageEncoder.h" |
| 14 #include "SkMatrix.h" | 14 #include "SkMatrix.h" |
| 15 #include "SkPDFCanon.h" | 15 #include "SkPDFCanon.h" |
| 16 #include "SkPDFCatalog.h" | |
| 17 #include "SkPDFDevice.h" | 16 #include "SkPDFDevice.h" |
| 18 #include "SkPDFStream.h" | 17 #include "SkPDFStream.h" |
| 19 #include "SkPDFTypes.h" | 18 #include "SkPDFTypes.h" |
| 20 #include "SkReadBuffer.h" | 19 #include "SkReadBuffer.h" |
| 21 #include "SkScalar.h" | 20 #include "SkScalar.h" |
| 22 #include "SkStream.h" | 21 #include "SkStream.h" |
| 23 #include "SkTypes.h" | 22 #include "SkTypes.h" |
| 24 #include "Test.h" | 23 #include "Test.h" |
| 25 | 24 |
| 26 #define DUMMY_TEXT "DCT compessed stream." | 25 #define DUMMY_TEXT "DCT compessed stream." |
| 27 | 26 |
| 28 static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, | 27 static bool stream_equals(const SkDynamicMemoryWStream& stream, size_t offset, |
| 29 const void* buffer, size_t len) { | 28 const void* buffer, size_t len) { |
| 30 SkAutoDataUnref data(stream.copyToData()); | 29 SkAutoDataUnref data(stream.copyToData()); |
| 31 if (offset + len > data->size()) { | 30 if (offset + len > data->size()) { |
| 32 return false; | 31 return false; |
| 33 } | 32 } |
| 34 return memcmp(data->bytes() + offset, buffer, len) == 0; | 33 return memcmp(data->bytes() + offset, buffer, len) == 0; |
| 35 } | 34 } |
| 36 | 35 |
| 37 static void emit_object(SkPDFObject* object, | 36 static void emit_object(SkPDFObject* object, |
| 38 SkWStream* stream, | 37 SkWStream* stream, |
| 39 SkPDFCatalog* catalog, | 38 const SkPDFObjNumMap& objNumMap, |
| 39 const SkPDFSubstituteMap& substitutes, |
| 40 bool indirect) { | 40 bool indirect) { |
| 41 SkPDFObject* realObject = catalog->getSubstituteObject(object); | 41 SkPDFObject* realObject = substitutes.getSubstitute(object); |
| 42 if (indirect) { | 42 if (indirect) { |
| 43 stream->writeDecAsText(catalog->getObjectNumber(object)); | 43 stream->writeDecAsText(objNumMap.getObjectNumber(realObject)); |
| 44 stream->writeText(" 0 obj\n"); // Generation number is always 0. | 44 stream->writeText(" 0 obj\n"); // Generation number is always 0. |
| 45 realObject->emitObject(stream, catalog); | 45 realObject->emitObject(stream, objNumMap, substitutes); |
| 46 stream->writeText("\nendobj\n"); | 46 stream->writeText("\nendobj\n"); |
| 47 } else { | 47 } else { |
| 48 realObject->emitObject(stream, catalog); | 48 realObject->emitObject(stream, objNumMap, substitutes); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 static size_t get_output_size(SkPDFObject* object, | 52 static size_t get_output_size(SkPDFObject* object, |
| 53 SkPDFCatalog* catalog, | 53 const SkPDFObjNumMap& objNumMap, |
| 54 const SkPDFSubstituteMap& substitutes, |
| 54 bool indirect) { | 55 bool indirect) { |
| 55 SkDynamicMemoryWStream buffer; | 56 SkDynamicMemoryWStream buffer; |
| 56 emit_object(object, &buffer, catalog, indirect); | 57 emit_object(object, &buffer, objNumMap, substitutes, indirect); |
| 57 return buffer.getOffset(); | 58 return buffer.getOffset(); |
| 58 } | 59 } |
| 59 | 60 |
| 60 static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj, | 61 static void CheckObjectOutput(skiatest::Reporter* reporter, SkPDFObject* obj, |
| 61 const char* expectedData, size_t expectedSize, | 62 const char* expectedData, size_t expectedSize, |
| 62 bool indirect) { | 63 bool indirect) { |
| 63 SkPDFCatalog catalog; | 64 SkPDFSubstituteMap substituteMap; |
| 64 size_t directSize = get_output_size(obj, &catalog, false); | 65 SkPDFObjNumMap catalog; |
| 66 size_t directSize = get_output_size(obj, catalog, substituteMap, false); |
| 65 REPORTER_ASSERT(reporter, directSize == expectedSize); | 67 REPORTER_ASSERT(reporter, directSize == expectedSize); |
| 66 | 68 |
| 67 SkDynamicMemoryWStream buffer; | 69 SkDynamicMemoryWStream buffer; |
| 68 emit_object(obj, &buffer, &catalog, false); | 70 emit_object(obj, &buffer, catalog, substituteMap, false); |
| 69 REPORTER_ASSERT(reporter, directSize == buffer.getOffset()); | 71 REPORTER_ASSERT(reporter, directSize == buffer.getOffset()); |
| 70 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedData, | 72 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedData, |
| 71 directSize)); | 73 directSize)); |
| 72 | 74 |
| 73 if (indirect) { | 75 if (indirect) { |
| 74 // Indirect output. | 76 // Indirect output. |
| 75 static char header[] = "1 0 obj\n"; | 77 static char header[] = "1 0 obj\n"; |
| 76 static size_t headerLen = strlen(header); | 78 static size_t headerLen = strlen(header); |
| 77 static char footer[] = "\nendobj\n"; | 79 static char footer[] = "\nendobj\n"; |
| 78 static size_t footerLen = strlen(footer); | 80 static size_t footerLen = strlen(footer); |
| 79 | 81 |
| 80 catalog.addObject(obj); | 82 catalog.addObject(obj); |
| 81 | 83 |
| 82 size_t indirectSize = get_output_size(obj, &catalog, true); | 84 size_t indirectSize = |
| 85 get_output_size(obj, catalog, substituteMap, true); |
| 83 REPORTER_ASSERT(reporter, | 86 REPORTER_ASSERT(reporter, |
| 84 indirectSize == directSize + headerLen + footerLen); | 87 indirectSize == directSize + headerLen + footerLen); |
| 85 | 88 |
| 86 buffer.reset(); | 89 buffer.reset(); |
| 87 emit_object(obj, &buffer, &catalog, true); | 90 emit_object(obj, &buffer, catalog, substituteMap, true); |
| 88 REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset()); | 91 REPORTER_ASSERT(reporter, indirectSize == buffer.getOffset()); |
| 89 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, header, headerLen)); | 92 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, header, headerLen)); |
| 90 REPORTER_ASSERT(reporter, stream_equals(buffer, headerLen, expectedData, | 93 REPORTER_ASSERT(reporter, stream_equals(buffer, headerLen, expectedData, |
| 91 directSize)); | 94 directSize)); |
| 92 REPORTER_ASSERT(reporter, stream_equals(buffer, headerLen + directSize, | 95 REPORTER_ASSERT(reporter, stream_equals(buffer, headerLen + directSize, |
| 93 footer, footerLen)); | 96 footer, footerLen)); |
| 94 } | 97 } |
| 95 } | 98 } |
| 96 | 99 |
| 97 static void SimpleCheckObjectOutput(skiatest::Reporter* reporter, | 100 static void SimpleCheckObjectOutput(skiatest::Reporter* reporter, |
| 98 SkPDFObject* obj, | 101 SkPDFObject* obj, |
| 99 const char* expectedResult) { | 102 const char* expectedResult) { |
| 100 CheckObjectOutput(reporter, obj, expectedResult, | 103 CheckObjectOutput(reporter, obj, expectedResult, |
| 101 strlen(expectedResult), true); | 104 strlen(expectedResult), true); |
| 102 } | 105 } |
| 103 | 106 |
| 104 static void TestPDFStream(skiatest::Reporter* reporter) { | 107 static void TestPDFStream(skiatest::Reporter* reporter) { |
| 105 char streamBytes[] = "Test\nFoo\tBar"; | 108 char streamBytes[] = "Test\nFoo\tBar"; |
| 106 SkAutoTDelete<SkMemoryStream> streamData(new SkMemoryStream( | 109 SkAutoTDelete<SkMemoryStream> streamData(new SkMemoryStream( |
| 107 streamBytes, strlen(streamBytes), true)); | 110 streamBytes, strlen(streamBytes), true)); |
| 108 SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData.get())); | 111 SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData.get())); |
| 109 SimpleCheckObjectOutput( | 112 SimpleCheckObjectOutput( |
| 110 reporter, stream.get(), | 113 reporter, stream.get(), |
| 111 "<</Length 12\n>> stream\nTest\nFoo\tBar\nendstream"); | 114 "<</Length 12>> stream\nTest\nFoo\tBar\nendstream"); |
| 112 stream->insert("Attribute", new SkPDFInt(42))->unref(); | 115 stream->insert("Attribute", new SkPDFInt(42))->unref(); |
| 113 SimpleCheckObjectOutput(reporter, stream.get(), | 116 SimpleCheckObjectOutput(reporter, stream.get(), |
| 114 "<</Length 12\n/Attribute 42\n>> stream\n" | 117 "<</Length 12\n/Attribute 42>> stream\n" |
| 115 "Test\nFoo\tBar\nendstream"); | 118 "Test\nFoo\tBar\nendstream"); |
| 116 | 119 |
| 117 { | 120 { |
| 118 char streamBytes2[] = "This is a longer string, so that compression " | 121 char streamBytes2[] = "This is a longer string, so that compression " |
| 119 "can do something with it. With shorter strings, " | 122 "can do something with it. With shorter strings, " |
| 120 "the short circuit logic cuts in and we end up " | 123 "the short circuit logic cuts in and we end up " |
| 121 "with an uncompressed string."; | 124 "with an uncompressed string."; |
| 122 SkAutoDataUnref streamData2(SkData::NewWithCopy(streamBytes2, | 125 SkAutoDataUnref streamData2(SkData::NewWithCopy(streamBytes2, |
| 123 strlen(streamBytes2))); | 126 strlen(streamBytes2))); |
| 124 SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData2.get())); | 127 SkAutoTUnref<SkPDFStream> stream(new SkPDFStream(streamData2.get())); |
| 125 | 128 |
| 126 SkDynamicMemoryWStream compressedByteStream; | 129 SkDynamicMemoryWStream compressedByteStream; |
| 127 SkFlate::Deflate(streamData2.get(), &compressedByteStream); | 130 SkFlate::Deflate(streamData2.get(), &compressedByteStream); |
| 128 SkAutoDataUnref compressedData(compressedByteStream.copyToData()); | 131 SkAutoDataUnref compressedData(compressedByteStream.copyToData()); |
| 129 | 132 |
| 130 SkDynamicMemoryWStream expected; | 133 SkDynamicMemoryWStream expected; |
| 131 expected.writeText("<</Filter /FlateDecode\n/Length 116\n" | 134 expected.writeText("<</Filter /FlateDecode\n/Length 116>> stream\n"); |
| 132 ">> stream\n"); | |
| 133 expected.write(compressedData->data(), compressedData->size()); | 135 expected.write(compressedData->data(), compressedData->size()); |
| 134 expected.writeText("\nendstream"); | 136 expected.writeText("\nendstream"); |
| 135 SkAutoDataUnref expectedResultData2(expected.copyToData()); | 137 SkAutoDataUnref expectedResultData2(expected.copyToData()); |
| 136 CheckObjectOutput(reporter, stream.get(), | 138 CheckObjectOutput(reporter, stream.get(), |
| 137 (const char*) expectedResultData2->data(), | 139 (const char*) expectedResultData2->data(), |
| 138 expectedResultData2->size(), true); | 140 expectedResultData2->size(), true); |
| 139 } | 141 } |
| 140 } | 142 } |
| 141 | 143 |
| 142 static void TestCatalog(skiatest::Reporter* reporter) { | 144 static void TestCatalog(skiatest::Reporter* reporter) { |
| 143 SkPDFCatalog catalog; | 145 SkPDFSubstituteMap substituteMap; |
| 146 SkPDFObjNumMap catalog; |
| 144 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); | 147 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); |
| 145 SkAutoTUnref<SkPDFInt> int2(new SkPDFInt(2)); | 148 SkAutoTUnref<SkPDFInt> int2(new SkPDFInt(2)); |
| 146 SkAutoTUnref<SkPDFInt> int3(new SkPDFInt(3)); | 149 SkAutoTUnref<SkPDFInt> int3(new SkPDFInt(3)); |
| 147 int1.get()->ref(); | 150 int1.get()->ref(); |
| 148 SkAutoTUnref<SkPDFInt> int1Again(int1.get()); | 151 SkAutoTUnref<SkPDFInt> int1Again(int1.get()); |
| 149 | 152 |
| 150 catalog.addObject(int1.get()); | 153 catalog.addObject(int1.get()); |
| 151 catalog.addObject(int2.get()); | 154 catalog.addObject(int2.get()); |
| 152 catalog.addObject(int3.get()); | 155 catalog.addObject(int3.get()); |
| 153 | 156 |
| 154 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1.get()) == 1); | 157 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1.get()) == 1); |
| 155 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int2.get()) == 2); | 158 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int2.get()) == 2); |
| 156 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int3.get()) == 3); | 159 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int3.get()) == 3); |
| 157 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1Again.get()) == 1); | 160 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1Again.get()) == 1); |
| 158 } | 161 } |
| 159 | 162 |
| 160 static void TestObjectRef(skiatest::Reporter* reporter) { | 163 static void TestObjectRef(skiatest::Reporter* reporter) { |
| 161 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); | 164 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); |
| 162 SkAutoTUnref<SkPDFInt> int2(new SkPDFInt(2)); | 165 SkAutoTUnref<SkPDFInt> int2(new SkPDFInt(2)); |
| 163 SkAutoTUnref<SkPDFObjRef> int2ref(new SkPDFObjRef(int2.get())); | 166 SkAutoTUnref<SkPDFObjRef> int2ref(new SkPDFObjRef(int2.get())); |
| 164 | 167 |
| 165 SkPDFCatalog catalog; | 168 SkPDFSubstituteMap substituteMap; |
| 169 SkPDFObjNumMap catalog; |
| 166 catalog.addObject(int1.get()); | 170 catalog.addObject(int1.get()); |
| 167 catalog.addObject(int2.get()); | 171 catalog.addObject(int2.get()); |
| 168 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1.get()) == 1); | 172 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int1.get()) == 1); |
| 169 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int2.get()) == 2); | 173 REPORTER_ASSERT(reporter, catalog.getObjectNumber(int2.get()) == 2); |
| 170 | 174 |
| 171 char expectedResult[] = "2 0 R"; | 175 char expectedResult[] = "2 0 R"; |
| 172 SkDynamicMemoryWStream buffer; | 176 SkDynamicMemoryWStream buffer; |
| 173 int2ref->emitObject(&buffer, &catalog); | 177 int2ref->emitObject(&buffer, catalog, substituteMap); |
| 174 REPORTER_ASSERT(reporter, buffer.getOffset() == strlen(expectedResult)); | 178 REPORTER_ASSERT(reporter, buffer.getOffset() == strlen(expectedResult)); |
| 175 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult, | 179 REPORTER_ASSERT(reporter, stream_equals(buffer, 0, expectedResult, |
| 176 buffer.getOffset())); | 180 buffer.getOffset())); |
| 177 } | 181 } |
| 178 | 182 |
| 179 static void TestSubstitute(skiatest::Reporter* reporter) { | 183 static void TestSubstitute(skiatest::Reporter* reporter) { |
| 180 SkAutoTUnref<SkPDFDict> proxy(new SkPDFDict()); | 184 SkAutoTUnref<SkPDFDict> proxy(new SkPDFDict()); |
| 181 SkAutoTUnref<SkPDFDict> stub(new SkPDFDict()); | 185 SkAutoTUnref<SkPDFDict> stub(new SkPDFDict()); |
| 182 | 186 |
| 183 proxy->insert("Value", new SkPDFInt(33))->unref(); | 187 proxy->insert("Value", new SkPDFInt(33))->unref(); |
| 184 stub->insert("Value", new SkPDFInt(44))->unref(); | 188 stub->insert("Value", new SkPDFInt(44))->unref(); |
| 185 | 189 |
| 186 SkPDFCatalog catalog; | 190 SkPDFSubstituteMap substituteMap; |
| 191 substituteMap.setSubstitute(proxy.get(), stub.get()); |
| 192 SkPDFObjNumMap catalog; |
| 187 catalog.addObject(proxy.get()); | 193 catalog.addObject(proxy.get()); |
| 188 catalog.setSubstitute(proxy.get(), stub.get()); | |
| 189 | 194 |
| 190 REPORTER_ASSERT(reporter, stub.get() == catalog.getSubstituteObject(proxy)); | 195 REPORTER_ASSERT(reporter, stub.get() == substituteMap.getSubstitute(proxy)); |
| 191 REPORTER_ASSERT(reporter, proxy.get() != catalog.getSubstituteObject(stub)); | 196 REPORTER_ASSERT(reporter, proxy.get() != substituteMap.getSubstitute(stub)); |
| 192 } | 197 } |
| 193 | 198 |
| 194 // This test used to assert without the fix submitted for | 199 // This test used to assert without the fix submitted for |
| 195 // http://code.google.com/p/skia/issues/detail?id=1083. | 200 // http://code.google.com/p/skia/issues/detail?id=1083. |
| 196 // SKP files might have invalid glyph ids. This test ensures they are ignored, | 201 // SKP files might have invalid glyph ids. This test ensures they are ignored, |
| 197 // and there is no assert on input data in Debug mode. | 202 // and there is no assert on input data in Debug mode. |
| 198 static void test_issue1083() { | 203 static void test_issue1083() { |
| 199 SkDynamicMemoryWStream outStream; | 204 SkDynamicMemoryWStream outStream; |
| 200 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&outStream)); | 205 SkAutoTUnref<SkDocument> doc(SkDocument::CreatePDF(&outStream)); |
| 201 SkCanvas* canvas = doc->beginPage(100.0f, 100.0f); | 206 SkCanvas* canvas = doc->beginPage(100.0f, 100.0f); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 array->append(int0.get()); | 270 array->append(int0.get()); |
| 266 SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5 0]"); | 271 SimpleCheckObjectOutput(reporter, array.get(), "[42 0.5 0]"); |
| 267 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); | 272 SkAutoTUnref<SkPDFInt> int1(new SkPDFInt(1)); |
| 268 array->setAt(0, int1.get()); | 273 array->setAt(0, int1.get()); |
| 269 SimpleCheckObjectOutput(reporter, array.get(), "[1 0.5 0]"); | 274 SimpleCheckObjectOutput(reporter, array.get(), "[1 0.5 0]"); |
| 270 | 275 |
| 271 SkAutoTUnref<SkPDFDict> dict(new SkPDFDict); | 276 SkAutoTUnref<SkPDFDict> dict(new SkPDFDict); |
| 272 SimpleCheckObjectOutput(reporter, dict.get(), "<<>>"); | 277 SimpleCheckObjectOutput(reporter, dict.get(), "<<>>"); |
| 273 SkAutoTUnref<SkPDFName> n1(new SkPDFName("n1")); | 278 SkAutoTUnref<SkPDFName> n1(new SkPDFName("n1")); |
| 274 dict->insert(n1.get(), int42.get()); | 279 dict->insert(n1.get(), int42.get()); |
| 275 SimpleCheckObjectOutput(reporter, dict.get(), "<</n1 42\n>>"); | 280 SimpleCheckObjectOutput(reporter, dict.get(), "<</n1 42>>"); |
| 276 SkAutoTUnref<SkPDFName> n2(new SkPDFName("n2")); | 281 SkAutoTUnref<SkPDFName> n2(new SkPDFName("n2")); |
| 277 SkAutoTUnref<SkPDFName> n3(new SkPDFName("n3")); | 282 SkAutoTUnref<SkPDFName> n3(new SkPDFName("n3")); |
| 278 dict->insert(n2.get(), realHalf.get()); | 283 dict->insert(n2.get(), realHalf.get()); |
| 279 dict->insert(n3.get(), array.get()); | 284 dict->insert(n3.get(), array.get()); |
| 280 SimpleCheckObjectOutput(reporter, dict.get(), | 285 SimpleCheckObjectOutput(reporter, dict.get(), |
| 281 "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]\n>>"); | 286 "<</n1 42\n/n2 0.5\n/n3 [1 0.5 0]>>"); |
| 282 | 287 |
| 283 TestPDFStream(reporter); | 288 TestPDFStream(reporter); |
| 284 | 289 |
| 285 TestCatalog(reporter); | 290 TestCatalog(reporter); |
| 286 | 291 |
| 287 TestObjectRef(reporter); | 292 TestObjectRef(reporter); |
| 288 | 293 |
| 289 TestSubstitute(reporter); | 294 TestSubstitute(reporter); |
| 290 | 295 |
| 291 test_issue1083(); | 296 test_issue1083(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 // Filter just created; should be unvisited. | 344 // Filter just created; should be unvisited. |
| 340 REPORTER_ASSERT(reporter, !filter->visited()); | 345 REPORTER_ASSERT(reporter, !filter->visited()); |
| 341 SkPaint paint; | 346 SkPaint paint; |
| 342 paint.setImageFilter(filter.get()); | 347 paint.setImageFilter(filter.get()); |
| 343 canvas->drawRect(SkRect::MakeWH(100, 100), paint); | 348 canvas->drawRect(SkRect::MakeWH(100, 100), paint); |
| 344 doc->close(); | 349 doc->close(); |
| 345 | 350 |
| 346 // Filter was used in rendering; should be visited. | 351 // Filter was used in rendering; should be visited. |
| 347 REPORTER_ASSERT(reporter, filter->visited()); | 352 REPORTER_ASSERT(reporter, filter->visited()); |
| 348 } | 353 } |
| OLD | NEW |