From: reed@google.com Date: Fri, 24 Feb 2012 15:29:00 +0000 (+0000) Subject: add SkCreateDataProviderFromStream to SkCGUtils X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~16785 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=61c22047dcc04be9fe7342f7e557996566f7f289;p=platform%2Fupstream%2FlibSkiaSharp.git add SkCreateDataProviderFromStream to SkCGUtils implement SkFontHost create_from_file/stream using SkCGUtils git-svn-id: http://skia.googlecode.com/svn/trunk@3249 2bbb7eff-a529-9590-31e7-b0007b416f81 --- diff --git a/gyp/ports.gyp b/gyp/ports.gyp index 148197d..5dc88d5 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 9848d22..46f8996 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 914ceb0..cd2dbf6 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 0000000..97df430 --- /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); +} + +