зеркало из https://github.com/mozilla/moz-skia.git
add SkCreateTypefaceFromCTFont() to create a typeface directly from a CTFontRef
Compute the actual style from the returned CTFontRef, rather than assuming the request will always be met. git-svn-id: http://skia.googlecode.com/svn/trunk@979 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
08526c07f4
Коммит
df49991eb3
3
Makefile
3
Makefile
|
@ -3,7 +3,8 @@
|
|||
# setup our defaults
|
||||
CC := gcc
|
||||
GPP := g++
|
||||
C_INCLUDES := -Iinclude/config -Iinclude/core -Iinclude/effects -Iinclude/images -Iinclude/gpu -Iinclude/utils -Igpu/include
|
||||
C_INCLUDES := -Iinclude/config -Iinclude/core -Iinclude/effects -Iinclude/images -Iinclude/ports
|
||||
C_INCLUDES += -Iinclude/gpu -Iinclude/utils -Igpu/include
|
||||
|
||||
CFLAGS := -Wall -fstrict-aliasing
|
||||
#CFLAGS += -W -Wextra -Wcast-align -Wchar-subscripts -Wformat -Wformat-security -Wno-format-y2k -Wno-parentheses -Wno-unused-parameter -Wpointer-arith -Wreturn-type -Wundef -Wwrite-strings
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SkTypeface_mac_DEFINED
|
||||
#define SkTypeface_mac_DEFINED
|
||||
|
||||
#include "SkTypeface.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
/**
|
||||
* Like the other Typeface create methods, this returns a new reference to the
|
||||
* corresponding typeface for the specified CTFontRef. The caller must call
|
||||
* unref() when it is finished.
|
||||
*/
|
||||
SK_API extern SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef);
|
||||
|
||||
#endif
|
||||
|
|
@ -48,10 +48,10 @@ static const struct {
|
|||
const char* fName;
|
||||
SkTypeface::Style fStyle;
|
||||
} gFaces[] = {
|
||||
{ NULL, SkTypeface::kNormal },
|
||||
{ NULL, SkTypeface::kBold },
|
||||
{ NULL, SkTypeface::kItalic },
|
||||
{ NULL, SkTypeface::kBoldItalic },
|
||||
{ "sans-serif", SkTypeface::kNormal },
|
||||
{ "sans-serif", SkTypeface::kBold },
|
||||
{ "sans-serif", SkTypeface::kItalic },
|
||||
{ "sans-serif", SkTypeface::kBoldItalic },
|
||||
{ "serif", SkTypeface::kNormal },
|
||||
{ "serif", SkTypeface::kBold },
|
||||
{ "serif", SkTypeface::kItalic },
|
||||
|
|
|
@ -18,16 +18,13 @@
|
|||
|
||||
#include "SkFontHost.h"
|
||||
#include "SkDescriptor.h"
|
||||
#include "SkString.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkFloatingPoint.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTypeface_mac.h"
|
||||
#include "SkUtils.h"
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Constants
|
||||
//----------------------------------------------------------------------------
|
||||
static const SkFontID kSkInvalidFontID = 0;
|
||||
|
||||
static const size_t FONT_CACHE_MEMORY_BUDGET = 1024 * 1024;
|
||||
|
@ -36,10 +33,6 @@ static const char FONT_DEFAULT_NAME[] = "Lucida Sans";
|
|||
static const float FONT_CANONICAL_POINTSIZE = 1.0f;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// Types
|
||||
//----------------------------------------------------------------------------
|
||||
// Native font info
|
||||
typedef struct {
|
||||
SkString name;
|
||||
SkTypeface::Style style;
|
||||
|
@ -47,13 +40,8 @@ typedef struct {
|
|||
CTFontRef fontRef;
|
||||
} SkNativeFontInfo;
|
||||
|
||||
typedef std::vector<SkNativeFontInfo> SkNativeFontInfoList;
|
||||
typedef SkNativeFontInfoList::iterator SkNativeFontInfoListIterator;
|
||||
typedef SkNativeFontInfoList::const_iterator SkNativeFontInfoListConstIterator;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef std::vector<SkNativeFontInfo> SkNativeFontInfoList;
|
||||
typedef SkNativeFontInfoList::iterator SkNativeFontInfoListIterator;
|
||||
|
||||
//============================================================================
|
||||
// Macros
|
||||
|
@ -73,7 +61,21 @@ typedef SkNativeFontInfoList::const_iterator SkNativeFont
|
|||
#endif
|
||||
|
||||
|
||||
static SkTypeface::Style computeStyleBits(CTFontRef font, bool* isMonospace) {
|
||||
unsigned style = SkTypeface::kNormal;
|
||||
CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(font);
|
||||
|
||||
if (traits & kCTFontBoldTrait) {
|
||||
style |= SkTypeface::kBold;
|
||||
}
|
||||
if (traits & kCTFontItalicTrait) {
|
||||
style |= SkTypeface::kItalic;
|
||||
}
|
||||
if (isMonospace) {
|
||||
*isMonospace = (traits & kCTFontMonoSpaceTrait) != 0;
|
||||
}
|
||||
return (SkTypeface::Style)style;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
@ -82,34 +84,24 @@ typedef SkNativeFontInfoList::const_iterator SkNativeFont
|
|||
#pragma mark -
|
||||
class SkNativeFontCache {
|
||||
public:
|
||||
SkNativeFontCache(void);
|
||||
virtual ~SkNativeFontCache(void);
|
||||
SkNativeFontCache(void);
|
||||
virtual ~SkNativeFontCache(void);
|
||||
|
||||
bool IsValid(SkFontID fontID);
|
||||
CTFontRef GetFont(SkFontID fontID);
|
||||
SkNativeFontInfo GetFontInfo(const char familyName[], SkTypeface::Style);
|
||||
SkNativeFontInfo CreateFont(const char familyName[], SkTypeface::Style);
|
||||
SkNativeFontInfo CreateFromCTFont(CTFontRef);
|
||||
|
||||
// Is a font ID valid?
|
||||
bool IsValid(SkFontID fontID);
|
||||
static SkNativeFontCache* Get(void);
|
||||
|
||||
|
||||
// Get a font
|
||||
CTFontRef GetFont(SkFontID fontID);
|
||||
SkNativeFontInfo GetFontInfo(const SkString &theName, SkTypeface::Style theStyle);
|
||||
|
||||
|
||||
// Create a font
|
||||
SkNativeFontInfo CreateFont(const SkString &theName, SkTypeface::Style theStyle);
|
||||
|
||||
|
||||
// Get the font table
|
||||
static SkNativeFontCache *Get(void);
|
||||
private:
|
||||
CTFontRef CreateNativeFont(const char familyName[], SkTypeface::Style style);
|
||||
|
||||
|
||||
private:
|
||||
CTFontRef CreateNativeFont(const SkString &name, SkTypeface::Style style);
|
||||
|
||||
|
||||
private:
|
||||
SkNativeFontInfoList mFonts;
|
||||
SkMutex mMutex;
|
||||
SkNativeFontInfoList mFonts;
|
||||
SkMutex mMutex;
|
||||
};
|
||||
|
||||
SkNativeFontCache::SkNativeFontCache(void)
|
||||
|
@ -168,64 +160,76 @@ CTFontRef SkNativeFontCache::GetFont(SkFontID fontID)
|
|||
return(mFonts.at(fontID).fontRef);
|
||||
}
|
||||
|
||||
SkNativeFontInfo SkNativeFontCache::GetFontInfo(const SkString &theName, SkTypeface::Style theStyle)
|
||||
SkNativeFontInfo SkNativeFontCache::GetFontInfo(const char familyName[],
|
||||
SkTypeface::Style theStyle)
|
||||
{ SkAutoMutexAcquire acquireLock(mMutex);
|
||||
SkNativeFontInfo fontInfo;
|
||||
SkNativeFontInfoListIterator theIter;
|
||||
|
||||
|
||||
// Validate our parameters
|
||||
SkASSERT(!theName.isEmpty());
|
||||
|
||||
SkASSERT(familyName && *familyName);
|
||||
|
||||
// Get the state we need
|
||||
fontInfo.style = SkTypeface::kNormal;
|
||||
fontInfo.fontID = kSkInvalidFontID;
|
||||
fontInfo.fontRef = NULL;
|
||||
|
||||
|
||||
// Get the font
|
||||
for (theIter = mFonts.begin(); theIter != mFonts.end(); theIter++)
|
||||
{
|
||||
if (theIter->name == theName && theIter->style == theStyle)
|
||||
return(*theIter);
|
||||
for (theIter = mFonts.begin(); theIter != mFonts.end(); theIter++) {
|
||||
if (theIter->style == theStyle && theIter->name.equals(familyName)) {
|
||||
return *theIter;
|
||||
}
|
||||
}
|
||||
|
||||
return(fontInfo);
|
||||
return fontInfo;
|
||||
}
|
||||
|
||||
SkNativeFontInfo SkNativeFontCache::CreateFont(const SkString &theName, SkTypeface::Style theStyle)
|
||||
{ SkAutoMutexAcquire acquireLock(mMutex);
|
||||
SkNativeFontInfo SkNativeFontCache::CreateFont(const char familyName[],
|
||||
SkTypeface::Style theStyle) {
|
||||
SkAutoMutexAcquire acquireLock(mMutex);
|
||||
SkNativeFontInfo fontInfo;
|
||||
|
||||
|
||||
|
||||
|
||||
// Validate our parameters
|
||||
SkASSERT(!theName.isEmpty());
|
||||
|
||||
|
||||
SkASSERT(familyName && *familyName);
|
||||
|
||||
|
||||
// Create the font
|
||||
fontInfo.name = theName;
|
||||
fontInfo.style = theStyle;
|
||||
fontInfo.fontID = mFonts.size();
|
||||
fontInfo.fontRef = CreateNativeFont(theName, theStyle);
|
||||
|
||||
fontInfo.name.set(familyName);
|
||||
fontInfo.fontID = mFonts.size();
|
||||
fontInfo.fontRef = CreateNativeFont(familyName, theStyle);
|
||||
fontInfo.style = computeStyleBits(fontInfo.fontRef, NULL);
|
||||
|
||||
mFonts.push_back(fontInfo);
|
||||
return(fontInfo);
|
||||
}
|
||||
|
||||
SkNativeFontCache *SkNativeFontCache::Get(void)
|
||||
{ static SkNativeFontCache sInstance;
|
||||
SkNativeFontInfo SkNativeFontCache::CreateFromCTFont(CTFontRef font) {
|
||||
SkAutoMutexAcquire acquireLock(mMutex);
|
||||
SkNativeFontInfo fontInfo;
|
||||
|
||||
// TODO: need to query the font's name
|
||||
// fontInfo.name.set(familyName);
|
||||
fontInfo.fontID = mFonts.size();
|
||||
fontInfo.fontRef = font;
|
||||
CFRetain(font);
|
||||
fontInfo.style = computeStyleBits(font, NULL);
|
||||
|
||||
mFonts.push_back(fontInfo);
|
||||
return(fontInfo);
|
||||
}
|
||||
|
||||
|
||||
// Get the instance
|
||||
//
|
||||
SkNativeFontCache *SkNativeFontCache::Get(void) {
|
||||
static SkNativeFontCache sInstance;
|
||||
// We use a local static for well-defined static initialisation order.
|
||||
return(&sInstance);
|
||||
return &sInstance;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypeface::Style theStyle)
|
||||
{ CFMutableDictionaryRef cfAttributes, cfTraits;
|
||||
|
||||
CTFontRef SkNativeFontCache::CreateNativeFont(const char familyName[],
|
||||
SkTypeface::Style theStyle) {
|
||||
CFMutableDictionaryRef cfAttributes, cfTraits;
|
||||
CFNumberRef cfFontTraits;
|
||||
CTFontSymbolicTraits ctFontTraits;
|
||||
CTFontDescriptorRef ctFontDesc;
|
||||
|
@ -246,7 +250,7 @@ CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypefac
|
|||
|
||||
|
||||
// Create the font info
|
||||
cfFontName = CFStringCreateWithCString(NULL, theName.c_str(), kCFStringEncodingUTF8);
|
||||
cfFontName = CFStringCreateWithCString(NULL, familyName, kCFStringEncodingUTF8);
|
||||
cfFontTraits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &ctFontTraits);
|
||||
cfAttributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
cfTraits = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
||||
|
@ -256,21 +260,18 @@ CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypefac
|
|||
//
|
||||
// Fonts are scaled using the Sk matrix, so we always request a font
|
||||
// at a canonical size FONT_CANONICAL_POINTSIZE
|
||||
if (cfFontName != NULL && cfFontTraits != NULL && cfAttributes != NULL && cfTraits != NULL)
|
||||
{
|
||||
if (cfFontName != NULL && cfFontTraits != NULL && cfAttributes != NULL && cfTraits != NULL) {
|
||||
CFDictionaryAddValue(cfTraits, kCTFontSymbolicTrait, cfFontTraits);
|
||||
|
||||
CFDictionaryAddValue(cfAttributes, kCTFontFamilyNameAttribute, cfFontName);
|
||||
CFDictionaryAddValue(cfAttributes, kCTFontTraitsAttribute, cfTraits);
|
||||
|
||||
ctFontDesc = CTFontDescriptorCreateWithAttributes(cfAttributes);
|
||||
if (ctFontDesc != NULL)
|
||||
if (ctFontDesc != NULL) {
|
||||
ctFont = CTFontCreateWithFontDescriptor(ctFontDesc, FONT_CANONICAL_POINTSIZE, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clean up
|
||||
CFSafeRelease(cfFontName);
|
||||
CFSafeRelease(cfFontTraits);
|
||||
CFSafeRelease(cfAttributes);
|
||||
|
@ -280,28 +281,27 @@ CTFontRef SkNativeFontCache::CreateNativeFont(const SkString &theName, SkTypefac
|
|||
return(ctFont);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//============================================================================
|
||||
// SkTypeface_Mac
|
||||
//----------------------------------------------------------------------------
|
||||
#pragma mark -
|
||||
class SkTypeface_Mac : public SkTypeface {
|
||||
public:
|
||||
SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID);
|
||||
SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID);
|
||||
};
|
||||
|
||||
|
||||
SkTypeface_Mac::SkTypeface_Mac(SkTypeface::Style style, uint32_t fontID)
|
||||
: SkTypeface(style, fontID)
|
||||
{
|
||||
: SkTypeface(style, fontID) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SkTypeface* SkCreateTypefaceFromCTFont(CTFontRef font) {
|
||||
SkNativeFontInfo info;
|
||||
|
||||
info = SkNativeFontCache::Get()->CreateFromCTFont(font);
|
||||
return new SkTypeface_Mac(info.style, info.fontID);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
// SkScalerContext_Mac
|
||||
|
@ -621,9 +621,9 @@ static const char* map_css_names(const char* name) {
|
|||
const char* fFrom;
|
||||
const char* fTo;
|
||||
} gPairs[] = {
|
||||
{ "sans-serif", FONT_DEFAULT_NAME },
|
||||
{ "serif", "Times" },
|
||||
{ "monospace", "Courier" }
|
||||
{ "sans-serif", "Helvetica" },
|
||||
{ "serif", "Times" },
|
||||
{ "monospace", "Courier" }
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) {
|
||||
|
@ -638,43 +638,33 @@ static const char* map_css_names(const char* name) {
|
|||
#pragma mark -
|
||||
|
||||
SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
|
||||
const char familyName[],
|
||||
const void* data, size_t bytelength,
|
||||
SkTypeface::Style style)
|
||||
{ SkTypeface *theTypeface;
|
||||
SkNativeFontCache *fontTable;
|
||||
SkNativeFontInfo fontInfo;
|
||||
SkString fontName;
|
||||
|
||||
const char familyName[],
|
||||
const void* data, size_t bytelength,
|
||||
SkTypeface::Style style) {
|
||||
if (familyName) {
|
||||
familyName = map_css_names(familyName);
|
||||
}
|
||||
|
||||
// Get the state we need
|
||||
fontName = SkString(familyName);
|
||||
fontTable = SkNativeFontCache::Get();
|
||||
|
||||
SkNativeFontCache* fontTable = SkNativeFontCache::Get();
|
||||
|
||||
// Clone an existing typeface
|
||||
// TODO: only clone if style matches the familyFace's style...
|
||||
if (familyName == NULL && familyFace != NULL)
|
||||
{
|
||||
if (familyName == NULL && familyFace != NULL) {
|
||||
familyFace->ref();
|
||||
return(const_cast<SkTypeface*>(familyFace));
|
||||
}
|
||||
|
||||
if (fontName.isEmpty()) {
|
||||
fontName.set(FONT_DEFAULT_NAME);
|
||||
return const_cast<SkTypeface*>(familyFace);
|
||||
}
|
||||
|
||||
if (!familyName || !*familyName) {
|
||||
familyName = FONT_DEFAULT_NAME;
|
||||
}
|
||||
|
||||
// Get the native font
|
||||
fontInfo = fontTable->GetFontInfo(fontName, style);
|
||||
if (fontInfo.fontID == kSkInvalidFontID)
|
||||
fontInfo = fontTable->CreateFont(fontName, style);
|
||||
SkNativeFontInfo fontInfo = fontTable->GetFontInfo(familyName, style);
|
||||
if (fontInfo.fontID == kSkInvalidFontID) {
|
||||
fontInfo = fontTable->CreateFont(familyName, style);
|
||||
}
|
||||
|
||||
|
||||
// Create the typeface
|
||||
theTypeface = new SkTypeface_Mac(fontInfo.style, fontInfo.fontID);
|
||||
return(theTypeface);
|
||||
return new SkTypeface_Mac(fontInfo.style, fontInfo.fontID);
|
||||
}
|
||||
|
||||
SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
|
||||
|
|
Загрузка…
Ссылка в новой задаче