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
This commit is contained in:
reed@google.com 2012-02-24 15:29:00 +00:00
parent 3a2b35f0af
commit 61c22047dc
4 changed files with 111 additions and 8 deletions

View File

@ -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',

View File

@ -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

View File

@ -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.

View File

@ -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);
}