aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/ports.gyp1
-rw-r--r--include/utils/mac/SkCGUtils.h15
-rw-r--r--src/ports/SkFontHost_mac_coretext.cpp44
-rw-r--r--src/utils/mac/SkStream_mac.cpp59
4 files changed, 111 insertions, 8 deletions
diff --git a/gyp/ports.gyp b/gyp/ports.gyp
index 148197d72d..5dc88d572c 100644
--- a/gyp/ports.gyp
+++ b/gyp/ports.gyp
@@ -48,6 +48,7 @@
],
'sources': [
'../src/ports/SkFontHost_mac_coretext.cpp',
+ '../src/utils/mac/SkStream_mac.cpp',
# '../src/ports/SkFontHost_FreeType.cpp',
# '../src/ports/SkFontHost_freetype_mac.cpp',
# '../src/ports/SkFontHost_gamma_none.cpp',
diff --git a/include/utils/mac/SkCGUtils.h b/include/utils/mac/SkCGUtils.h
index 9848d221db..46f89960f8 100644
--- a/include/utils/mac/SkCGUtils.h
+++ b/include/utils/mac/SkCGUtils.h
@@ -46,4 +46,19 @@ void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y);
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output);
+/**
+ * Return a provider that wraps the specified stream. It will become an
+ * owner of the stream, so the caller must still manage its ownership.
+ *
+ * To hand-off ownership of the stream to the provider, the caller must do
+ * something like the following:
+ *
+ * SkStream* stream = new ...;
+ * CGDataProviderRef provider = SkStreamToDataProvider(stream);
+ * stream->unref();
+ *
+ * Now when the provider is finally deleted, it will delete the stream.
+ */
+CGDataProviderRef SkCreateDataProviderFromStream(SkStream*);
+
#endif
diff --git a/src/ports/SkFontHost_mac_coretext.cpp b/src/ports/SkFontHost_mac_coretext.cpp
index 914ceb0a2c..cd2dbf6c18 100644
--- a/src/ports/SkFontHost_mac_coretext.cpp
+++ b/src/ports/SkFontHost_mac_coretext.cpp
@@ -18,6 +18,7 @@
#endif
#include "SkFontHost.h"
+#include "SkCGUtils.h"
#include "SkDescriptor.h"
#include "SkEndian.h"
#include "SkFloatingPoint.h"
@@ -1487,16 +1488,43 @@ void SkScalerContext_Mac::CTPathElement(void *info, const CGPathElement *element
///////////////////////////////////////////////////////////////////////////////
-SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
-{
-// SkDEBUGFAIL("SkFontHost::CreateTypefaceFromStream unimplemented");
- return SkFontHost::CreateTypeface(NULL, NULL, NULL, NULL, SkTypeface::kNormal);
+// Returns NULL on failure
+// Call must still manage its ownership of provider
+static SkTypeface* create_from_dataProvider(CGDataProviderRef provider) {
+ CGFontRef cg = CGFontCreateWithDataProvider(provider);
+ if (NULL == cg) {
+ return NULL;
+ }
+ CTFontRef ct = CTFontCreateWithGraphicsFont(cg, 0, NULL, NULL);
+ CGFontRelease(cg);
+ return cg ? SkCreateTypefaceFromCTFont(ct) : NULL;
}
-SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
-{
-// SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented");
- return SkFontHost::CreateTypeface(NULL, NULL, NULL, NULL, SkTypeface::kNormal);
+class AutoCGDataProviderRelease : SkNoncopyable {
+public:
+ AutoCGDataProviderRelease(CGDataProviderRef provider) : fProvider(provider) {}
+ ~AutoCGDataProviderRelease() { CGDataProviderRelease(fProvider); }
+
+private:
+ CGDataProviderRef fProvider;
+};
+
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
+ CGDataProviderRef provider = SkCreateDataProviderFromStream(stream);
+ if (NULL == provider) {
+ return NULL;
+ }
+ AutoCGDataProviderRelease ar(provider);
+ return create_from_dataProvider(provider);
+}
+
+SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
+ CGDataProviderRef provider = CGDataProviderCreateWithFilename(path);
+ if (NULL == provider) {
+ return NULL;
+ }
+ AutoCGDataProviderRelease ar(provider);
+ return create_from_dataProvider(provider);
}
// Web fonts added to the the CTFont registry do not return their character set.
diff --git a/src/utils/mac/SkStream_mac.cpp b/src/utils/mac/SkStream_mac.cpp
new file mode 100644
index 0000000000..97df43055c
--- /dev/null
+++ b/src/utils/mac/SkStream_mac.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkCGUtils.h"
+#include "SkStream.h"
+
+// This is used by CGDataProviderCreateWithData
+
+static void unref_data_proc(void* info, const void* addr, size_t size) {
+ SkASSERT(info);
+ ((SkRefCnt*)info)->unref();
+}
+
+// These are used by CGDataProviderSequentialCallbacks
+
+size_t get_bytes_proc(void* info, void* buffer, size_t bytes) {
+ SkASSERT(info);
+ return ((SkStream*)info)->read(buffer, bytes);
+}
+
+static off_t skip_forward_proc(void* info, off_t bytes) {
+ return ((SkStream*)info)->skip(bytes);
+}
+
+static void rewind_proc(void* info) {
+ SkASSERT(info);
+ ((SkStream*)info)->rewind();
+}
+
+static void release_info_proc(void* info) {
+ SkASSERT(info);
+ ((SkStream*)info)->unref();
+}
+
+CGDataProviderRef SkCreateDataProviderFromStream(SkStream* stream) {
+ stream->ref(); // unref will be called when the provider is deleted
+
+ const void* addr = stream->getMemoryBase();
+ if (addr) {
+ // special-case when the stream is just a block of ram
+ return CGDataProviderCreateWithData(stream, addr, stream->getLength(),
+ unref_data_proc);
+ }
+
+ CGDataProviderSequentialCallbacks rec;
+ sk_bzero(&rec, sizeof(rec));
+ rec.version = 0;
+ rec.getBytes = get_bytes_proc;
+ rec.skipForward = skip_forward_proc;
+ rec.rewind = rewind_proc;
+ rec.releaseInfo = release_info_proc;
+ return CGDataProviderCreateSequential(stream, &rec);
+}
+
+