File: browser_frame_view_paint_utils_linux.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (106 lines) | stat: -rw-r--r-- 4,012 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
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/frame/browser_frame_view_paint_utils_linux.h"

#include "third_party/skia/include/core/SkRRect.h"
#include "ui/color/color_provider.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/scoped_canvas.h"
#include "ui/gfx/skia_paint_util.h"
#include "ui/views/view.h"
#include "ui/views/window/frame_background.h"

namespace {

constexpr int kBorderAlpha = 0x26;

}

void PaintRestoredFrameBorderLinux(gfx::Canvas& canvas,
                                   const views::View& view,
                                   views::FrameBackground* frame_background,
                                   const SkRRect& clip,
                                   bool showing_shadow,
                                   bool is_active,
                                   const gfx::Insets& border,
                                   const gfx::ShadowValues& shadow_values,
                                   bool tiled) {
  const auto* color_provider = view.GetColorProvider();
  if (frame_background) {
    gfx::ScopedCanvas scoped_canvas(&canvas);
    canvas.sk_canvas()->clipRRect(clip, SkClipOp::kIntersect, true);
    auto shadow_inset = showing_shadow ? border : gfx::Insets();
    frame_background->PaintMaximized(
        &canvas, view.GetNativeTheme(), color_provider, shadow_inset.left(),
        shadow_inset.top(), view.width() - shadow_inset.width());
    if (!showing_shadow) {
      frame_background->FillFrameBorders(&canvas, &view, border.left(),
                                         border.right(), border.bottom());
    }
  }

  // If rendering shadows, draw a 1px exterior border, otherwise draw a 1px
  // interior border.
  const SkScalar one_pixel = SkFloatToScalar(1 / canvas.image_scale());
  SkRRect outset_rect = clip;
  SkRRect inset_rect = clip;
  if (tiled) {
    outset_rect.outset(1, 1);
  } else if (showing_shadow) {
    outset_rect.outset(one_pixel, one_pixel);
  } else {
    inset_rect.inset(one_pixel, one_pixel);
  }

  cc::PaintFlags flags;
  const SkColor frame_color = color_provider->GetColor(
      is_active ? ui::kColorFrameActive : ui::kColorFrameInactive);
  const SkColor border_color =
      showing_shadow ? SK_ColorBLACK
                     : color_utils::PickContrastingColor(
                           SK_ColorBLACK, SK_ColorWHITE, frame_color);
  flags.setColor(SkColorSetA(border_color, kBorderAlpha));
  flags.setAntiAlias(true);
  if (showing_shadow) {
    flags.setLooper(gfx::CreateShadowDrawLooper(shadow_values));
  }

  gfx::ScopedCanvas scoped_canvas(&canvas);
  canvas.sk_canvas()->clipRRect(inset_rect, SkClipOp::kDifference, true);
  canvas.sk_canvas()->drawRRect(outset_rect, flags);
}

gfx::Insets GetRestoredFrameBorderInsetsLinux(
    bool showing_shadow,
    const gfx::Insets& default_border,
    const gfx::ShadowValues& shadow_values,
    const gfx::Insets& resize_border) {
  if (!showing_shadow) {
    auto no_shadow_border = default_border;
    no_shadow_border.set_top(0);
    return no_shadow_border;
  }

  // The border must be at least as large as the shadow.
  gfx::Rect frame_extents;
  for (const auto& shadow_value : shadow_values) {
    const auto shadow_radius = shadow_value.blur() / 4;
    const gfx::InsetsF shadow_insets(shadow_radius);
    gfx::RectF shadow_extents;
    shadow_extents.Inset(-shadow_insets);
    shadow_extents.set_origin(shadow_extents.origin() + shadow_value.offset());
    frame_extents.Union(gfx::ToEnclosingRect(shadow_extents));
  }

  // The border must be at least as large as the input region.
  const gfx::Insets insets(resize_border);
  gfx::Rect input_extents;
  input_extents.Inset(-insets);
  frame_extents.Union(input_extents);

  return gfx::Insets::TLBR(-frame_extents.y(), -frame_extents.x(),
                           frame_extents.bottom(), frame_extents.right());
}