Commit 70e20e22 authored by tdanderson's avatar tdanderson Committed by Commit bot

Move Ash-specific vector icons to ash/common/resources

Adds the initial plumbing needed in order to move
Ash-specific .icon files out of ui/gfx/vector_icons
and into ash/common/resources/vector_icons. As a
result, these icons will only be included when the
'ash' component is built.

Previously, the icon file foo_bar.icon would be
identified in code as the enum value
gfx::VectorIconId::FOO_BAR. For Ash-specific icons,
foo_bar.icon is now identified in code as the
constant ash::kFooBarIcon, which maps to a
VectorIcon struct (also introduced in this CL).
The eventual goal is for all icons to be identified
in this manner, and for the gfx::VectorIconId struct
to be removed.

BUG=626786
TEST=manual

Review-Url: https://codereview.chromium.org/2251643011
Cr-Commit-Position: refs/heads/master@{#415782}
parent 30f12cd9
......@@ -24,6 +24,7 @@ component("ash") {
public_deps = [
"//ash/common/strings",
"//ash/resources",
"//ash/resources/vector_icons",
]
deps = [
"//ash/autoclick/common:autoclick",
......
......@@ -2,6 +2,7 @@ include_rules = [
"-ash",
"+ash/ash_export.h",
"+ash/common",
"+ash/resources",
"+ash/shared",
"+ui",
"-ui/aura",
......
......@@ -20,6 +20,7 @@
#include "ash/common/system/tray/tray_utils.h"
#include "ash/common/system/tray_accessibility.h"
#include "ash/common/wm_shell.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "grit/ash_resources.h"
......@@ -30,7 +31,6 @@
#include "ui/gfx/font.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icons_public.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
......@@ -70,11 +70,10 @@ class SelectableHoverHighlightView : public HoverHighlightView {
class IMEDefaultView : public TrayItemMore {
public:
explicit IMEDefaultView(SystemTrayItem* owner, const base::string16& label)
IMEDefaultView(SystemTrayItem* owner, const base::string16& label)
: TrayItemMore(owner, true) {
if (MaterialDesignController::IsSystemTrayMenuMaterial()) {
SetImage(gfx::CreateVectorIcon(gfx::VectorIconId::SYSTEM_MENU_KEYBOARD,
kMenuIconColor));
SetImage(gfx::CreateVectorIcon(kSystemMenuKeyboardIcon, kMenuIconColor));
} else {
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
SetImage(*bundle.GetImageNamed(IDR_AURA_UBER_TRAY_IME).ToImageSkia());
......
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
action("aggregate_vector_icons") {
visibility = [ ":*" ]
script = "//ui/gfx/vector_icons/aggregate_vector_icons.py"
icons = [
"system_menu_keyboard.1x.icon",
"system_menu_keyboard.icon",
]
output_cc = "$target_gen_dir/vector_icons.cc"
output_h = "$target_gen_dir/vector_icons.h"
inputs = icons
inputs += [
"vector_icons.cc.template",
"vector_icons.h.template",
]
outputs = [
output_cc,
output_h,
]
response_file_contents = rebase_path(icons, root_build_dir)
args = [
"--working_directory=" + rebase_path("./"),
"--file_list={{response_file_name}}",
"--output_cc=" + rebase_path(output_cc, root_build_dir),
"--output_h=" + rebase_path(output_h, root_build_dir),
]
}
source_set("vector_icons") {
sources = get_target_outputs(":aggregate_vector_icons")
sources += [ "//ui/gfx/vector_icon_types.h" ]
deps = [
":aggregate_vector_icons",
"//base",
"//skia",
]
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// vector_icons.cc.template is used to generate vector_icons.cc. Edit the former
// rather than the latter.
#include "ash/resources/vector_icons/vector_icons.h"
#include "base/logging.h"
#include "ui/gfx/vector_icon_types.h"
#define PATH_ELEMENT_TEMPLATE(path_name, ...) \
static gfx::PathElement path_name[] = {__VA_ARGS__};
#define VECTOR_ICON_TEMPLATE(icon_name, path_name, path_name_1x) \
const gfx::VectorIcon icon_name = { path_name , path_name_1x };
namespace ash {
using namespace gfx;
TEMPLATE_PLACEHOLDER
} // namespace ash
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// vector_icons.h.template is used to generate vector_icons.h. Edit the former
// rather than the latter.
#ifndef ASH_RESOURCES_VECTOR_ICONS_VECTOR_ICONS_H_
#define ASH_RESOURCES_VECTOR_ICONS_VECTOR_ICONS_H_
namespace gfx {
struct VectorIcon;
}
#define VECTOR_ICON_TEMPLATE_H(icon_name) \
extern const gfx::VectorIcon icon_name;
namespace ash {
TEMPLATE_PLACEHOLDER
} // namespace ash
#endif // ASH_RESOURCES_VECTOR_ICONS_VECTOR_ICONS_H_
......@@ -311,25 +311,57 @@ void PaintPath(Canvas* canvas,
class VectorIconSource : public CanvasImageSource {
public:
VectorIconSource(VectorIconId id,
VectorIconSource(const VectorIcon& icon,
int dip_size,
SkColor color,
VectorIconId badge_id)
const VectorIcon& badge_icon)
: CanvasImageSource(gfx::Size(dip_size, dip_size), false),
color_(color),
icon_(icon),
badge_(badge_icon) {}
~VectorIconSource() override {}
// CanvasImageSource:
bool HasRepresentationAtAllScales() const override {
return !icon_.is_empty();
}
void Draw(gfx::Canvas* canvas) override {
PaintVectorIcon(canvas, icon_, size_.width(), color_);
if (!badge_.is_empty())
PaintVectorIcon(canvas, badge_, size_.width(), color_);
}
private:
const SkColor color_;
const VectorIcon& icon_;
const VectorIcon& badge_;
DISALLOW_COPY_AND_ASSIGN(VectorIconSource);
};
class VectorIconSourceLegacy : public CanvasImageSource {
public:
VectorIconSourceLegacy(VectorIconId id,
int dip_size,
SkColor color,
VectorIconId badge_id)
: CanvasImageSource(gfx::Size(dip_size, dip_size), false),
id_(id),
color_(color),
badge_id_(badge_id) {}
VectorIconSource(const std::string& definition,
int dip_size,
SkColor color)
VectorIconSourceLegacy(const std::string& definition,
int dip_size,
SkColor color)
: CanvasImageSource(gfx::Size(dip_size, dip_size), false),
id_(VectorIconId::VECTOR_ICON_NONE),
path_(PathFromSource(definition)),
color_(color),
badge_id_(VectorIconId::VECTOR_ICON_NONE) {}
~VectorIconSource() override {}
~VectorIconSourceLegacy() override {}
// CanvasImageSource:
bool HasRepresentationAtAllScales() const override {
......@@ -352,7 +384,7 @@ class VectorIconSource : public CanvasImageSource {
const SkColor color_;
const VectorIconId badge_id_;
DISALLOW_COPY_AND_ASSIGN(VectorIconSource);
DISALLOW_COPY_AND_ASSIGN(VectorIconSourceLegacy);
};
// This class caches vector icons (as ImageSkia) so they don't have to be drawn
......@@ -363,6 +395,58 @@ class VectorIconCache {
VectorIconCache() {}
~VectorIconCache() {}
ImageSkia GetOrCreateIcon(const VectorIcon& icon,
int dip_size,
SkColor color,
const VectorIcon& badge_icon) {
IconDescription description(&icon, dip_size, color, &badge_icon);
auto iter = images_.find(description);
if (iter != images_.end())
return iter->second;
ImageSkia icon_image(
new VectorIconSource(icon, dip_size, color, badge_icon),
gfx::Size(dip_size, dip_size));
images_.insert(std::make_pair(description, icon_image));
return icon_image;
}
private:
struct IconDescription {
IconDescription(const VectorIcon* icon,
int dip_size,
SkColor color,
const VectorIcon* badge_icon)
: icon(icon),
dip_size(dip_size),
color(color),
badge_icon(badge_icon) {}
bool operator<(const IconDescription& other) const {
return std::tie(icon, dip_size, color, badge_icon) <
std::tie(other.icon, other.dip_size, other.color,
other.badge_icon);
}
const gfx::VectorIcon* icon;
int dip_size;
SkColor color;
const gfx::VectorIcon* badge_icon;
};
std::map<IconDescription, ImageSkia> images_;
DISALLOW_COPY_AND_ASSIGN(VectorIconCache);
};
static base::LazyInstance<VectorIconCache> g_icon_cache =
LAZY_INSTANCE_INITIALIZER;
class VectorIconCacheLegacy {
public:
VectorIconCacheLegacy() {}
~VectorIconCacheLegacy() {}
ImageSkia GetOrCreateIcon(VectorIconId id,
int dip_size,
SkColor color,
......@@ -372,7 +456,7 @@ class VectorIconCache {
if (iter != images_.end())
return iter->second;
ImageSkia icon(new VectorIconSource(id, dip_size, color, badge_id),
ImageSkia icon(new VectorIconSourceLegacy(id, dip_size, color, badge_id),
gfx::Size(dip_size, dip_size));
images_.insert(std::make_pair(description, icon));
return icon;
......@@ -392,21 +476,23 @@ class VectorIconCache {
}
VectorIconId id;
size_t dip_size;
int dip_size;
SkColor color;
VectorIconId badge_id;
};
std::map<IconDescription, ImageSkia> images_;
DISALLOW_COPY_AND_ASSIGN(VectorIconCache);
DISALLOW_COPY_AND_ASSIGN(VectorIconCacheLegacy);
};
static base::LazyInstance<VectorIconCache> g_icon_cache =
static base::LazyInstance<VectorIconCacheLegacy> g_icon_cache_legacy =
LAZY_INSTANCE_INITIALIZER;
} // namespace
const VectorIcon kNoneIcon = {};
void PaintVectorIcon(Canvas* canvas,
VectorIconId id,
int dip_size,
......@@ -418,6 +504,17 @@ void PaintVectorIcon(Canvas* canvas,
PaintPath(canvas, path, dip_size, color);
}
void PaintVectorIcon(Canvas* canvas,
const VectorIcon& icon,
int dip_size,
SkColor color) {
DCHECK(!icon.is_empty());
const PathElement* path = (canvas->image_scale() == 1.f && icon.path_1x_)
? icon.path_1x_
: icon.path_;
PaintPath(canvas, path, dip_size, color);
}
ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) {
const PathElement* one_x_path = GetPathForVectorIconAt1xScale(id);
int size = (one_x_path[0].type == CANVAS_DIMENSIONS)
......@@ -426,27 +523,48 @@ ImageSkia CreateVectorIcon(VectorIconId id, SkColor color) {
return CreateVectorIcon(id, size, color);
}
ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color) {
const PathElement* one_x_path = icon.path_1x_ ? icon.path_1x_ : icon.path_;
int size = one_x_path[0].type == CANVAS_DIMENSIONS ? one_x_path[1].arg
: kReferenceSizeDip;
return CreateVectorIcon(icon, size, color);
}
ImageSkia CreateVectorIcon(VectorIconId id, int dip_size, SkColor color) {
return CreateVectorIconWithBadge(id, dip_size, color,
VectorIconId::VECTOR_ICON_NONE);
}
ImageSkia CreateVectorIcon(const VectorIcon& icon,
int dip_size,
SkColor color) {
return CreateVectorIconWithBadge(icon, dip_size, color, kNoneIcon);
}
ImageSkia CreateVectorIconWithBadge(VectorIconId id,
int dip_size,
SkColor color,
VectorIconId badge_id) {
return (id == VectorIconId::VECTOR_ICON_NONE)
? gfx::ImageSkia()
: g_icon_cache.Get().GetOrCreateIcon(id, dip_size, color,
badge_id);
: g_icon_cache_legacy.Get().GetOrCreateIcon(id, dip_size, color,
badge_id);
}
ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon,
int dip_size,
SkColor color,
const VectorIcon& badge_icon) {
return icon.is_empty() ? gfx::ImageSkia()
: g_icon_cache.Get().GetOrCreateIcon(
icon, dip_size, color, badge_icon);
}
ImageSkia CreateVectorIconFromSource(const std::string& source,
int dip_size,
SkColor color) {
return ImageSkia(
new VectorIconSource(source, dip_size, color),
gfx::Size(dip_size, dip_size));
return ImageSkia(new VectorIconSourceLegacy(source, dip_size, color),
gfx::Size(dip_size, dip_size));
}
} // namespace gfx
......@@ -12,8 +12,11 @@
namespace gfx {
class Canvas;
struct VectorIcon;
enum class VectorIconId;
GFX_EXPORT extern const VectorIcon kNoneIcon;
// Draws a vector icon identified by |id| onto |canvas| at (0, 0). |dip_size|
// is the length of a single edge of the square icon, in device independent
// pixels. |color| is used as the fill.
......@@ -21,16 +24,24 @@ GFX_EXPORT void PaintVectorIcon(Canvas* canvas,
VectorIconId id,
int dip_size,
SkColor color);
GFX_EXPORT void PaintVectorIcon(Canvas* canvas,
const VectorIcon& icon,
int dip_size,
SkColor color);
// Creates an ImageSkia which will render the icon on demand. The size will come
// from the .icon file (the 1x version, if multiple versions exist).
GFX_EXPORT ImageSkia CreateVectorIcon(VectorIconId id,
SkColor color);
GFX_EXPORT ImageSkia CreateVectorIcon(const VectorIcon& icon, SkColor color);
// As above, but creates the image at the given size.
GFX_EXPORT ImageSkia CreateVectorIcon(VectorIconId id,
int dip_size,
SkColor color);
GFX_EXPORT ImageSkia CreateVectorIcon(const VectorIcon& icon,
int dip_size,
SkColor color);
// As above, but also paints a badge defined by |badge_id| on top of the icon.
// The badge uses the same canvas size and default color as the icon.
......@@ -38,6 +49,10 @@ GFX_EXPORT ImageSkia CreateVectorIconWithBadge(VectorIconId id,
int dip_size,
SkColor color,
VectorIconId badge_id);
GFX_EXPORT ImageSkia CreateVectorIconWithBadge(const VectorIcon& icon,
int dip_size,
SkColor color,
const VectorIcon& badge_icon);
#if defined(GFX_VECTOR_ICONS_UNSAFE) || defined(GFX_IMPLEMENTATION)
// Takes a string of the format expected of .icon files and renders onto
......
......@@ -72,6 +72,17 @@ struct PathElement {
};
};
struct VectorIcon {
VectorIcon() : path_(nullptr), path_1x_(nullptr) {}
VectorIcon(gfx::PathElement* path, gfx::PathElement* path_1x)
: path_(path), path_1x_(path_1x) {}
bool is_empty() const { return !path_; }
gfx::PathElement* path_;
gfx::PathElement* path_1x_;
};
// Returns an array of path commands and arguments, terminated by END.
const PathElement* GetPathForVectorIcon(VectorIconId id);
// As above, but returns an icon specifically adjusted for 1x scale factors.
......
......@@ -171,8 +171,6 @@ action("aggregate_vector_icons") {
"system_menu_cast.icon",
"system_menu_child_user.1x.icon",
"system_menu_child_user.icon",
"system_menu_keyboard.1x.icon",
"system_menu_keyboard.icon",
"system_menu_rotation_lock_auto.1x.icon",
"system_menu_rotation_lock_auto.icon",
"system_menu_rotation_lock_locked.1x.icon",
......@@ -268,6 +266,7 @@ action("aggregate_vector_icons") {
"--file_list={{response_file_name}}",
"--output_cc=" + rebase_path(output_cc, root_build_dir),
"--output_h=" + rebase_path(output_h, root_build_dir),
"--use_legacy_template",
]
}
......
......@@ -7,20 +7,11 @@ import glob
import optparse
import os
import shlex
import sys
import textwrap
def AggregateVectorIcons(working_directory, file_list, output_cc, output_h):
"""Compiles all .icon files in a directory into two C++ files.
Args:
working_directory: The path to the directory that holds the .icon files
and C++ templates.
file_list: A file containing the list of vector icon files to process.
Used for GN only (this argument defaults to None for GYP).
output_cc: The path that should be used to write the .cc file.
output_h: The path that should be used to write the .h file.
"""
def AggregateVectorIconsLegacy(working_directory, file_list, output_cc,
output_h):
icon_list = []
if file_list is None:
# TODO(GYP_GONE): |file_list| is only None for GYP builds (where response
......@@ -79,6 +70,139 @@ def AggregateVectorIcons(working_directory, file_list, output_cc, output_h):
output_cc.close()
def Error(msg):
print >> sys.stderr, msg
sys.exit(1)
def CamelCase(name, suffix):
words = name.split('_')
words = [w.capitalize() for w in words]
return 'k' + ''.join(words) + suffix
def AggregateVectorIcons(working_directory, file_list, output_cc, output_h,
use_legacy_template):
"""Compiles all .icon files in a directory into two C++ files.
Args:
working_directory: The path to the directory that holds the .icon files
and C++ templates.
file_list: A file containing the list of vector icon files to process.
Used for GN only (this argument defaults to None for GYP).
output_cc: The path that should be used to write the .cc file.
output_h: The path that should be used to write the .h file.
use_legacy_template: If True, |output_cc| and |output_h| are generated
using .template files which make use of the VectorIconId enum.
"""
# TODO(tdanderson): Remove this code once all vector icons map to VectorIcon
# constants rather than VectorIconId values.
if use_legacy_template:
AggregateVectorIconsLegacy(working_directory, file_list, output_cc,
output_h)
return
# For each file in |file_list|, place it in |path_map| if its extension is
# .icon or place it in |path_map_1x| if its extension is .1x.icon. The
# two dictionaries map the icon's name to its path, e.g.,
# path_map['cat'] = 'foo/bar/cat.icon'.
icon_list = []
with open(file_list, 'r') as f:
file_list_contents = f.read()
icon_list = shlex.split(file_list_contents)
path_map = {}
path_map_1x = {}
for icon_path in icon_list:
(icon_name, extension) = os.path.splitext(os.path.basename(icon_path))
(icon_name, scale_factor) = os.path.splitext(icon_name)
if (scale_factor and scale_factor != ".1x") or (extension != ".icon"):
Error("Only filenames " + icon_name + ".icon or " + icon_name +
".1x.icon are allowed.")
if not scale_factor and icon_name not in path_map:
path_map[icon_name] = icon_path
elif scale_factor and icon_name not in path_map_1x:
path_map_1x[icon_name] = icon_path
else:
Error("A vector icon with name '" + icon_name + "' already exists.")
for icon_1x in path_map_1x:
if icon_1x not in path_map:
Error("The file " + icon_1x + ".icon must be provided.")
# Generate the file vector_icons.h which declares a variable for each
# icon in |path_map|. The variable name is derived from the icon name by
# converting to camel case, prepending 'k', and appending 'Icon'. For
# example, the icon 'foo_bar' will have the variable name kFooBarIcon.
input_header_template = open(os.path.join(working_directory,
"vector_icons.h.template"))
header_template_contents = input_header_template.readlines()
input_header_template.close()
output_header = open(output_h, "w")
for line in header_template_contents:
if not "TEMPLATE_PLACEHOLDER" in line:
output_header.write(line)
continue
for icon in path_map:
(icon_name, extension) = os.path.splitext(
os.path.basename(path_map[icon]))
(icon_name, scale_factor) = os.path.splitext(icon_name)
output_header.write(
"VECTOR_ICON_TEMPLATE_H({})\n".format(CamelCase(icon_name, "Icon")))
output_header.close()
# Copy the vector icon drawing commands from the .icon and .1x.icon files
# and use them to generate vector_icons.cc, which defines the variables
# declared in vector_icons.h.
input_cc_template = open(
os.path.join(working_directory, "vector_icons.cc.template"))
cc_template_contents = input_cc_template.readlines()
input_cc_template.close()
output_cc = open(output_cc, "w")
for line in cc_template_contents:
if not "TEMPLATE_PLACEHOLDER" in line:
output_cc.write(line)
continue;
for icon in path_map:
(icon_name, extension) = os.path.splitext(
os.path.basename(path_map[icon]))
(icon_name, scale_factor) = os.path.splitext(icon_name)
# Store the vector-drawing commands for foo_bar.icon in the temporary
# variable kFooBarPath.
icon_file = open(path_map[icon])
vector_commands = "".join(icon_file.readlines())
icon_file.close()
output_cc.write("PATH_ELEMENT_TEMPLATE({}, {})\n".format(
CamelCase(icon_name, "Path"), vector_commands))
# Store the vector-drawing commands for foo_bar.1x.icon in the temporary
# variable kFooBarPath1x, if the file exists.
vector_commands_1x = None
if (icon in path_map_1x):
icon_file = open(path_map_1x[icon])
vector_commands_1x = "".join(icon_file.readlines())
icon_file.close()
output_cc.write("PATH_ELEMENT_TEMPLATE({}, {})\n".format(
CamelCase(icon_name, "Path1x"), vector_commands_1x))
# Define the value of kFooBarIcon.
third_arg = "nullptr" if vector_commands_1x is None else CamelCase(
icon_name, "Path1x")
output_cc.write("VECTOR_ICON_TEMPLATE({}, {}, {})\n".format(CamelCase(
icon_name, "Icon"), CamelCase(icon_name, "Path"), third_arg))
output_cc.close()
def main():
parser = optparse.OptionParser()
parser.add_option("--working_directory",
......@@ -92,13 +216,20 @@ def main():
help="The path to output the CC file to.")
parser.add_option("--output_h",
help="The path to output the header file to.")
parser.add_option("--use_legacy_template",
action="store_true",
help="When set, the VectorIconId enum is populated "
"with values corresponding to .icon files in "
"the current working directory.",
default=False)
(options, args) = parser.parse_args()
AggregateVectorIcons(options.working_directory,
options.file_list,
options.output_cc,
options.output_h)
options.output_h,
options.use_legacy_template)
if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment