diff options
author | 2008-12-19 19:46:15 +0000 | |
---|---|---|
committer | 2008-12-19 19:46:15 +0000 | |
commit | 0680d6c7caa9c2d4b1e5ee49e5816b96be0cc7bf (patch) | |
tree | a2e27449b5c659cd685e95add7a57083539fdfa9 | |
parent | aaeab429f9a8a5682bb050e48dfe59a3d105904d (diff) |
use native mac fonthost
add 444 and (fake) 565 support in cg
git-svn-id: http://skia.googlecode.com/svn/trunk@41 2bbb7eff-a529-9590-31e7-b0007b416f81
-rwxr-xr-x | src/ports/SkFontHost_mac.cpp | 1124 | ||||
-rw-r--r-- | src/utils/mac/SkCreateCGImageRef.cpp | 9 | ||||
-rw-r--r-- | xcode/sampleapp/English.lproj/main.nib/info.nib | 6 | ||||
-rw-r--r-- | xcode/sampleapp/English.lproj/main.nib/objects.xib | 167 | ||||
-rw-r--r-- | xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj | 12 |
5 files changed, 666 insertions, 652 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index af44cf5266..d1e4335843 100755 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1,563 +1,563 @@ -/*
+/* ** Copyright 2006, The Android Open Source Project - **
- ** 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.
-*/
-
-#include "SkFontHost.h"
-#include "SkDescriptor.h"
-
-// Give 1MB font cache budget
-#define FONT_CACHE_MEMORY_BUDGET (1024 * 1024)
-
-const char* gDefaultfont = "Arial"; // hard code for now
-static SkMutex gFTMutex;
-
-inline SkPoint F32PtToSkPoint(const Float32Point p)
-{
- SkPoint sp = { SkFloatToFixed(p.x),SkFloatToFixed(p.y) };
- return sp;
-}
-
-static inline uint32_t _rotl(uint32_t v, uint32_t r)
-{
- return (v << r | v >> (32 - r));
-}
-
-// This will generate a unique ID based on the fontname + fontstyle
-// and also used by upper layer
-uint32_t FontFaceChecksum(const char *name,SkTypeface::Style style)
-{
- if (!name) return style;
-
- char* q = (char*)name;
-
- // From "Performance in Practice of String Hashing Functions"
- // Ramakrishna & Zobel
- const uint32_t L = 5;
- const uint32_t R = 2;
-
- uint32_t h = 0x12345678;
- while (*q) {
- uint32_t ql = tolower(*q);
- h ^= ((h << L) + (h >> R) + ql);
- q ++;
- }
-
- // add style
- h = _rotl(h, 3) ^ style;
-
- return h;
-}
-
-#pragma mark -
-struct SkFaceRec {
- SkFaceRec* fNext;
- uint32_t fRefCnt;
- ATSUFontID fFontID;
- ATSUStyle fStyle;
-
- SkFaceRec() : fFontID(0), fRefCnt(0), fStyle(NULL) {};
-
- ~SkFaceRec() {
- if (fStyle) {
- ::ATSUDisposeStyle(fStyle);
- fStyle = NULL;
- }
- }
-
- uint32_t ref() {
- return ++fRefCnt;
- }
-};
-
-// Font Face list
-static SkFaceRec* gFaceRecHead = NULL;
-
-static SkFaceRec* find_ft_face(const ATSUFontID fontID) {
- SkFaceRec* rec = gFaceRecHead;
- while (rec) {
- if (rec->fFontID == fontID) {
- return rec;
- }
- rec = rec->fNext;
- }
-
- return NULL;
-}
-
-static SkFaceRec* insert_ft_face(const ATSUFontID afontID, const ATSUStyle atsuStyle) {
- SkFaceRec* rec = find_ft_face(afontID);
- if (rec) {
- return rec; // found?
- }
-
- rec = SkNEW(SkFaceRec);
- rec->fFontID = afontID;
- rec->fStyle = atsuStyle;
- rec->fNext = gFaceRecHead;
- gFaceRecHead = rec;
-
- return rec;
-}
-
-static void unref_ft_face(const ATSUFontID fontID) {
-
- SkFaceRec* rec = gFaceRecHead;
- SkFaceRec* prev = NULL;
- while (rec) {
- SkFaceRec* next = rec->fNext;
- if (rec->fFontID == fontID) {
- if (--rec->fRefCnt == 0) {
- if (prev)
- prev->fNext = next;
- else
- gFaceRecHead = next;
-
- SkDELETE(rec);
- }
- return;
- }
- prev = rec;
- rec = next;
- }
- SkASSERT("shouldn't get here, face not in list");
-}
-
-#pragma mark -
-
-// have to do this because SkTypeface::SkTypeface() is protected
-class SkTypeface_Mac : public SkTypeface {
-public:
- SkTypeface_Mac(SkTypeface::Style style, uint32_t id) : SkTypeface(style, id) {}
-
- ~SkTypeface_Mac() {}
-};
-
-#pragma mark -
-
-static SkTypeface* CreateTypeface_(const char *name, const SkTypeface::Style style) {
-
- OSStatus err;
- ATSUStyle atsuStyle;
- ::ATSUCreateStyle(&atsuStyle);
- if (name != NULL) {
- static const ATSUAttributeTag fontTag = kATSUFontTag;
- static const ByteCount fontTagSize = sizeof(ATSUFontID);
-
- ATSUFontID fontID = 0;
-#if 1
- err = ::ATSUFindFontFromName(
- name,strlen(name),kFontNoNameCode, /* instead of regular, kFontFamilyName returns bold and/or italic sometimes, but why this works?? */
- kFontMacintoshPlatform,kFontNoScriptCode,kFontNoLanguageCode,&fontID);
-#else
- CFStringRef cfontName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII);
- ATSFontRef fontRef = ::ATSFontFindFromName(cfontName,kATSOptionFlagsDefault);
- fontID = ::FMGetFontFromATSFontRef(fontRef);
- CFRelease(cfontName);
-#endif
- if (0 != fontID) {
- const ATSUAttributeValuePtr values[] = { &fontID };
- err = ::ATSUSetAttributes(atsuStyle,1,&fontTag,&fontTagSize,values);
- }
- else {
- }
- }
- if (style != SkTypeface::kNormal) {
- Boolean fontItalic = ((style & SkTypeface::kItalic) != 0);
- Boolean fontBold = ((style & SkTypeface::kBold) != 0);
- const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag };
- const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic };
- const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) };
- err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values);
- }
-
- uint32_t cs = FontFaceChecksum(name,style);
- SkTypeface_Mac* ptypeface = new SkTypeface_Mac(style,cs);
-
- if (NULL == ptypeface) {
- SkASSERT(false);
- return NULL;
- }
-
- SkFaceRec* rec = insert_ft_face(cs, atsuStyle);
- SkASSERT(rec);
-
- return ptypeface;
-}
-
-static SkTypeface* CreateTypeface_(const SkFaceRec* rec, const SkTypeface::Style style) {
-
- OSStatus err;
- ATSUStyle atsuStyle;
- err = ::ATSUCreateAndCopyStyle(rec->fStyle, &atsuStyle);
-
- Boolean fontItalic = ((style & SkTypeface::kItalic) != 0);
- Boolean fontBold = ((style & SkTypeface::kBold) != 0);
- const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag };
- const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic };
- const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) };
- err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values);
-
- // get old font id and name
- ATSUFontID fontID = 0;
- ByteCount actual = 0;
- err = ::ATSUGetAttribute(rec->fStyle,kATSUFontTag,sizeof(ATSUFontID),&fontID,&actual);
-
- ByteCount actualLength = 0;
- char *fontname = NULL;
- err = ::ATSUFindFontName(fontID , kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
- kFontNoLanguageCode , 0 , NULL , &actualLength , NULL );
- if ( err == noErr)
- {
- actualLength += 1 ;
- fontname = (char*)malloc( actualLength );
- err = ::ATSUFindFontName(fontID, kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode,
- kFontNoLanguageCode, actualLength, fontname , NULL, NULL);
- }
-
- SkTypeface_Mac* ptypeface = NULL;
- if (fontname == NULL) {
- ptypeface = new SkTypeface_Mac(style,rec->fFontID);
- return ptypeface;
- }
- else {
- uint32_t cs = FontFaceChecksum(fontname,style);
- ptypeface = new SkTypeface_Mac(style, cs);
-
- if (NULL == ptypeface) {
- SkASSERT(false);
- return NULL;
- }
-
- free(fontname);
-
- insert_ft_face(cs,atsuStyle);
- }
- return ptypeface;
-}
-
-#pragma mark -
-
-class SkScalerContext_Mac : public SkScalerContext {
-public:
- SkScalerContext_Mac(const SkDescriptor* desc);
- virtual ~SkScalerContext_Mac();
-
-protected:
- virtual unsigned generateGlyphCount() const;
- virtual uint16_t generateCharToGlyph(SkUnichar uni);
- virtual void generateAdvance(SkGlyph* glyph);
- virtual void generateMetrics(SkGlyph* glyph);
- virtual void generateImage(const SkGlyph& glyph);
- virtual void generatePath(const SkGlyph& glyph, SkPath* path);
- virtual void generateLineHeight(SkPoint* ascent, SkPoint* descent);
- virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY);
- virtual SkDeviceContext getDC() { return NULL; } // not implemented on Mac
-
-private:
- ATSUTextLayout fLayout;
- ATSUStyle fStyle;
-
- static OSStatus MoveTo(const Float32Point *pt, void *cb);
- static OSStatus Line(const Float32Point *pt, void *cb);
- static OSStatus Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb);
- static OSStatus Close(void *cb);
-};
-
-SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc)
- : SkScalerContext(desc), fLayout(0), fStyle(0)
-{
- SkAutoMutexAcquire ac(gFTMutex);
- OSStatus err;
-
- SkFaceRec* rec = find_ft_face(fRec.fFontID);
- if (rec) {
- rec->ref();
- err = ::ATSUCreateAndCopyStyle(rec->fStyle, &fStyle);
- }
- else {
- SkASSERT(false);
- // create a default
- err = ::ATSUCreateStyle(&fStyle);
- }
-
- uint32_t size = SkFixedFloor(fRec.fTextSize);
- Fixed fixedSize = IntToFixed(size);
- static const ATSUAttributeTag sizeTag = kATSUSizeTag;
- static const ByteCount sizeTagSize = sizeof(Fixed);
- const ATSUAttributeValuePtr values[] = { &fixedSize };
- err = ::ATSUSetAttributes(fStyle,1,&sizeTag,&sizeTagSize,values);
-
- err = ::ATSUCreateTextLayout(&fLayout);
-}
-
-SkScalerContext_Mac::~SkScalerContext_Mac()
-{
- unref_ft_face(fRec.fFontID);
-
- ::ATSUDisposeTextLayout(fLayout);
- ::ATSUDisposeStyle(fStyle);
-}
-
-unsigned SkScalerContext_Mac::generateGlyphCount() const
-{
- return 0xFFFF;
-}
-
-uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni)
-{
- SkAutoMutexAcquire ac(gFTMutex);
-
- OSStatus err;
- UniChar achar = uni;
- err = ::ATSUSetTextPointerLocation(fLayout,&achar,0,1,1);
- err = ::ATSUSetRunStyle(fLayout,fStyle,kATSUFromTextBeginning,kATSUToTextEnd);
-
- ATSLayoutRecord *layoutPtr;
- ItemCount count;
- ATSGlyphRef glyph;
-
- err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(fLayout,0,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr,&count);
- glyph = layoutPtr->glyphID;
- ::ATSUDirectReleaseLayoutDataArrayPtr(NULL,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr);
- return glyph;
-}
-
-void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) {
- this->generateMetrics(glyph);
-}
-
-void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph)
-{
- GlyphID glyphID = glyph->fID;
- ATSGlyphScreenMetrics metrics= { 0 };
-
- glyph->fRsbDelta = 0;
- glyph->fLsbDelta = 0;
-
- OSStatus err = ATSUGlyphGetScreenMetrics(fStyle,1,&glyphID,0,true,true,&metrics);
- if (err == noErr) {
- glyph->fAdvanceX = SkFloatToFixed(metrics.deviceAdvance.x);
- glyph->fAdvanceY = SkFloatToFixed(metrics.deviceAdvance.y);
- //glyph->fWidth = metrics.width;
- //glyph->fHeight = metrics.height;
- glyph->fWidth = metrics.width + ceil(metrics.sideBearing.x - metrics.otherSideBearing.x);
- glyph->fHeight = metrics.height + ceil(metrics.sideBearing.y - metrics.otherSideBearing.y) + 1;
-
- glyph->fTop = -metrics.topLeft.y;
- glyph->fLeft = metrics.topLeft.x;
- }
-}
-
-void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
- //SkASSERT(false);
- if (mx)
- memset(mx, 0, sizeof(SkPaint::FontMetrics));
- if (my)
- memset(my, 0, sizeof(SkPaint::FontMetrics));
- return;
-}
-
-void SkScalerContext_Mac::generateImage(const SkGlyph& glyph)
-{
- SkAutoMutexAcquire ac(gFTMutex);
-
- GlyphID glyphID = glyph.fID;
- ATSGlyphScreenMetrics metrics= { 0 };
-
- SkASSERT(fLayout);
- OSStatus err = ::ATSUGlyphGetScreenMetrics(fStyle,1,&glyphID,0,true,true,&metrics);
-
-// uint32_t w = metrics.width;
-// uint32_t h = metrics.height;
-// uint32_t pitch = (w + 3) & ~0x3;
-// if (pitch != glyph.rowBytes()) {
-// SkASSERT(false); // it's different from previously cacluated in generateMetrics(), so the size of glyph.fImage buffer is incorrect!
-// }
-
- CGColorSpaceRef greyColorSpace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericGray);
- CGContextRef contextRef = ::CGBitmapContextCreate((uint8_t*)glyph.fImage, glyph.fWidth, glyph.fHeight, 8, glyph.rowBytes(), greyColorSpace, kCGImageAlphaNone);
- if (!contextRef) {
- SkASSERT(false);
- return;
- }
-
- ::CGContextSetFillColorSpace(contextRef, greyColorSpace);
- ::CGContextSetStrokeColorSpace(contextRef, greyColorSpace);
-
- ::CGContextSetGrayFillColor(contextRef, 0.0, 1.0);
- ::CGContextFillRect(contextRef, ::CGRectMake(0, 0, glyph.fWidth, glyph.fHeight));
-
- ::CGContextSetGrayFillColor(contextRef, 1.0, 1.0);
- ::CGContextSetGrayStrokeColor(contextRef, 1.0, 1.0);
- ::CGContextSetTextDrawingMode(contextRef, kCGTextFill);
-
- ATSUAttributeTag tag = kATSUCGContextTag;
- ByteCount size = sizeof(CGContextRef);
- ATSUAttributeValuePtr value = &contextRef;
- err = ::ATSUSetLayoutControls(fLayout,1,&tag,&size,&value);
- err = ::ATSUDrawText(fLayout,kATSUFromTextBeginning,kATSUToTextEnd,FloatToFixed(-metrics.topLeft.x),FloatToFixed(glyph.fHeight-metrics.topLeft.y));
- ::CGContextRelease(contextRef);
-}
-
-void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path)
-{
- SkAutoMutexAcquire ac(gFTMutex);
- OSStatus err,result;
-
- err = ::ATSUGlyphGetCubicPaths(
- fStyle,glyph.fID,
- &SkScalerContext_Mac::MoveTo,
- &SkScalerContext_Mac::Line,
- &SkScalerContext_Mac::Curve,
- &SkScalerContext_Mac::Close,
- path,&result);
- SkASSERT(err == noErr);
-}
-
-void SkScalerContext_Mac::generateLineHeight(SkPoint* ascent, SkPoint* descent)
-{
- ATSUTextMeasurement textAscent, textDescent;
- ByteCount actual = 0;
- OSStatus err = ::ATSUGetAttribute(fStyle,kATSULineAscentTag,sizeof(ATSUTextMeasurement),&textAscent,&actual);
- ascent->set(0,textAscent);
- err = ::ATSUGetAttribute(fStyle,kATSULineDescentTag,sizeof(ATSUTextMeasurement),&textDescent,&actual);
- descent->set(0,textDescent);
-}
-
-OSStatus SkScalerContext_Mac::MoveTo(const Float32Point *pt, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->moveTo(F32PtToSkPoint(*pt));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Line(const Float32Point *pt, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->lineTo(F32PtToSkPoint(*pt));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->cubicTo(F32PtToSkPoint(*pt1),F32PtToSkPoint(*pt2),F32PtToSkPoint(*pt3));
- return noErr;
-}
-
-OSStatus SkScalerContext_Mac::Close(void *cb)
-{
- reinterpret_cast<SkPath*>(cb)->close();
- return noErr;
-}
-
-#pragma mark -
-
-void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
- SkASSERT(!"SkFontHost::Serialize unimplemented");
-}
-
-SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
- SkASSERT(!"SkFontHost::Deserialize unimplemented");
- return NULL;
-}
-
-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) {
-
- //Should not be used on Mac, keep linker happy
- SkASSERT(false);
- return CreateTypeface_(gDefaultfont,SkTypeface::kNormal);
-}
-
-SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc)
-{
- return new SkScalerContext_Mac(desc);
-}
-
-SkScalerContext* SkFontHost::CreateFallbackScalerContext(const SkScalerContext::Rec& rec)
-{
- SkAutoDescriptor ad(sizeof(rec) + sizeof(gDefaultfont) + SkDescriptor::ComputeOverhead(2));
- SkDescriptor* desc = ad.getDesc();
-
- desc->init();
- SkScalerContext::Rec* newRec =
- (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
-
- CreateTypeface_(gDefaultfont,SkTypeface::kNormal);
- newRec->fFontID = FontFaceChecksum(gDefaultfont,SkTypeface::kNormal);
- desc->computeChecksum();
-
- return SkFontHost::CreateScalerContext(desc);
-}
-
-
- /** Return the closest matching typeface given either an existing family
- (specified by a typeface in that family) or by a familyName, and a
- requested style.
- 1) If familyFace is null, use famillyName.
- 2) If famillyName is null, use familyFace.
- 3) If both are null, return the default font that best matches style
- This MUST not return NULL.
- */
-
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) {
-
- SkAutoMutexAcquire ac(gFTMutex);
-
- // clip to legal style bits
- style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic);
-
- SkTypeface* tf = NULL;
-
- if (NULL == familyFace && NULL == familyName) {
- tf = CreateTypeface_(gDefaultfont,style);
- }
- else {
- if (NULL != familyFace) {
- uint32_t id = familyFace->uniqueID();
- SkFaceRec* rec = find_ft_face(id);
- if (!rec) {
- SkASSERT(false);
- tf = CreateTypeface_(gDefaultfont,style);
- }
- else {
- tf = CreateTypeface_(rec,style);
- }
- }
- else {
- tf = CreateTypeface_(familyName,style);
- }
- }
-
- if (NULL == tf) {
- tf = CreateTypeface_(gDefaultfont,style);
- }
- return tf;
-
-}
-
-size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) {
- if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET)
- return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET;
- else
- return 0; // nothing to do
-}
-
-int SkFontHost::ComputeGammaFlag(const SkPaint& paint) {
- return 0;
-}
-
-void SkFontHost::GetGammaTables(const uint8_t* tables[2]) {
- tables[0] = NULL; // black gamma (e.g. exp=1.4)
- tables[1] = NULL; // white gamma (e.g. exp= 1/1.4)
-}
-
+ ** + ** 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. +*/ + +#include "SkFontHost.h" +#include "SkDescriptor.h" + +// Give 1MB font cache budget +#define FONT_CACHE_MEMORY_BUDGET (1024 * 1024) + +const char* gDefaultfont = "Arial"; // hard code for now +static SkMutex gFTMutex; + +inline SkPoint F32PtToSkPoint(const Float32Point p) +{ + SkPoint sp = { SkFloatToFixed(p.x),SkFloatToFixed(p.y) }; + return sp; +} + +static inline uint32_t _rotl(uint32_t v, uint32_t r) +{ + return (v << r | v >> (32 - r)); +} + +// This will generate a unique ID based on the fontname + fontstyle +// and also used by upper layer +uint32_t FontFaceChecksum(const char *name,SkTypeface::Style style) +{ + if (!name) return style; + + char* q = (char*)name; + + // From "Performance in Practice of String Hashing Functions" + // Ramakrishna & Zobel + const uint32_t L = 5; + const uint32_t R = 2; + + uint32_t h = 0x12345678; + while (*q) { + uint32_t ql = tolower(*q); + h ^= ((h << L) + (h >> R) + ql); + q ++; + } + + // add style + h = _rotl(h, 3) ^ style; + + return h; +} + +#pragma mark - +struct SkFaceRec { + SkFaceRec* fNext; + uint32_t fRefCnt; + ATSUFontID fFontID; + ATSUStyle fStyle; + + SkFaceRec() : fFontID(0), fRefCnt(0), fStyle(NULL) {}; + + ~SkFaceRec() { + if (fStyle) { + ::ATSUDisposeStyle(fStyle); + fStyle = NULL; + } + } + + uint32_t ref() { + return ++fRefCnt; + } +}; + +// Font Face list +static SkFaceRec* gFaceRecHead = NULL; + +static SkFaceRec* find_ft_face(const ATSUFontID fontID) { + SkFaceRec* rec = gFaceRecHead; + while (rec) { + if (rec->fFontID == fontID) { + return rec; + } + rec = rec->fNext; + } + + return NULL; +} + +static SkFaceRec* insert_ft_face(const ATSUFontID afontID, const ATSUStyle atsuStyle) { + SkFaceRec* rec = find_ft_face(afontID); + if (rec) { + return rec; // found? + } + + rec = SkNEW(SkFaceRec); + rec->fFontID = afontID; + rec->fStyle = atsuStyle; + rec->fNext = gFaceRecHead; + gFaceRecHead = rec; + + return rec; +} + +static void unref_ft_face(const ATSUFontID fontID) { + + SkFaceRec* rec = gFaceRecHead; + SkFaceRec* prev = NULL; + while (rec) { + SkFaceRec* next = rec->fNext; + if (rec->fFontID == fontID) { + if (--rec->fRefCnt == 0) { + if (prev) + prev->fNext = next; + else + gFaceRecHead = next; + + SkDELETE(rec); + } + return; + } + prev = rec; + rec = next; + } + SkASSERT("shouldn't get here, face not in list"); +} + +#pragma mark - + +// have to do this because SkTypeface::SkTypeface() is protected +class SkTypeface_Mac : public SkTypeface { +public: + SkTypeface_Mac(SkTypeface::Style style, uint32_t id) : SkTypeface(style, id) {} + + ~SkTypeface_Mac() {} +}; + +#pragma mark - + +static SkTypeface* CreateTypeface_(const char *name, const SkTypeface::Style style) { + + OSStatus err; + ATSUStyle atsuStyle; + ::ATSUCreateStyle(&atsuStyle); + if (name != NULL) { + static const ATSUAttributeTag fontTag = kATSUFontTag; + static const ByteCount fontTagSize = sizeof(ATSUFontID); + + ATSUFontID fontID = 0; +#if 1 + err = ::ATSUFindFontFromName( + name,strlen(name),kFontNoNameCode, /* instead of regular, kFontFamilyName returns bold and/or italic sometimes, but why this works?? */ + kFontMacintoshPlatform,kFontNoScriptCode,kFontNoLanguageCode,&fontID); +#else + CFStringRef cfontName = CFStringCreateWithCString(NULL, name, kCFStringEncodingASCII); + ATSFontRef fontRef = ::ATSFontFindFromName(cfontName,kATSOptionFlagsDefault); + fontID = ::FMGetFontFromATSFontRef(fontRef); + CFRelease(cfontName); +#endif + if (0 != fontID) { + const ATSUAttributeValuePtr values[] = { &fontID }; + err = ::ATSUSetAttributes(atsuStyle,1,&fontTag,&fontTagSize,values); + } + else { + } + } + if (style != SkTypeface::kNormal) { + Boolean fontItalic = ((style & SkTypeface::kItalic) != 0); + Boolean fontBold = ((style & SkTypeface::kBold) != 0); + const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag }; + const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic }; + const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) }; + err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values); + } + + uint32_t cs = FontFaceChecksum(name,style); + SkTypeface_Mac* ptypeface = new SkTypeface_Mac(style,cs); + + if (NULL == ptypeface) { + SkASSERT(false); + return NULL; + } + + SkFaceRec* rec = insert_ft_face(cs, atsuStyle); + SkASSERT(rec); + + return ptypeface; +} + +static SkTypeface* CreateTypeface_(const SkFaceRec* rec, const SkTypeface::Style style) { + + OSStatus err; + ATSUStyle atsuStyle; + err = ::ATSUCreateAndCopyStyle(rec->fStyle, &atsuStyle); + + Boolean fontItalic = ((style & SkTypeface::kItalic) != 0); + Boolean fontBold = ((style & SkTypeface::kBold) != 0); + const ATSUAttributeTag tags[2] = { kATSUQDBoldfaceTag, kATSUQDItalicTag }; + const ATSUAttributeValuePtr values[2] = { &fontBold, &fontItalic }; + const ByteCount sizes[2] = { sizeof(Boolean), sizeof(Boolean) }; + err = ::ATSUSetAttributes(atsuStyle,2,tags,sizes,values); + + // get old font id and name + ATSUFontID fontID = 0; + ByteCount actual = 0; + err = ::ATSUGetAttribute(rec->fStyle,kATSUFontTag,sizeof(ATSUFontID),&fontID,&actual); + + ByteCount actualLength = 0; + char *fontname = NULL; + err = ::ATSUFindFontName(fontID , kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode, + kFontNoLanguageCode , 0 , NULL , &actualLength , NULL ); + if ( err == noErr) + { + actualLength += 1 ; + fontname = (char*)malloc( actualLength ); + err = ::ATSUFindFontName(fontID, kFontFamilyName, kFontUnicodePlatform, kFontNoScriptCode, + kFontNoLanguageCode, actualLength, fontname , NULL, NULL); + } + + SkTypeface_Mac* ptypeface = NULL; + if (fontname == NULL) { + ptypeface = new SkTypeface_Mac(style,rec->fFontID); + return ptypeface; + } + else { + uint32_t cs = FontFaceChecksum(fontname,style); + ptypeface = new SkTypeface_Mac(style, cs); + + if (NULL == ptypeface) { + SkASSERT(false); + return NULL; + } + + free(fontname); + + insert_ft_face(cs,atsuStyle); + } + return ptypeface; +} + +#pragma mark - + +class SkScalerContext_Mac : public SkScalerContext { +public: + SkScalerContext_Mac(const SkDescriptor* desc); + virtual ~SkScalerContext_Mac(); + +protected: + virtual unsigned generateGlyphCount() const; + virtual uint16_t generateCharToGlyph(SkUnichar uni); + virtual void generateAdvance(SkGlyph* glyph); + virtual void generateMetrics(SkGlyph* glyph); + virtual void generateImage(const SkGlyph& glyph); + virtual void generatePath(const SkGlyph& glyph, SkPath* path); + virtual void generateLineHeight(SkPoint* ascent, SkPoint* descent); + virtual void generateFontMetrics(SkPaint::FontMetrics* mX, SkPaint::FontMetrics* mY); +// virtual SkDeviceContext getDC() { return NULL; } // not implemented on Mac + +private: + ATSUTextLayout fLayout; + ATSUStyle fStyle; + + static OSStatus MoveTo(const Float32Point *pt, void *cb); + static OSStatus Line(const Float32Point *pt, void *cb); + static OSStatus Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb); + static OSStatus Close(void *cb); +}; + +SkScalerContext_Mac::SkScalerContext_Mac(const SkDescriptor* desc) + : SkScalerContext(desc), fLayout(0), fStyle(0) +{ + SkAutoMutexAcquire ac(gFTMutex); + OSStatus err; + + SkFaceRec* rec = find_ft_face(fRec.fFontID); + if (rec) { + rec->ref(); + err = ::ATSUCreateAndCopyStyle(rec->fStyle, &fStyle); + } + else { + SkASSERT(false); + // create a default + err = ::ATSUCreateStyle(&fStyle); + } + + uint32_t size = SkScalarFloor(fRec.fTextSize); + Fixed fixedSize = IntToFixed(size); + static const ATSUAttributeTag sizeTag = kATSUSizeTag; + static const ByteCount sizeTagSize = sizeof(Fixed); + const ATSUAttributeValuePtr values[] = { &fixedSize }; + err = ::ATSUSetAttributes(fStyle,1,&sizeTag,&sizeTagSize,values); + + err = ::ATSUCreateTextLayout(&fLayout); +} + +SkScalerContext_Mac::~SkScalerContext_Mac() +{ + unref_ft_face(fRec.fFontID); + + ::ATSUDisposeTextLayout(fLayout); + ::ATSUDisposeStyle(fStyle); +} + +unsigned SkScalerContext_Mac::generateGlyphCount() const +{ + return 0xFFFF; +} + +uint16_t SkScalerContext_Mac::generateCharToGlyph(SkUnichar uni) +{ + SkAutoMutexAcquire ac(gFTMutex); + + OSStatus err; + UniChar achar = uni; + err = ::ATSUSetTextPointerLocation(fLayout,&achar,0,1,1); + err = ::ATSUSetRunStyle(fLayout,fStyle,kATSUFromTextBeginning,kATSUToTextEnd); + + ATSLayoutRecord *layoutPtr; + ItemCount count; + ATSGlyphRef glyph; + + err = ::ATSUDirectGetLayoutDataArrayPtrFromTextLayout(fLayout,0,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr,&count); + glyph = layoutPtr->glyphID; + ::ATSUDirectReleaseLayoutDataArrayPtr(NULL,kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,(void**)&layoutPtr); + return glyph; +} + +void SkScalerContext_Mac::generateAdvance(SkGlyph* glyph) { + this->generateMetrics(glyph); +} + +void SkScalerContext_Mac::generateMetrics(SkGlyph* glyph) +{ + GlyphID glyphID = glyph->fID; + ATSGlyphScreenMetrics metrics= { 0 }; + + glyph->fRsbDelta = 0; + glyph->fLsbDelta = 0; + + OSStatus err = ATSUGlyphGetScreenMetrics(fStyle,1,&glyphID,0,true,true,&metrics); + if (err == noErr) { + glyph->fAdvanceX = SkFloatToFixed(metrics.deviceAdvance.x); + glyph->fAdvanceY = SkFloatToFixed(metrics.deviceAdvance.y); + //glyph->fWidth = metrics.width; + //glyph->fHeight = metrics.height; + glyph->fWidth = metrics.width + ceil(metrics.sideBearing.x - metrics.otherSideBearing.x); + glyph->fHeight = metrics.height + ceil(metrics.sideBearing.y - metrics.otherSideBearing.y) + 1; + + glyph->fTop = -metrics.topLeft.y; + glyph->fLeft = metrics.topLeft.x; + } +} + +void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) { + //SkASSERT(false); + if (mx) + memset(mx, 0, sizeof(SkPaint::FontMetrics)); + if (my) + memset(my, 0, sizeof(SkPaint::FontMetrics)); + return; +} + +void SkScalerContext_Mac::generateImage(const SkGlyph& glyph) +{ + SkAutoMutexAcquire ac(gFTMutex); + + GlyphID glyphID = glyph.fID; + ATSGlyphScreenMetrics metrics= { 0 }; + + SkASSERT(fLayout); + OSStatus err = ::ATSUGlyphGetScreenMetrics(fStyle,1,&glyphID,0,true,true,&metrics); + +// uint32_t w = metrics.width; +// uint32_t h = metrics.height; +// uint32_t pitch = (w + 3) & ~0x3; +// if (pitch != glyph.rowBytes()) { +// SkASSERT(false); // it's different from previously cacluated in generateMetrics(), so the size of glyph.fImage buffer is incorrect! +// } + + CGColorSpaceRef greyColorSpace = ::CGColorSpaceCreateWithName(kCGColorSpaceGenericGray); + CGContextRef contextRef = ::CGBitmapContextCreate((uint8_t*)glyph.fImage, glyph.fWidth, glyph.fHeight, 8, glyph.rowBytes(), greyColorSpace, kCGImageAlphaNone); + if (!contextRef) { + SkASSERT(false); + return; + } + + ::CGContextSetFillColorSpace(contextRef, greyColorSpace); + ::CGContextSetStrokeColorSpace(contextRef, greyColorSpace); + + ::CGContextSetGrayFillColor(contextRef, 0.0, 1.0); + ::CGContextFillRect(contextRef, ::CGRectMake(0, 0, glyph.fWidth, glyph.fHeight)); + + ::CGContextSetGrayFillColor(contextRef, 1.0, 1.0); + ::CGContextSetGrayStrokeColor(contextRef, 1.0, 1.0); + ::CGContextSetTextDrawingMode(contextRef, kCGTextFill); + + ATSUAttributeTag tag = kATSUCGContextTag; + ByteCount size = sizeof(CGContextRef); + ATSUAttributeValuePtr value = &contextRef; + err = ::ATSUSetLayoutControls(fLayout,1,&tag,&size,&value); + err = ::ATSUDrawText(fLayout,kATSUFromTextBeginning,kATSUToTextEnd,FloatToFixed(-metrics.topLeft.x),FloatToFixed(glyph.fHeight-metrics.topLeft.y)); + ::CGContextRelease(contextRef); +} + +void SkScalerContext_Mac::generatePath(const SkGlyph& glyph, SkPath* path) +{ + SkAutoMutexAcquire ac(gFTMutex); + OSStatus err,result; + + err = ::ATSUGlyphGetCubicPaths( + fStyle,glyph.fID, + &SkScalerContext_Mac::MoveTo, + &SkScalerContext_Mac::Line, + &SkScalerContext_Mac::Curve, + &SkScalerContext_Mac::Close, + path,&result); + SkASSERT(err == noErr); +} + +void SkScalerContext_Mac::generateLineHeight(SkPoint* ascent, SkPoint* descent) +{ + ATSUTextMeasurement textAscent, textDescent; + ByteCount actual = 0; + OSStatus err = ::ATSUGetAttribute(fStyle,kATSULineAscentTag,sizeof(ATSUTextMeasurement),&textAscent,&actual); + ascent->set(0,textAscent); + err = ::ATSUGetAttribute(fStyle,kATSULineDescentTag,sizeof(ATSUTextMeasurement),&textDescent,&actual); + descent->set(0,textDescent); +} + +OSStatus SkScalerContext_Mac::MoveTo(const Float32Point *pt, void *cb) +{ + reinterpret_cast<SkPath*>(cb)->moveTo(F32PtToSkPoint(*pt)); + return noErr; +} + +OSStatus SkScalerContext_Mac::Line(const Float32Point *pt, void *cb) +{ + reinterpret_cast<SkPath*>(cb)->lineTo(F32PtToSkPoint(*pt)); + return noErr; +} + +OSStatus SkScalerContext_Mac::Curve(const Float32Point *pt1, const Float32Point *pt2, const Float32Point *pt3, void *cb) +{ + reinterpret_cast<SkPath*>(cb)->cubicTo(F32PtToSkPoint(*pt1),F32PtToSkPoint(*pt2),F32PtToSkPoint(*pt3)); + return noErr; +} + +OSStatus SkScalerContext_Mac::Close(void *cb) +{ + reinterpret_cast<SkPath*>(cb)->close(); + return noErr; +} + +#pragma mark - + +void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) { + SkASSERT(!"SkFontHost::Serialize unimplemented"); +} + +SkTypeface* SkFontHost::Deserialize(SkStream* stream) { + SkASSERT(!"SkFontHost::Deserialize unimplemented"); + return NULL; +} + +SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) { + + //Should not be used on Mac, keep linker happy + SkASSERT(false); + return CreateTypeface_(gDefaultfont,SkTypeface::kNormal); +} + +SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) +{ + return new SkScalerContext_Mac(desc); +} + +SkScalerContext* SkFontHost::CreateFallbackScalerContext(const SkScalerContext::Rec& rec) +{ + SkAutoDescriptor ad(sizeof(rec) + sizeof(gDefaultfont) + SkDescriptor::ComputeOverhead(2)); + SkDescriptor* desc = ad.getDesc(); + + desc->init(); + SkScalerContext::Rec* newRec = + (SkScalerContext::Rec*)desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec); + + CreateTypeface_(gDefaultfont,SkTypeface::kNormal); + newRec->fFontID = FontFaceChecksum(gDefaultfont,SkTypeface::kNormal); + desc->computeChecksum(); + + return SkFontHost::CreateScalerContext(desc); +} + + + /** Return the closest matching typeface given either an existing family + (specified by a typeface in that family) or by a familyName, and a + requested style. + 1) If familyFace is null, use famillyName. + 2) If famillyName is null, use familyFace. + 3) If both are null, return the default font that best matches style + This MUST not return NULL. + */ + +SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) { + + SkAutoMutexAcquire ac(gFTMutex); + + // clip to legal style bits + style = (SkTypeface::Style)(style & SkTypeface::kBoldItalic); + + SkTypeface* tf = NULL; + + if (NULL == familyFace && NULL == familyName) { + tf = CreateTypeface_(gDefaultfont,style); + } + else { + if (NULL != familyFace) { + uint32_t id = familyFace->uniqueID(); + SkFaceRec* rec = find_ft_face(id); + if (!rec) { + SkASSERT(false); + tf = CreateTypeface_(gDefaultfont,style); + } + else { + tf = CreateTypeface_(rec,style); + } + } + else { + tf = CreateTypeface_(familyName,style); + } + } + + if (NULL == tf) { + tf = CreateTypeface_(gDefaultfont,style); + } + return tf; + +} + +size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar) { + if (sizeAllocatedSoFar > FONT_CACHE_MEMORY_BUDGET) + return sizeAllocatedSoFar - FONT_CACHE_MEMORY_BUDGET; + else + return 0; // nothing to do +} + +int SkFontHost::ComputeGammaFlag(const SkPaint& paint) { + return 0; +} + +void SkFontHost::GetGammaTables(const uint8_t* tables[2]) { + tables[0] = NULL; // black gamma (e.g. exp=1.4) + tables[1] = NULL; // white gamma (e.g. exp= 1/1.4) +} + diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp index 001e1fa31c..b2a37f0174 100644 --- a/src/utils/mac/SkCreateCGImageRef.cpp +++ b/src/utils/mac/SkCreateCGImageRef.cpp @@ -38,6 +38,15 @@ static SkBitmap* prepareForImageRef(const SkBitmap& bm, *info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast; break; + case SkBitmap::kRGB_565_Config: + // doesn't see quite right. Are they thinking 1555? + *bitsPerComponent = 5; + *info = kCGBitmapByteOrder16Little; + break; + case SkBitmap::kARGB_4444_Config: + *bitsPerComponent = 4; + *info = kCGBitmapByteOrder16Little | kCGImageAlphaPremultipliedLast; + break; default: return NULL; } diff --git a/xcode/sampleapp/English.lproj/main.nib/info.nib b/xcode/sampleapp/English.lproj/main.nib/info.nib index 848f03c06b..0f3d719d6d 100644 --- a/xcode/sampleapp/English.lproj/main.nib/info.nib +++ b/xcode/sampleapp/English.lproj/main.nib/info.nib @@ -5,11 +5,13 @@ <key>IBFramework Version</key> <string>629</string> <key>IBLastKnownRelativeProjectPath</key> - <string>../../CICarbonSample.xcodeproj</string> + <string>../../SampleApp.xcodeproj</string> <key>IBOldestOS</key> <integer>5</integer> <key>IBOpenObjects</key> - <array/> + <array> + <integer>166</integer> + </array> <key>IBSystem Version</key> <string>9F33</string> <key>targetFramework</key> diff --git a/xcode/sampleapp/English.lproj/main.nib/objects.xib b/xcode/sampleapp/English.lproj/main.nib/objects.xib index 9809e73d29..40f5ca3935 100644 --- a/xcode/sampleapp/English.lproj/main.nib/objects.xib +++ b/xcode/sampleapp/English.lproj/main.nib/objects.xib @@ -3,26 +3,55 @@ <object name="rootObject" class="NSCustomObject" id="1"> </object> <array count="18" name="allObjects"> - <object class="IBCarbonWindow" id="166"> - <boolean name="receiveUpdates">FALSE</boolean> - <boolean name="hasCloseBox">FALSE</boolean> - <boolean name="liveResize">TRUE</boolean> - <boolean name="compositing">TRUE</boolean> - <boolean name="asyncDrag">TRUE</boolean> - <boolean name="isConstrained">FALSE</boolean> - <boolean name="hideOnFullScreen">TRUE</boolean> - <boolean name="hideOnSuspend">TRUE</boolean> - <boolean name="doesNotCycle">TRUE</boolean> - <int name="windowPosition">1</int> - <int name="scalingMode">1048576</int> - <string name="title">Window</string> - <object name="rootControl" class="IBCarbonRootControl" id="167"> - <string name="viewFrame">0 0 480 360 </string> - <string name="bounds">0 0 360 480 </string> - </object> - <string name="windowRect">504 338 864 818 </string> - <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string> + <object class="IBCarbonMenuItem" id="193"> + <string name="title">Arrange in Front</string> + <boolean name="dynamic">TRUE</boolean> + <int name="keyEquivalentModifier">1572864</int> + <ostype name="command">frnt</ostype> + </object> + <object class="IBCarbonMenuItem" id="190"> + <string name="title">Minimize</string> + <string name="keyEquivalent">m</string> + <boolean name="dynamic">TRUE</boolean> + <ostype name="command">mini</ostype> + </object> + <object class="IBCarbonMenuItem" id="194"> + <boolean name="separator">TRUE</boolean> + </object> + <object class="IBCarbonMenu" id="131"> + <string name="title">File</string> + <array count="2" name="items"> + <object class="IBCarbonMenuItem" id="135"> + <string name="title">Page Setup…</string> + <string name="keyEquivalent">P</string> + <ostype name="command">page</ostype> + </object> + <object class="IBCarbonMenuItem" id="136"> + <string name="title">Print…</string> + <string name="keyEquivalent">p</string> + <ostype name="command">prnt</ostype> + </object> + </array> + </object> + <object class="IBCarbonMenuItem" id="197"> + <string name="title">Zoom</string> + <ostype name="command">zoom</ostype> + </object> + <object class="IBCarbonRootControl" id="167"> + <string name="viewFrame">0 0 480 360 </string> + <string name="bounds">0 0 360 480 </string> </object> + <reference idRef="136"/> + <object class="IBCarbonMenuItem" id="127"> + <string name="title">File</string> + <reference name="submenu" idRef="131"/> + </object> + <object class="IBCarbonMenuItem" id="196"> + <string name="title">Bring All to Front</string> + <boolean name="dynamic">TRUE</boolean> + <ostype name="command">bfrt</ostype> + </object> + <reference idRef="135"/> <object class="IBCarbonMenu" id="29"> <string name="title">main</string> <string name="name">_NSMainMenu</string> @@ -41,36 +70,14 @@ </array> </object> </object> - <object class="IBCarbonMenuItem" id="127"> - <string name="title">File</string> - <object name="submenu" class="IBCarbonMenu" id="131"> - <string name="title">File</string> - <array count="2" name="items"> - <object class="IBCarbonMenuItem" id="135"> - <string name="title">Page Setup…</string> - <string name="keyEquivalent">P</string> - <ostype name="command">page</ostype> - </object> - <object class="IBCarbonMenuItem" id="136"> - <string name="title">Print…</string> - <string name="keyEquivalent">p</string> - <ostype name="command">prnt</ostype> - </object> - </array> - </object> - </object> + <reference idRef="127"/> <object class="IBCarbonMenuItem" id="192"> <string name="title">Window</string> <object name="submenu" class="IBCarbonMenu" id="195"> <string name="title">Window</string> <string name="name">_NSWindowsMenu</string> <array count="6" name="items"> - <object class="IBCarbonMenuItem" id="190"> - <string name="title">Minimize</string> - <string name="keyEquivalent">m</string> - <boolean name="dynamic">TRUE</boolean> - <ostype name="command">mini</ostype> - </object> + <reference idRef="190"/> <object class="IBCarbonMenuItem" id="191"> <string name="title">Minimize All</string> <string name="keyEquivalent">m</string> @@ -78,65 +85,57 @@ <int name="keyEquivalentModifier">1572864</int> <ostype name="command">mina</ostype> </object> - <object class="IBCarbonMenuItem" id="197"> - <string name="title">Zoom</string> - <ostype name="command">zoom</ostype> - </object> - <object class="IBCarbonMenuItem" id="194"> - <boolean name="separator">TRUE</boolean> - </object> - <object class="IBCarbonMenuItem" id="196"> - <string name="title">Bring All to Front</string> - <boolean name="dynamic">TRUE</boolean> - <ostype name="command">bfrt</ostype> - </object> - <object class="IBCarbonMenuItem" id="193"> - <string name="title">Arrange in Front</string> - <boolean name="dynamic">TRUE</boolean> - <int name="keyEquivalentModifier">1572864</int> - <ostype name="command">frnt</ostype> - </object> + <reference idRef="197"/> + <reference idRef="194"/> + <reference idRef="196"/> + <reference idRef="193"/> </array> </object> </object> </array> </object> - <reference idRef="193"/> + <object class="IBCarbonWindow" id="166"> + <boolean name="receiveUpdates">FALSE</boolean> + <boolean name="hasCloseBox">FALSE</boolean> + <boolean name="liveResize">TRUE</boolean> + <boolean name="compositing">TRUE</boolean> + <boolean name="asyncDrag">TRUE</boolean> + <boolean name="isConstrained">FALSE</boolean> + <boolean name="hideOnFullScreen">TRUE</boolean> + <boolean name="doesNotCycle">TRUE</boolean> + <int name="windowPosition">1</int> + <int name="scalingMode">1048576</int> + <string name="title">Window</string> + <reference name="rootControl" idRef="167"/> + <string name="windowRect">504 338 864 818 </string> + <string name="ScreenRectAtEncodeTime">0 0 768 1024 </string> + </object> + <reference idRef="184"/> <reference idRef="191"/> - <reference idRef="135"/> - <reference idRef="196"/> - <reference idRef="192"/> - <reference idRef="127"/> - <reference idRef="195"/> - <reference idRef="194"/> <reference idRef="187"/> - <reference idRef="131"/> - <reference idRef="184"/> - <reference idRef="136"/> - <reference idRef="167"/> + <reference idRef="195"/> + <reference idRef="192"/> <reference idRef="185"/> - <reference idRef="190"/> - <reference idRef="197"/> </array> <array count="18" name="allParents"> - <reference idRef="1"/> - <reference idRef="1"/> <reference idRef="195"/> <reference idRef="195"/> - <reference idRef="131"/> <reference idRef="195"/> - <reference idRef="29"/> - <reference idRef="29"/> - <reference idRef="192"/> - <reference idRef="195"/> - <reference idRef="184"/> <reference idRef="127"/> - <reference idRef="185"/> - <reference idRef="131"/> + <reference idRef="195"/> <reference idRef="166"/> + <reference idRef="131"/> <reference idRef="29"/> <reference idRef="195"/> + <reference idRef="131"/> + <reference idRef="1"/> + <reference idRef="1"/> + <reference idRef="185"/> <reference idRef="195"/> + <reference idRef="184"/> + <reference idRef="192"/> + <reference idRef="29"/> + <reference idRef="29"/> </array> <dictionary count="3" name="nameTable"> <string>File's Owner</string> diff --git a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj index 029b42656b..6e4e5791f3 100644 --- a/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj +++ b/xcode/sampleapp/SampleApp.xcodeproj/project.pbxproj @@ -29,7 +29,8 @@ 00003CA40EFC235F000FF73A /* SkXMLParser_empty.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00003CA30EFC235F000FF73A /* SkXMLParser_empty.cpp */; }; 0028847B0EFAB46A0083E387 /* libcore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 002884510EFAA35C0083E387 /* libcore.a */; }; 002884BD0EFAB6A30083E387 /* libmaccore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 002884BC0EFAB69F0083E387 /* libmaccore.a */; }; - 002884D90EFABFE60083E387 /* SkFontHost_none.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 002884D80EFABFE60083E387 /* SkFontHost_none.cpp */; }; + 00A41E3E0EFC30EC00C9CBEB /* SkFontHost_mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E3D0EFC30EC00C9CBEB /* SkFontHost_mac.cpp */; }; + 00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; }; 0156F80407C56A3000C6122B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0156F80307C56A3000C6122B /* Foundation.framework */; }; 01FC44D507BD3BB800D228F4 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FC44D407BD3BB800D228F4 /* Quartz.framework */; }; 8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; }; @@ -105,7 +106,8 @@ 00003CA30EFC235F000FF73A /* SkXMLParser_empty.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkXMLParser_empty.cpp; path = ../../src/ports/SkXMLParser_empty.cpp; sourceTree = SOURCE_ROOT; }; 002884490EFAA35C0083E387 /* core.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = core.xcodeproj; path = ../core/core.xcodeproj; sourceTree = SOURCE_ROOT; }; 002884B40EFAB69F0083E387 /* maccore.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = maccore.xcodeproj; path = ../maccore/maccore.xcodeproj; sourceTree = SOURCE_ROOT; }; - 002884D80EFABFE60083E387 /* SkFontHost_none.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_none.cpp; path = ../../src/ports/SkFontHost_none.cpp; sourceTree = SOURCE_ROOT; }; + 00A41E3D0EFC30EC00C9CBEB /* SkFontHost_mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkFontHost_mac.cpp; path = ../../src/ports/SkFontHost_mac.cpp; sourceTree = SOURCE_ROOT; }; + 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleArc.cpp; path = ../../samplecode/SampleArc.cpp; sourceTree = SOURCE_ROOT; }; 0156F80307C56A3000C6122B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 01FC44D407BD3BB800D228F4 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = /System/Library/Frameworks/Quartz.framework; sourceTree = "<absolute>"; }; 0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; }; @@ -138,6 +140,7 @@ 00003C610EFC2287000FF73A /* samples */ = { isa = PBXGroup; children = ( + 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */, 00003C620EFC22A8000FF73A /* SampleApp.cpp */, 00003C640EFC22A8000FF73A /* SamplePath.cpp */, 00003C650EFC22A8000FF73A /* SamplePathEffects.cpp */, @@ -204,7 +207,7 @@ children = ( 00003C6A0EFC22AD000FF73A /* views */, 00003C610EFC2287000FF73A /* samples */, - 002884D80EFABFE60083E387 /* SkFontHost_none.cpp */, + 00A41E3D0EFC30EC00C9CBEB /* SkFontHost_mac.cpp */, 00003CA30EFC235F000FF73A /* SkXMLParser_empty.cpp */, 20286C2AFDCF999611CA2CEA /* Sources */, 20286C2CFDCF999611CA2CEA /* Resources */, @@ -343,7 +346,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 002884D90EFABFE60083E387 /* SkFontHost_none.cpp in Sources */, 00003C660EFC22A8000FF73A /* SampleApp.cpp in Sources */, 00003C680EFC22A8000FF73A /* SamplePath.cpp in Sources */, 00003C690EFC22A8000FF73A /* SamplePathEffects.cpp in Sources */, @@ -363,6 +365,8 @@ 00003CA00EFC233F000FF73A /* SkParseColor.cpp in Sources */, 00003CA10EFC233F000FF73A /* SkXMLParser.cpp in Sources */, 00003CA40EFC235F000FF73A /* SkXMLParser_empty.cpp in Sources */, + 00A41E3E0EFC30EC00C9CBEB /* SkFontHost_mac.cpp in Sources */, + 00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |