File: pdf_transform.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 (129 lines) | stat: -rw-r--r-- 4,374 bytes parent folder | download | duplicates (9)
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
123
124
125
126
127
128
129
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "pdf/pdf_transform.h"

#include <algorithm>
#include <utility>

#include "base/notreached.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size_f.h"

namespace chrome_pdf {

namespace {

// When a PdfRectangle has top < bottom, or right < left, the values should be
// swapped.
void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
  if (rect->top < rect->bottom)
    std::swap(rect->top, rect->bottom);
  if (rect->right < rect->left)
    std::swap(rect->right, rect->left);
}

}  // namespace

float CalculateScaleFactor(const gfx::Rect& content_rect,
                           const gfx::SizeF& src_size,
                           bool rotated) {
  if (src_size.IsEmpty())
    return 1.0f;

  float actual_source_page_width =
      rotated ? src_size.height() : src_size.width();
  float actual_source_page_height =
      rotated ? src_size.width() : src_size.height();
  float ratio_x = content_rect.width() / actual_source_page_width;
  float ratio_y = content_rect.height() / actual_source_page_height;
  return std::min(ratio_x, ratio_y);
}

void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) {
  constexpr int kDpi = 72;
  constexpr float kPaperWidth = 8.5 * kDpi;
  constexpr float kPaperHeight = 11 * kDpi;
  clip_box->left = 0;
  clip_box->bottom = 0;
  clip_box->right = rotated ? kPaperHeight : kPaperWidth;
  clip_box->top = rotated ? kPaperWidth : kPaperHeight;
}

void CalculateMediaBoxAndCropBox(bool rotated,
                                 bool has_media_box,
                                 bool has_crop_box,
                                 PdfRectangle* media_box,
                                 PdfRectangle* crop_box) {
  if (has_media_box)
    SwapPdfRectangleValuesIfNeeded(media_box);
  if (has_crop_box)
    SwapPdfRectangleValuesIfNeeded(crop_box);

  if (!has_media_box && !has_crop_box) {
    SetDefaultClipBox(rotated, crop_box);
    SetDefaultClipBox(rotated, media_box);
  } else if (has_crop_box && !has_media_box) {
    *media_box = *crop_box;
  } else if (has_media_box && !has_crop_box) {
    *crop_box = *media_box;
  }
}

PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
                                      const PdfRectangle& crop_box) {
  PdfRectangle clip_box;

  // Clip `media_box` to the size of `crop_box`, but ignore `crop_box` if it is
  // bigger than `media_box`.
  clip_box.left = std::max(crop_box.left, media_box.left);
  clip_box.bottom = std::max(crop_box.bottom, media_box.bottom);
  clip_box.right = std::min(crop_box.right, media_box.right);
  clip_box.top = std::min(crop_box.top, media_box.top);
  return clip_box;
}

void ScalePdfRectangle(float scale_factor, PdfRectangle* rect) {
  rect->left *= scale_factor;
  rect->bottom *= scale_factor;
  rect->right *= scale_factor;
  rect->top *= scale_factor;
}

gfx::PointF CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
                                         const PdfRectangle& source_clip_box) {
  const float clip_box_width = source_clip_box.right - source_clip_box.left;
  const float clip_box_height = source_clip_box.top - source_clip_box.bottom;

  // Center the intended clip region to real clip region.
  return gfx::PointF((content_rect.width() - clip_box_width) / 2 +
                         content_rect.x() - source_clip_box.left,
                     (content_rect.height() - clip_box_height) / 2 +
                         content_rect.y() - source_clip_box.bottom);
}

gfx::PointF CalculateNonScaledClipBoxOffset(
    int rotation,
    int page_width,
    int page_height,
    const PdfRectangle& source_clip_box) {
  // Align the intended clip region to left-top corner of real clip region.
  switch (rotation) {
    case 0:
      return gfx::PointF(-1 * source_clip_box.left,
                         page_height - source_clip_box.top);
    case 1:
      return gfx::PointF(0, -1 * source_clip_box.bottom);
    case 2:
      return gfx::PointF(page_width - source_clip_box.right, 0);
    case 3:
      return gfx::PointF(page_height - source_clip_box.right,
                         page_width - source_clip_box.top);
    default:
      NOTREACHED();
  }
}

}  // namespace chrome_pdf