commit
64622ceae3
20 changed files with 499 additions and 195 deletions
5
atom.gyp
5
atom.gyp
|
@ -38,6 +38,7 @@
|
|||
'atom/common/api/lib/clipboard.coffee',
|
||||
'atom/common/api/lib/crash-reporter.coffee',
|
||||
'atom/common/api/lib/id-weak-map.coffee',
|
||||
'atom/common/api/lib/native-image.coffee',
|
||||
'atom/common/api/lib/original-fs.coffee',
|
||||
'atom/common/api/lib/shell.coffee',
|
||||
'atom/common/lib/init.coffee',
|
||||
|
@ -204,6 +205,9 @@
|
|||
'atom/common/api/atom_api_crash_reporter.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.cc',
|
||||
'atom/common/api/atom_api_id_weak_map.h',
|
||||
'atom/common/api/atom_api_native_image.cc',
|
||||
'atom/common/api/atom_api_native_image.h',
|
||||
'atom/common/api/atom_api_native_image_mac.mm',
|
||||
'atom/common/api/atom_api_shell.cc',
|
||||
'atom/common/api/atom_api_v8_util.cc',
|
||||
'atom/common/api/atom_bindings.cc',
|
||||
|
@ -242,7 +246,6 @@
|
|||
'atom/common/native_mate_converters/gurl_converter.h',
|
||||
'atom/common/native_mate_converters/image_converter.cc',
|
||||
'atom/common/native_mate_converters/image_converter.h',
|
||||
'atom/common/native_mate_converters/image_converter_mac.mm',
|
||||
'atom/common/native_mate_converters/string16_converter.h',
|
||||
'atom/common/native_mate_converters/v8_value_converter.cc',
|
||||
'atom/common/native_mate_converters/v8_value_converter.h',
|
||||
|
|
|
@ -52,15 +52,11 @@ namespace {
|
|||
|
||||
void OnCapturePageDone(
|
||||
v8::Isolate* isolate,
|
||||
const base::Callback<void(v8::Handle<v8::Value>)>& callback,
|
||||
const base::Callback<void(const gfx::Image&)>& callback,
|
||||
const std::vector<unsigned char>& data) {
|
||||
v8::Locker locker(isolate);
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
v8::Local<v8::Value> buffer = node::Buffer::New(
|
||||
reinterpret_cast<const char*>(data.data()),
|
||||
data.size());
|
||||
callback.Run(buffer);
|
||||
callback.Run(gfx::Image::CreateFrom1xPNGBytes(&data.front(), data.size()));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -374,7 +370,7 @@ bool Window::IsDocumentEdited() {
|
|||
|
||||
void Window::CapturePage(mate::Arguments* args) {
|
||||
gfx::Rect rect;
|
||||
base::Callback<void(v8::Handle<v8::Value>)> callback;
|
||||
base::Callback<void(const gfx::Image&)> callback;
|
||||
|
||||
if (!(args->Length() == 1 && args->GetNext(&callback)) &&
|
||||
!(args->Length() == 2 && args->GetNext(&rect)
|
||||
|
|
|
@ -54,13 +54,11 @@ TrayIconCocoa::~TrayIconCocoa() {
|
|||
}
|
||||
|
||||
void TrayIconCocoa::SetImage(const gfx::Image& image) {
|
||||
if (!image.IsEmpty())
|
||||
[item_ setImage:image.ToNSImage()];
|
||||
[item_ setImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetPressedImage(const gfx::Image& image) {
|
||||
if (!image.IsEmpty())
|
||||
[item_ setAlternateImage:image.ToNSImage()];
|
||||
[item_ setAlternateImage:image.AsNSImage()];
|
||||
}
|
||||
|
||||
void TrayIconCocoa::SetToolTip(const std::string& tool_tip) {
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
#include "atom/common/native_mate_converters/string16_converter.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/clipboard/clipboard.h"
|
||||
#include "ui/base/clipboard/scoped_clipboard_writer.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
|
@ -16,8 +19,7 @@ namespace mate {
|
|||
|
||||
template<>
|
||||
struct Converter<ui::ClipboardType> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
|
||||
ui::ClipboardType* out) {
|
||||
std::string type;
|
||||
if (!Converter<std::string>::FromV8(isolate, val, &type))
|
||||
|
@ -62,6 +64,11 @@ void WriteText(const base::string16& text, ui::ClipboardType type) {
|
|||
writer.WriteText(text);
|
||||
}
|
||||
|
||||
gfx::Image ReadImage(ui::ClipboardType type) {
|
||||
SkBitmap bitmap = ui::Clipboard::GetForCurrentThread()->ReadImage(type);
|
||||
return gfx::Image::CreateFrom1xBitmap(bitmap);
|
||||
}
|
||||
|
||||
void Clear(ui::ClipboardType type) {
|
||||
ui::Clipboard::GetForCurrentThread()->Clear(type);
|
||||
}
|
||||
|
@ -73,6 +80,7 @@ void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
|||
dict.SetMethod("_read", &Read);
|
||||
dict.SetMethod("_readText", &ReadText);
|
||||
dict.SetMethod("_writeText", &WriteText);
|
||||
dict.SetMethod("_readImage", &ReadImage);
|
||||
dict.SetMethod("_clear", &Clear);
|
||||
}
|
||||
|
||||
|
|
266
atom/common/api/atom_api_native_image.cc
Normal file
266
atom/common/api/atom_api_native_image.cc
Normal file
|
@ -0,0 +1,266 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "atom/common/native_mate_converters/gfx_converter.h"
|
||||
#include "atom/common/native_mate_converters/gurl_converter.h"
|
||||
#include "base/base64.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "native_mate/object_template_builder.h"
|
||||
#include "net/base/data_url.h"
|
||||
#include "ui/base/layout.h"
|
||||
#include "ui/gfx/codec/jpeg_codec.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/geometry/size.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/gfx/image/image_util.h"
|
||||
|
||||
#include "atom/common/node_includes.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
namespace {
|
||||
|
||||
struct ScaleFactorPair {
|
||||
const char* name;
|
||||
float scale;
|
||||
};
|
||||
|
||||
ScaleFactorPair kScaleFactorPairs[] = {
|
||||
// The "@2x" is put as first one to make scale matching faster.
|
||||
{ "@2x" , 2.0f },
|
||||
{ "@3x" , 3.0f },
|
||||
{ "@1x" , 1.0f },
|
||||
{ "@4x" , 4.0f },
|
||||
{ "@5x" , 5.0f },
|
||||
{ "@1.25x" , 1.25f },
|
||||
{ "@1.33x" , 1.33f },
|
||||
{ "@1.4x" , 1.4f },
|
||||
{ "@1.5x" , 1.5f },
|
||||
{ "@1.8x" , 1.8f },
|
||||
{ "@2.5x" , 2.5f },
|
||||
};
|
||||
|
||||
float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
|
||||
// We don't try to convert string to float here because it is very very
|
||||
// expensive.
|
||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
||||
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
|
||||
return kScaleFactorPairs[i].scale;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const unsigned char* data,
|
||||
size_t size,
|
||||
double scale_factor) {
|
||||
scoped_ptr<SkBitmap> decoded(new SkBitmap());
|
||||
|
||||
// Try PNG first.
|
||||
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
|
||||
// Try JPEG.
|
||||
decoded.reset(gfx::JPEGCodec::Decode(data, size));
|
||||
|
||||
if (!decoded)
|
||||
return false;
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const base::FilePath& path,
|
||||
double scale_factor) {
|
||||
std::string file_contents;
|
||||
if (!base::ReadFileToString(path, &file_contents))
|
||||
return false;
|
||||
|
||||
const unsigned char* data =
|
||||
reinterpret_cast<const unsigned char*>(file_contents.data());
|
||||
size_t size = file_contents.size();
|
||||
return AddImageSkiaRep(image, data, size, scale_factor);
|
||||
}
|
||||
|
||||
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path) {
|
||||
bool succeed = false;
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
if (MatchPattern(filename, "*@*x"))
|
||||
// Don't search for other representations if the DPI has been specified.
|
||||
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
|
||||
else
|
||||
succeed |= AddImageSkiaRep(image, path, 1.0f);
|
||||
|
||||
for (const ScaleFactorPair& pair : kScaleFactorPairs)
|
||||
succeed |= AddImageSkiaRep(image,
|
||||
path.InsertBeforeExtensionASCII(pair.name),
|
||||
pair.scale);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
bool IsTemplateImage(const base::FilePath& path) {
|
||||
return (MatchPattern(path.value(), "*Template.*") ||
|
||||
MatchPattern(path.value(), "*Template@*x.*"));
|
||||
}
|
||||
#endif
|
||||
|
||||
v8::Persistent<v8::ObjectTemplate> template_;
|
||||
|
||||
} // namespace
|
||||
|
||||
NativeImage::NativeImage() {}
|
||||
|
||||
NativeImage::NativeImage(const gfx::Image& image) : image_(image) {}
|
||||
|
||||
NativeImage::~NativeImage() {}
|
||||
|
||||
mate::ObjectTemplateBuilder NativeImage::GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) {
|
||||
if (template_.IsEmpty())
|
||||
template_.Reset(isolate, mate::ObjectTemplateBuilder(isolate)
|
||||
.SetMethod("toPng", &NativeImage::ToPNG)
|
||||
.SetMethod("toJpeg", &NativeImage::ToJPEG)
|
||||
.SetMethod("toDataUrl", &NativeImage::ToDataURL)
|
||||
.SetMethod("isEmpty", &NativeImage::IsEmpty)
|
||||
.SetMethod("getSize", &NativeImage::GetSize)
|
||||
.Build());
|
||||
|
||||
return mate::ObjectTemplateBuilder(
|
||||
isolate, v8::Local<v8::ObjectTemplate>::New(isolate, template_));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> NativeImage::ToPNG(v8::Isolate* isolate) {
|
||||
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
|
||||
return node::Buffer::New(isolate,
|
||||
reinterpret_cast<const char*>(png->front()),
|
||||
png->size());
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> NativeImage::ToJPEG(v8::Isolate* isolate, int quality) {
|
||||
std::vector<unsigned char> output;
|
||||
gfx::JPEG1xEncodedDataFromImage(image_, quality, &output);
|
||||
return node::Buffer::New(isolate,
|
||||
reinterpret_cast<const char*>(&output.front()),
|
||||
output.size());
|
||||
}
|
||||
|
||||
std::string NativeImage::ToDataURL() {
|
||||
scoped_refptr<base::RefCountedMemory> png = image_.As1xPNGBytes();
|
||||
std::string data_url;
|
||||
data_url.insert(data_url.end(), png->front(), png->front() + png->size());
|
||||
base::Base64Encode(data_url, &data_url);
|
||||
data_url.insert(0, "data:image/png;base64,");
|
||||
return data_url;
|
||||
}
|
||||
|
||||
bool NativeImage::IsEmpty() {
|
||||
return image_.IsEmpty();
|
||||
}
|
||||
|
||||
gfx::Size NativeImage::GetSize() {
|
||||
return image_.Size();
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateEmpty(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new NativeImage);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::Create(
|
||||
v8::Isolate* isolate, const gfx::Image& image) {
|
||||
return mate::CreateHandle(isolate, new NativeImage(image));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromPNG(
|
||||
v8::Isolate* isolate, const char* buffer, size_t length) {
|
||||
gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
|
||||
reinterpret_cast<const unsigned char*>(buffer), length);
|
||||
return Create(isolate, image);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromJPEG(
|
||||
v8::Isolate* isolate, const char* buffer, size_t length) {
|
||||
gfx::Image image = gfx::ImageFrom1xJPEGEncodedData(
|
||||
reinterpret_cast<const unsigned char*>(buffer), length);
|
||||
return Create(isolate, image);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromPath(
|
||||
v8::Isolate* isolate, const base::FilePath& path) {
|
||||
gfx::ImageSkia image_skia;
|
||||
PopulateImageSkiaRepsFromPath(&image_skia, path);
|
||||
gfx::Image image(image_skia);
|
||||
#if defined(OS_MACOSX)
|
||||
if (IsTemplateImage(path))
|
||||
MakeTemplateImage(&image);
|
||||
#endif
|
||||
return Create(isolate, image);
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromBuffer(
|
||||
mate::Arguments* args, v8::Handle<v8::Value> buffer) {
|
||||
double scale_factor = 1.;
|
||||
args->GetNext(&scale_factor);
|
||||
|
||||
gfx::ImageSkia image_skia;
|
||||
AddImageSkiaRep(&image_skia,
|
||||
reinterpret_cast<unsigned char*>(node::Buffer::Data(buffer)),
|
||||
node::Buffer::Length(buffer),
|
||||
scale_factor);
|
||||
return Create(args->isolate(), gfx::Image(image_skia));
|
||||
}
|
||||
|
||||
// static
|
||||
mate::Handle<NativeImage> NativeImage::CreateFromDataURL(
|
||||
v8::Isolate* isolate, const GURL& url) {
|
||||
std::string mime_type, charset, data;
|
||||
if (net::DataURL::Parse(url, &mime_type, &charset, &data)) {
|
||||
if (mime_type == "image/png")
|
||||
return CreateFromPNG(isolate, data.c_str(), data.size());
|
||||
else if (mime_type == "image/jpeg")
|
||||
return CreateFromJPEG(isolate, data.c_str(), data.size());
|
||||
}
|
||||
|
||||
return CreateEmpty(isolate);
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void Initialize(v8::Handle<v8::Object> exports, v8::Handle<v8::Value> unused,
|
||||
v8::Handle<v8::Context> context, void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("createEmpty", &atom::api::NativeImage::CreateEmpty);
|
||||
dict.SetMethod("createFromPath", &atom::api::NativeImage::CreateFromPath);
|
||||
dict.SetMethod("createFromBuffer", &atom::api::NativeImage::CreateFromBuffer);
|
||||
dict.SetMethod("createFromDataUrl",
|
||||
&atom::api::NativeImage::CreateFromDataURL);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_native_image, Initialize)
|
82
atom/common/api/atom_api_native_image.h
Normal file
82
atom/common/api/atom_api_native_image.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
|
||||
#define ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
class GURL;
|
||||
|
||||
namespace base {
|
||||
class FilePath;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class Size;
|
||||
}
|
||||
|
||||
namespace mate {
|
||||
class Arguments;
|
||||
}
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
class NativeImage : public mate::Wrappable {
|
||||
public:
|
||||
static mate::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate);
|
||||
static mate::Handle<NativeImage> Create(
|
||||
v8::Isolate* isolate, const gfx::Image& image);
|
||||
static mate::Handle<NativeImage> CreateFromPNG(
|
||||
v8::Isolate* isolate, const char* buffer, size_t length);
|
||||
static mate::Handle<NativeImage> CreateFromJPEG(
|
||||
v8::Isolate* isolate, const char* buffer, size_t length);
|
||||
static mate::Handle<NativeImage> CreateFromPath(
|
||||
v8::Isolate* isolate, const base::FilePath& path);
|
||||
static mate::Handle<NativeImage> CreateFromBuffer(
|
||||
mate::Arguments* args, v8::Handle<v8::Value> buffer);
|
||||
static mate::Handle<NativeImage> CreateFromDataURL(
|
||||
v8::Isolate* isolate, const GURL& url);
|
||||
|
||||
// The default constructor should only be used by image_converter.cc.
|
||||
NativeImage();
|
||||
|
||||
const gfx::Image& image() const { return image_; }
|
||||
|
||||
protected:
|
||||
explicit NativeImage(const gfx::Image& image);
|
||||
virtual ~NativeImage();
|
||||
|
||||
// mate::Wrappable:
|
||||
mate::ObjectTemplateBuilder GetObjectTemplateBuilder(
|
||||
v8::Isolate* isolate) override;
|
||||
|
||||
private:
|
||||
#if defined(OS_MACOSX)
|
||||
// Mark the image as template image if possible.
|
||||
static void MakeTemplateImage(gfx::Image* image);
|
||||
#endif
|
||||
|
||||
v8::Handle<v8::Value> ToPNG(v8::Isolate* isolate);
|
||||
v8::Handle<v8::Value> ToJPEG(v8::Isolate* isolate, int quality);
|
||||
std::string ToDataURL();
|
||||
bool IsEmpty();
|
||||
gfx::Size GetSize();
|
||||
|
||||
gfx::Image image_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeImage);
|
||||
};
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
||||
|
||||
#endif // ATOM_COMMON_API_ATOM_API_NATIVE_IMAGE_H_
|
20
atom/common/api/atom_api_native_image_mac.mm
Normal file
20
atom/common/api/atom_api_native_image_mac.mm
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace atom {
|
||||
|
||||
namespace api {
|
||||
|
||||
// static
|
||||
void NativeImage::MakeTemplateImage(gfx::Image* image) {
|
||||
[image->AsNSImage() setTemplate:YES];
|
||||
}
|
||||
|
||||
} // namespace api
|
||||
|
||||
} // namespace atom
|
|
@ -9,4 +9,5 @@ else
|
|||
read: (format, type='standard') -> binding._read format, type
|
||||
readText: (type='standard') -> binding._readText type
|
||||
writeText: (text, type='standard') -> binding._writeText text, type
|
||||
readImage: (type='standard') -> binding._readImage type
|
||||
clear: (type='standard') -> binding._clear type
|
||||
|
|
1
atom/common/api/lib/native-image.coffee
Normal file
1
atom/common/api/lib/native-image.coffee
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = process.atomBinding 'native_image'
|
|
@ -4,124 +4,48 @@
|
|||
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/common/api/atom_api_native_image.h"
|
||||
#include "atom/common/native_mate_converters/file_path_converter.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "ui/gfx/codec/jpeg_codec.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/base/layout.h"
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
namespace mate {
|
||||
|
||||
namespace {
|
||||
|
||||
struct ScaleFactorPair {
|
||||
const char* name;
|
||||
float scale;
|
||||
};
|
||||
|
||||
ScaleFactorPair kScaleFactorPairs[] = {
|
||||
// The "@2x" is put as first one to make scale matching faster.
|
||||
{ "@2x" , 2.0f },
|
||||
{ "@3x" , 3.0f },
|
||||
{ "@1x" , 1.0f },
|
||||
{ "@4x" , 4.0f },
|
||||
{ "@5x" , 5.0f },
|
||||
{ "@1.25x" , 1.25f },
|
||||
{ "@1.33x" , 1.33f },
|
||||
{ "@1.4x" , 1.4f },
|
||||
{ "@1.5x" , 1.5f },
|
||||
{ "@1.8x" , 1.8f },
|
||||
{ "@2.5x" , 2.5f },
|
||||
};
|
||||
|
||||
float GetScaleFactorFromPath(const base::FilePath& path) {
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
|
||||
// We don't try to convert string to float here because it is very very
|
||||
// expensive.
|
||||
for (unsigned i = 0; i < arraysize(kScaleFactorPairs); ++i) {
|
||||
if (EndsWith(filename, kScaleFactorPairs[i].name, true))
|
||||
return kScaleFactorPairs[i].scale;
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
bool AddImageSkiaRep(gfx::ImageSkia* image,
|
||||
const base::FilePath& path,
|
||||
double scale_factor) {
|
||||
std::string file_contents;
|
||||
if (!base::ReadFileToString(path, &file_contents))
|
||||
return false;
|
||||
|
||||
const unsigned char* data =
|
||||
reinterpret_cast<const unsigned char*>(file_contents.data());
|
||||
size_t size = file_contents.size();
|
||||
scoped_ptr<SkBitmap> decoded(new SkBitmap());
|
||||
|
||||
// Try PNG first.
|
||||
if (!gfx::PNGCodec::Decode(data, size, decoded.get()))
|
||||
// Try JPEG.
|
||||
decoded.reset(gfx::JPEGCodec::Decode(data, size));
|
||||
|
||||
if (!decoded)
|
||||
return false;
|
||||
|
||||
image->AddRepresentation(gfx::ImageSkiaRep(*decoded.release(), scale_factor));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PopulateImageSkiaRepsFromPath(gfx::ImageSkia* image,
|
||||
const base::FilePath& path) {
|
||||
bool succeed = false;
|
||||
std::string filename(path.BaseName().RemoveExtension().AsUTF8Unsafe());
|
||||
if (MatchPattern(filename, "*@*x"))
|
||||
// Don't search for other representations if the DPI has been specified.
|
||||
return AddImageSkiaRep(image, path, GetScaleFactorFromPath(path));
|
||||
else
|
||||
succeed |= AddImageSkiaRep(image, path, 1.0f);
|
||||
|
||||
for (const ScaleFactorPair& pair : kScaleFactorPairs)
|
||||
succeed |= AddImageSkiaRep(image,
|
||||
path.InsertBeforeExtensionASCII(pair.name),
|
||||
pair.scale);
|
||||
return succeed;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::ImageSkia* out) {
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
base::FilePath path;
|
||||
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
|
||||
gfx::Image image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
|
||||
return PopulateImageSkiaRepsFromPath(out, path);
|
||||
*out = image.AsImageSkia();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out) {
|
||||
gfx::ImageSkia image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
*out = gfx::Image(image);
|
||||
Handle<atom::api::NativeImage> native_image;
|
||||
if (!ConvertFromV8(isolate, val, &native_image)) {
|
||||
// Try converting from file path.
|
||||
base::FilePath path;
|
||||
if (!Converter<base::FilePath>::FromV8(isolate, val, &path))
|
||||
return false;
|
||||
|
||||
native_image = atom::api::NativeImage::CreateFromPath(isolate, path);
|
||||
if (native_image->image().IsEmpty())
|
||||
return false;
|
||||
}
|
||||
|
||||
*out = native_image->image();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
v8::Handle<v8::Value> Converter<gfx::Image>::ToV8(v8::Isolate* isolate,
|
||||
const gfx::Image& val) {
|
||||
return ConvertToV8(isolate, atom::api::NativeImage::Create(isolate, val));
|
||||
}
|
||||
|
||||
#endif // !defined(OS_MACOSX)
|
||||
} // namespace mate
|
||||
|
|
|
@ -26,6 +26,8 @@ struct Converter<gfx::Image> {
|
|||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out);
|
||||
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const gfx::Image& val);
|
||||
};
|
||||
|
||||
} // namespace mate
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) 2015 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "atom/common/native_mate_converters/image_converter.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "base/mac/foundation_util.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsTemplateImage(const std::string& path) {
|
||||
return (MatchPattern(path, "*Template.*") ||
|
||||
MatchPattern(path, "*Template@*x.*"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace mate {
|
||||
|
||||
bool Converter<gfx::ImageSkia>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::ImageSkia* out) {
|
||||
gfx::Image image;
|
||||
if (!ConvertFromV8(isolate, val, &image))
|
||||
return false;
|
||||
|
||||
*out = image.AsImageSkia();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Converter<gfx::Image>::FromV8(v8::Isolate* isolate,
|
||||
v8::Handle<v8::Value> val,
|
||||
gfx::Image* out) {
|
||||
if (val->IsNull())
|
||||
return true;
|
||||
|
||||
std::string path;
|
||||
if (!ConvertFromV8(isolate, val, &path))
|
||||
return false;
|
||||
|
||||
base::scoped_nsobject<NSImage> image([[NSImage alloc]
|
||||
initByReferencingFile:base::SysUTF8ToNSString(path)]);
|
||||
if (![image isValid])
|
||||
return false;
|
||||
|
||||
if (IsTemplateImage(path))
|
||||
[image setTemplate:YES];
|
||||
|
||||
*out = gfx::Image(image.release());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mate
|
|
@ -72,6 +72,7 @@ REFERENCE_MODULE(atom_common_asar);
|
|||
REFERENCE_MODULE(atom_common_clipboard);
|
||||
REFERENCE_MODULE(atom_common_crash_reporter);
|
||||
REFERENCE_MODULE(atom_common_id_weak_map);
|
||||
REFERENCE_MODULE(atom_common_native_image);
|
||||
REFERENCE_MODULE(atom_common_screen);
|
||||
REFERENCE_MODULE(atom_common_shell);
|
||||
REFERENCE_MODULE(atom_common_v8_util);
|
||||
|
|
|
@ -46,6 +46,7 @@ Modules for both sides:
|
|||
|
||||
* [clipboard](api/clipboard.md)
|
||||
* [crash-reporter](api/crash-reporter.md)
|
||||
* [native-image](api/native-image.md)
|
||||
* [screen](api/screen.md)
|
||||
* [shell](api/shell.md)
|
||||
|
||||
|
|
|
@ -43,13 +43,13 @@ You can also create a window without chrome by using
|
|||
other windows
|
||||
* `fullscreen` Boolean - Whether the window should show in fullscreen, when
|
||||
set to `false` the fullscreen button would also be hidden on OS X
|
||||
* `skip-taskbar` Boolean - Do not show window in taskbar
|
||||
* `skip-taskbar` Boolean - Do not show window in Taskbar
|
||||
* `zoom-factor` Number - The default zoom factor of the page, zoom factor is
|
||||
zoom percent / 100, so `3.0` represents `300%`
|
||||
* `kiosk` Boolean - The kiosk mode
|
||||
* `title` String - Default window title
|
||||
* `icon` [Image](image.md) - The window icon, when omitted on Windows the
|
||||
executable's icon would be used as window icon
|
||||
* `icon` [NativeImage](native-image.md) - The window icon, when omitted on
|
||||
Windows the executable's icon would be used as window icon
|
||||
* `show` Boolean - Whether window should be shown when created
|
||||
* `frame` Boolean - Specify `false` to create a
|
||||
[Frameless Window](frameless-window.md)
|
||||
|
@ -415,7 +415,7 @@ Starts or stops flashing the window to attract user's attention.
|
|||
|
||||
* `skip` Boolean
|
||||
|
||||
Makes the window do not show in taskbar.
|
||||
Makes the window do not show in Taskbar.
|
||||
|
||||
### BrowserWindow.setKiosk(flag)
|
||||
|
||||
|
@ -545,8 +545,11 @@ it will assume `app.getName().desktop`.
|
|||
|
||||
### BrowserWindow.setOverlayIcon(overlay, description)
|
||||
|
||||
* `overlay` [Image](image.md) - the icon to display on the bottom right corner of the Taskbar icon. If this parameter is `null`, the overlay is cleared.
|
||||
* `description` String - a description that will be provided to Accessibility screenreaders
|
||||
* `overlay` [NativeImage](native-image.md) - the icon to display on the bottom
|
||||
right corner of the Taskbar icon. If this parameter is `null`, the overlay is
|
||||
cleared
|
||||
* `description` String - a description that will be provided to Accessibility
|
||||
screen readers
|
||||
|
||||
Sets a 16px overlay onto the current Taskbar icon, usually used to convey some sort of application status or to passively notify the user.
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ would be passed via `callback(filename)`
|
|||
* `title` String - Title of the message box, some platforms will not show it
|
||||
* `message` String - Content of the message box
|
||||
* `detail` String - Extra information of the message
|
||||
* `icon` [Image](image.md)
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
* `callback` Function
|
||||
|
||||
Shows a message box, it will block until the message box is closed. It returns
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Image
|
||||
# NativeImage
|
||||
|
||||
In atom-shell images are represented by their file paths, we currently do not
|
||||
support in-memory images or remote images.
|
||||
In atom-shell for the APIs that take images, you can pass either file paths or
|
||||
`NativeImage` instances. When passing `null`, an empty image will be used.
|
||||
|
||||
For example when creating tray or setting window's icon, you can pass image's
|
||||
file path as `String` to represent an image:
|
||||
|
@ -11,12 +11,18 @@ var appIcon = new Tray('/Users/somebody/images/icon.png');
|
|||
var window = new BrowserWindow({icon: '/Users/somebody/images/window.png'});
|
||||
```
|
||||
|
||||
Or read the image from clipboard:
|
||||
|
||||
```javascript
|
||||
var clipboard = require('clipboard');
|
||||
var image = clipboard.readImage();
|
||||
var appIcon = new Tray(image);
|
||||
```
|
||||
|
||||
## Supported formats
|
||||
|
||||
On Mac all formats supported by the system can be used, while on Linux and
|
||||
Windows only `PNG` and `JPG` formats are supported.
|
||||
|
||||
So it is recommended to use `PNG` images for all cases.
|
||||
Currently `PNG` and `JPEG` are supported, and it is recommended to use `PNG`
|
||||
because it supports alpha channel and image is usually not compressed.
|
||||
|
||||
## High resolution image
|
||||
|
||||
|
@ -73,3 +79,55 @@ To mark an image as template image, its filename should end with the word
|
|||
|
||||
* `xxxTemplate.png`
|
||||
* `xxxTemplate@2x.png`
|
||||
|
||||
## nativeImage.createEmpty()
|
||||
|
||||
Creates an empty `NativeImage` instance.
|
||||
|
||||
## nativeImage.createFromPath(path)
|
||||
|
||||
* `path` String
|
||||
|
||||
Creates a new `NativeImage` instance from file located at `path`.
|
||||
|
||||
## nativeImage.createFromBuffer(buffer[, scaleFactor])
|
||||
|
||||
* `buffer` [Buffer][buffer]
|
||||
* `scaleFactor` Double
|
||||
|
||||
Creates a new `NativeImage` instance from `buffer`. The `scaleFactor` is 1.0 by
|
||||
default.
|
||||
|
||||
## nativeImage.createFromDataUrl(dataUrl)
|
||||
|
||||
* `dataUrl` String
|
||||
|
||||
Creates a new `NativeImage` instance from `dataUrl`.
|
||||
|
||||
## Class: NativeImage
|
||||
|
||||
This class is used to represent an image.
|
||||
|
||||
### NativeImage.toPng()
|
||||
|
||||
Returns a [Buffer][buffer] that contains image's `PNG` encoded data.
|
||||
|
||||
### NativeImage.toJpeg(quality)
|
||||
|
||||
* `quality` Integer
|
||||
|
||||
Returns a [Buffer][buffer] that contains image's `JPEG` encoded data.
|
||||
|
||||
### NativeImage.toDataUrl()
|
||||
|
||||
Returns the data URL of image.
|
||||
|
||||
### NativeImage.isEmpty()
|
||||
|
||||
Returns whether the image is empty.
|
||||
|
||||
### NativeImage.getSize()
|
||||
|
||||
Returns the size of the image.
|
||||
|
||||
[buffer]: https://iojs.org/api/buffer.html#buffer_class_buffer
|
|
@ -40,7 +40,7 @@ rely on `clicked` event and always attach a context menu to the tray icon.
|
|||
|
||||
### new Tray(image)
|
||||
|
||||
* `image` [Image](image.md)
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Creates a new tray icon associated with the `image`.
|
||||
|
||||
|
@ -79,13 +79,13 @@ Destroys the tray icon immediately.
|
|||
|
||||
### Tray.setImage(image)
|
||||
|
||||
* `image` [Image](image.md)
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Sets the `image` associated with this tray icon.
|
||||
|
||||
### Tray.setPressedImage(image)
|
||||
|
||||
* `image` [Image](image.md)
|
||||
* `image` [NativeImage](native-image.md)
|
||||
|
||||
Sets the `image` associated with this tray icon when pressed.
|
||||
|
||||
|
@ -114,7 +114,7 @@ This is only implmented on OS X.
|
|||
### Tray.displayBalloon(options)
|
||||
|
||||
* `options` Object
|
||||
* `icon` [Image](image.md)
|
||||
* `icon` [NativeImage](native-image.md)
|
||||
* `title` String
|
||||
* `content` String
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ describe 'browser-window module', ->
|
|||
describe 'BrowserWindow.capturePage(rect, callback)', ->
|
||||
it 'calls the callback with a Buffer', (done) ->
|
||||
w.capturePage {x: 0, y: 0, width: 100, height: 100}, (image) ->
|
||||
assert.equal image.constructor.name, 'Buffer'
|
||||
assert.equal image.isEmpty(), true
|
||||
done()
|
||||
|
||||
describe 'BrowserWindow.setSize(width, height)', ->
|
||||
|
|
2
vendor/native_mate
vendored
2
vendor/native_mate
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 1116a36c15ac3e65720cf12d38a3308f40f7ea58
|
||||
Subproject commit 8d537ee2b6da29c1aa38928590d4c56700e1c69b
|
Loading…
Add table
Reference in a new issue