OLD | NEW |
(Empty) | |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 """Presubmit script for Chromium browser resources. |
| 6 |
| 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts |
| 8 for more details about the presubmit API built into gcl/git cl, and see |
| 9 http://www.chromium.org/developers/web-development-style-guide for the rules |
| 10 we're checking against here. |
| 11 """ |
| 12 |
| 13 |
| 14 import os |
| 15 import struct |
| 16 |
| 17 |
| 18 class ResourceScaleFactors(object): |
| 19 """Verifier of image dimensions for Chromium resources. |
| 20 |
| 21 This class verifies the image dimensions of resources in the various |
| 22 resource subdirectories. |
| 23 |
| 24 Attributes: |
| 25 paths: An array of tuples giving the folders to check and their |
| 26 relevant scale factors. For example: |
| 27 |
| 28 [(1, 'default_100_percent'), (2, 'default_200_percent')] |
| 29 """ |
| 30 |
| 31 def __init__(self, input_api, output_api, paths): |
| 32 """ Initializes ResourceScaleFactors with paths.""" |
| 33 self.input_api = input_api |
| 34 self.output_api = output_api |
| 35 self.paths = paths |
| 36 |
| 37 def RunChecks(self): |
| 38 """Verifies the scale factors of resources being added or modified. |
| 39 |
| 40 Returns: |
| 41 An array of presubmit errors if any images were detected not |
| 42 having the correct dimensions. |
| 43 """ |
| 44 def ImageSize(filename): |
| 45 with open(filename, 'rb', buffering=0) as f: |
| 46 data = f.read(24) |
| 47 assert data[:8] == '\x89PNG\r\n\x1A\n' and data[12:16] == 'IHDR' |
| 48 return struct.unpack('>ii', data[16:24]) |
| 49 |
| 50 # TODO(flackr): This should allow some flexibility for non-integer scale |
| 51 # factors such as allowing any size between the floor and ceiling of |
| 52 # base * scale. |
| 53 def ExpectedSize(base_width, base_height, scale): |
| 54 return round(base_width * scale), round(base_height * scale) |
| 55 |
| 56 repository_path = self.input_api.os_path.relpath( |
| 57 self.input_api.PresubmitLocalPath(), |
| 58 self.input_api.change.RepositoryRoot()) |
| 59 results = [] |
| 60 |
| 61 # Check for affected files in any of the paths specified. |
| 62 affected_files = self.input_api.AffectedFiles(include_deletes=False) |
| 63 files = [] |
| 64 for f in affected_files: |
| 65 for path_spec in self.paths: |
| 66 path_root = self.input_api.os_path.join( |
| 67 repository_path, path_spec[1]) |
| 68 if (f.LocalPath().endswith('.png') and |
| 69 f.LocalPath().startswith(path_root)): |
| 70 # Only save the relative path from the resource directory. |
| 71 relative_path = self.input_api.os_path.relpath(f.LocalPath(), |
| 72 path_root) |
| 73 if relative_path not in files: |
| 74 files.append(relative_path) |
| 75 |
| 76 for f in files: |
| 77 base_image = self.input_api.os_path.join(self.paths[0][1], f) |
| 78 if not os.path.exists(base_image): |
| 79 results.append(self.output_api.PresubmitError( |
| 80 'Base image %s does not exist' % self.input_api.os_path.join( |
| 81 repository_path, base_image))) |
| 82 continue |
| 83 base_width, base_height = ImageSize(base_image) |
| 84 # Find all scaled versions of the base image and verify their sizes. |
| 85 for i in range(1, len(self.paths)): |
| 86 image_path = self.input_api.os_path.join(self.paths[i][1], f) |
| 87 if not os.path.exists(image_path): |
| 88 continue |
| 89 # Ensure that each image for a particular scale factor is the |
| 90 # correct scale of the base image. |
| 91 exp_width, exp_height = ExpectedSize(base_width, base_height, |
| 92 self.paths[i][0]) |
| 93 width, height = ImageSize(image_path) |
| 94 if width != exp_width or height != exp_height: |
| 95 results.append(self.output_api.PresubmitError( |
| 96 'Image %s is %dx%d, expected to be %dx%d' % ( |
| 97 self.input_api.os_path.join(repository_path, image_path), |
| 98 width, height, exp_width, exp_height))) |
| 99 return results |
OLD | NEW |