File: text_detector.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (122 lines) | stat: -rw-r--r-- 4,764 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/modules/shapedetection/text_detector.h"

#include <utility>

#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_detected_text.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_point_2d.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/geometry/dom_rect.h"
#include "third_party/blink/renderer/core/workers/worker_thread.h"
#include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_source_util.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"

namespace blink {

TextDetector* TextDetector::Create(ExecutionContext* context) {
  return MakeGarbageCollected<TextDetector>(context);
}

TextDetector::TextDetector(ExecutionContext* context) : text_service_(context) {
  // See https://bit.ly/2S0zRAS for task types.
  auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI);
  context->GetBrowserInterfaceBroker().GetInterface(
      text_service_.BindNewPipeAndPassReceiver(task_runner));

  text_service_.set_disconnect_handler(WTF::BindOnce(
      &TextDetector::OnTextServiceConnectionError, WrapWeakPersistent(this)));
}

ScriptPromise<IDLSequence<DetectedText>> TextDetector::detect(
    ScriptState* script_state,
    const V8ImageBitmapSource* image_source,
    ExceptionState& exception_state) {
  std::optional<SkBitmap> bitmap = GetBitmapFromV8ImageBitmapSource(
      script_state, image_source, exception_state);
  if (!bitmap) {
    return ScriptPromise<IDLSequence<DetectedText>>();
  }

  auto* resolver =
      MakeGarbageCollected<ScriptPromiseResolver<IDLSequence<DetectedText>>>(
          script_state, exception_state.GetContext());
  auto promise = resolver->Promise();
  if (bitmap->isNull()) {
    resolver->Resolve(HeapVector<Member<DetectedText>>());
    return promise;
  }
  if (!text_service_.is_bound()) {
    resolver->RejectWithDOMException(DOMExceptionCode::kNotSupportedError,
                                     "Text detection service unavailable.");
    return promise;
  }
  text_service_requests_.insert(resolver);
  text_service_->Detect(
      std::move(*bitmap),
      WTF::BindOnce(&TextDetector::OnDetectText, WrapPersistent(this),
                    WrapPersistent(resolver)));
  return promise;
}

void TextDetector::OnDetectText(
    ScriptPromiseResolver<IDLSequence<DetectedText>>* resolver,
    Vector<shape_detection::mojom::blink::TextDetectionResultPtr>
        text_detection_results) {
  DCHECK(text_service_requests_.Contains(resolver));
  text_service_requests_.erase(resolver);

  HeapVector<Member<DetectedText>> results;
  for (const auto& text : text_detection_results) {
    HeapVector<Member<Point2D>> corner_points;
    for (const auto& corner_point : text->corner_points) {
      Point2D* point = Point2D::Create();
      point->setX(corner_point.x());
      point->setY(corner_point.y());
      corner_points.push_back(point);
    }

    DetectedText* detected_text = DetectedText::Create();
    detected_text->setRawValue(text->raw_value);
    detected_text->setBoundingBox(DOMRectReadOnly::Create(
        text->bounding_box.x(), text->bounding_box.y(),
        text->bounding_box.width(), text->bounding_box.height()));
    detected_text->setCornerPoints(corner_points);
    results.push_back(detected_text);
  }

  resolver->Resolve(results);
}

void TextDetector::OnTextServiceConnectionError() {
  for (const auto& request : text_service_requests_) {
    // Check if callback's resolver is still valid.
    if (!IsInParallelAlgorithmRunnable(request->GetExecutionContext(),
                                       request->GetScriptState())) {
      continue;
    }
    // Enter into resolver's context to support creating DOMException.
    ScriptState::Scope script_state_scope(request->GetScriptState());

    request->Reject(V8ThrowDOMException::CreateOrDie(
        request->GetScriptState()->GetIsolate(),
        DOMExceptionCode::kNotSupportedError,
        "Text Detection not implemented."));
  }
  text_service_requests_.clear();
  text_service_.reset();
}

void TextDetector::Trace(Visitor* visitor) const {
  ScriptWrappable::Trace(visitor);
  visitor->Trace(text_service_);
  visitor->Trace(text_service_requests_);
}

}  // namespace blink