Changeset 285725 in webkit
- Timestamp:
- Nov 12, 2021, 8:52:20 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
dom/ImageOverlay.cpp (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r285724 r285725 1 2021-11-12 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Move subtree update logic in ImageOverlay::updateWithTextRecognitionResult() into a separate helper 4 https://bugs.webkit.org/show_bug.cgi?id=233010 5 6 Reviewed by Aditya Keerthi. 7 8 Split `updateWithTextRecognitionResult()` into two phases: the first of which updates the UA shadow DOM to 9 reflect the given text recognition results, and a second phase that updates inline styles for each of the image 10 overlay elements by mapping normalized OCR quads onto rotated bounding rects in client coordinates. This will 11 make it easier to add support for representing `TextRecognitionBlockData` as image overlay content in the next 12 patch. 13 14 * dom/ImageOverlay.cpp: 15 (WebCore::ImageOverlay::imageOverlayLineClass): 16 (WebCore::ImageOverlay::imageOverlayTextClass): 17 (WebCore::ImageOverlay::updateSubtree): 18 19 Now that this is all namespaced inside `ImageOverlay`, we can also simplify some of these names. Instead of 20 TextRecognitionLineElements and TextRecognitionElements, we can just call them LineElements and Elements. 21 22 (WebCore::ImageOverlay::updateWithTextRecognitionResult): 23 1 24 2021-11-12 Adrian Perez de Castro <aperez@igalia.com> 2 25 -
trunk/Source/WebCore/dom/ImageOverlay.cpp
r285655 r285725 70 70 } 71 71 72 #if ENABLE(IMAGE_ANALYSIS) 73 74 static const AtomString& imageOverlayLineClass() 75 { 76 static MainThreadNeverDestroyed<const AtomString> className("image-overlay-line", AtomString::ConstructFromLiteral); 77 return className; 78 } 79 80 static const AtomString& imageOverlayTextClass() 81 { 82 static MainThreadNeverDestroyed<const AtomString> className("image-overlay-text", AtomString::ConstructFromLiteral); 83 return className; 84 } 85 86 #endif // ENABLE(IMAGE_ANALYSIS) 87 72 88 bool hasOverlay(const HTMLElement& element) 73 89 { … … 167 183 } 168 184 169 void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults) 170 { 171 static MainThreadNeverDestroyed<const AtomString> imageOverlayLineClass("image-overlay-line", AtomString::ConstructFromLiteral); 172 static MainThreadNeverDestroyed<const AtomString> imageOverlayTextClass("image-overlay-text", AtomString::ConstructFromLiteral); 173 174 struct TextRecognitionLineElements { 175 Ref<HTMLDivElement> line; 176 Vector<Ref<HTMLElement>> children; 177 }; 178 179 struct TextRecognitionElements { 180 RefPtr<HTMLDivElement> root; 181 Vector<TextRecognitionLineElements> lines; 182 Vector<Ref<HTMLDivElement>> dataDetectors; 183 }; 184 185 bool hadExistingTextRecognitionElements = false; 186 TextRecognitionElements textRecognitionElements; 185 struct LineElements { 186 Ref<HTMLDivElement> line; 187 Vector<Ref<HTMLElement>> children; 188 }; 189 190 struct Elements { 191 RefPtr<HTMLDivElement> root; 192 Vector<LineElements> lines; 193 Vector<Ref<HTMLDivElement>> dataDetectors; 194 }; 195 196 static Elements updateSubtree(HTMLElement& element, const TextRecognitionResult& result) 197 { 198 bool hadExistingElements = false; 199 Elements elements; 187 200 RefPtr<HTMLElement> mediaControlsContainer; 188 201 if (RefPtr shadowRoot = element.shadowRoot()) { … … 208 221 for (auto& child : childrenOfType<HTMLDivElement>(*containerForImageOverlay)) { 209 222 if (child.getIdAttribute() == imageOverlayElementIdentifier()) { 210 textRecognitionElements.root = &child;211 hadExisting TextRecognitionElements = true;223 elements.root = &child; 224 hadExistingElements = true; 212 225 continue; 213 226 } … … 216 229 } 217 230 218 if ( textRecognitionElements.root) {219 for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(* textRecognitionElements.root)) {231 if (elements.root) { 232 for (auto& lineOrDataDetector : childrenOfType<HTMLDivElement>(*elements.root)) { 220 233 if (!lineOrDataDetector.hasClass()) 221 234 continue; 222 235 223 if (lineOrDataDetector.classList().contains(imageOverlayLineClass )) {224 TextRecognitionLineElements lineElements { lineOrDataDetector, { } };236 if (lineOrDataDetector.classList().contains(imageOverlayLineClass())) { 237 LineElements lineElements { lineOrDataDetector, { } }; 225 238 for (auto& text : childrenOfType<HTMLDivElement>(lineOrDataDetector)) 226 239 lineElements.children.append(text); 227 textRecognitionElements.lines.append(WTFMove(lineElements));240 elements.lines.append(WTFMove(lineElements)); 228 241 } else if (lineOrDataDetector.classList().contains(imageOverlayDataDetectorClassName())) 229 textRecognitionElements.dataDetectors.append(lineOrDataDetector);230 } 231 232 bool canUseExisting TextRecognitionElements = ([&] {233 if (result.dataDetectors.size() != textRecognitionElements.dataDetectors.size())242 elements.dataDetectors.append(lineOrDataDetector); 243 } 244 245 bool canUseExistingElements = ([&] { 246 if (result.dataDetectors.size() != elements.dataDetectors.size()) 234 247 return false; 235 248 236 if (result.lines.size() != textRecognitionElements.lines.size())249 if (result.lines.size() != elements.lines.size()) 237 250 return false; 238 251 239 252 for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) { 240 253 auto& childResults = result.lines[lineIndex].children; 241 auto& childTextElements = textRecognitionElements.lines[lineIndex].children;254 auto& childTextElements = elements.lines[lineIndex].children; 242 255 if (childResults.size() != childTextElements.size()) 243 256 return false; … … 252 265 })(); 253 266 254 if (!canUseExisting TextRecognitionElements) {255 textRecognitionElements.root->remove();256 textRecognitionElements = { };267 if (!canUseExistingElements) { 268 elements.root->remove(); 269 elements = { }; 257 270 } 258 271 } 259 272 260 273 if (result.isEmpty()) 261 return ;274 return { }; 262 275 263 276 Ref document = element.document(); 264 277 Ref shadowRoot = element.ensureUserAgentShadowRoot(); 265 if (! textRecognitionElements.root) {278 if (!elements.root) { 266 279 auto rootContainer = HTMLDivElement::create(document.get()); 267 280 rootContainer->setIdAttribute(imageOverlayElementIdentifier()); … … 273 286 else 274 287 shadowRoot->appendChild(rootContainer); 275 textRecognitionElements.root = rootContainer.copyRef();276 textRecognitionElements.lines.reserveInitialCapacity(result.lines.size());288 elements.root = rootContainer.copyRef(); 289 elements.lines.reserveInitialCapacity(result.lines.size()); 277 290 for (auto& line : result.lines) { 278 291 auto lineContainer = HTMLDivElement::create(document.get()); 279 lineContainer->classList().add(imageOverlayLineClass );292 lineContainer->classList().add(imageOverlayLineClass()); 280 293 rootContainer->appendChild(lineContainer); 281 TextRecognitionLineElements lineElements { lineContainer, { } };294 LineElements lineElements { lineContainer, { } }; 282 295 lineElements.children.reserveInitialCapacity(line.children.size()); 283 296 for (size_t childIndex = 0; childIndex < line.children.size(); ++childIndex) { 284 297 auto& child = line.children[childIndex]; 285 298 auto textContainer = HTMLDivElement::create(document.get()); 286 textContainer->classList().add(imageOverlayTextClass );299 textContainer->classList().add(imageOverlayTextClass()); 287 300 lineContainer->appendChild(textContainer); 288 301 textContainer->appendChild(Text::create(document.get(), child.hasLeadingWhitespace ? makeString('\n', child.text) : child.text)); … … 291 304 292 305 lineContainer->appendChild(HTMLBRElement::create(document.get())); 293 textRecognitionElements.lines.uncheckedAppend(WTFMove(lineElements));306 elements.lines.uncheckedAppend(WTFMove(lineElements)); 294 307 } 295 308 296 309 #if ENABLE(DATA_DETECTION) 297 textRecognitionElements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size());310 elements.dataDetectors.reserveInitialCapacity(result.dataDetectors.size()); 298 311 for (auto& dataDetector : result.dataDetectors) { 299 312 auto dataDetectorContainer = DataDetection::createElementForImageOverlay(document.get(), dataDetector); 300 313 dataDetectorContainer->classList().add(imageOverlayDataDetectorClassName()); 301 314 rootContainer->appendChild(dataDetectorContainer); 302 textRecognitionElements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer));315 elements.dataDetectors.uncheckedAppend(WTFMove(dataDetectorContainer)); 303 316 } 304 317 #endif // ENABLE(DATA_DETECTION) … … 308 321 } 309 322 310 if (!hadExisting TextRecognitionElements) {323 if (!hadExistingElements) { 311 324 static MainThreadNeverDestroyed<const String> shadowStyle(StringImpl::createWithoutCopying(imageOverlayUserAgentStyleSheet, sizeof(imageOverlayUserAgentStyleSheet))); 312 325 auto style = HTMLStyleElement::create(HTMLNames::styleTag, document.get(), false); … … 315 328 } 316 329 330 return elements; 331 } 332 333 void updateWithTextRecognitionResult(HTMLElement& element, const TextRecognitionResult& result, CacheTextRecognitionResults cacheTextRecognitionResults) 334 { 335 auto elements = updateSubtree(element, result); 336 if (!elements.root) 337 return; 338 339 Ref document = element.document(); 317 340 document->updateLayoutIgnorePendingStylesheets(); 318 341 … … 333 356 bool applyUserSelectAll = document->isImageDocument() || renderer->style().userSelect() != UserSelect::None; 334 357 for (size_t lineIndex = 0; lineIndex < result.lines.size(); ++lineIndex) { 335 auto& lineElements = textRecognitionElements.lines[lineIndex];358 auto& lineElements = elements.lines[lineIndex]; 336 359 auto& lineContainer = lineElements.line; 337 360 auto& line = result.lines[lineIndex]; … … 424 447 #if ENABLE(DATA_DETECTION) 425 448 for (size_t index = 0; index < result.dataDetectors.size(); ++index) { 426 auto dataDetectorContainer = textRecognitionElements.dataDetectors[index];449 auto dataDetectorContainer = elements.dataDetectors[index]; 427 450 auto& dataDetector = result.dataDetectors[index]; 428 451 if (dataDetector.normalizedQuads.isEmpty())
Note:
See TracChangeset
for help on using the changeset viewer.