| Index: skia/ports/SkFontHost_FONTPATH.cpp
|
| ===================================================================
|
| --- skia/ports/SkFontHost_FONTPATH.cpp (revision 16859)
|
| +++ skia/ports/SkFontHost_FONTPATH.cpp (working copy)
|
| @@ -1,415 +0,0 @@
|
| -/* libs/graphics/ports/SkFontHost_android.cpp
|
| -**
|
| -** 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"
|
| -#include "SkString.h"
|
| -#include "SkStream.h"
|
| -#include <stdio.h>
|
| -
|
| -/* define this if we can use mmap() to access fonts from the filesystem */
|
| -#define SK_CAN_USE_MMAP
|
| -
|
| -#ifndef SK_FONTPATH
|
| - #define SK_FONTPATH "the complete path for a font file"
|
| -#endif
|
| -
|
| -struct FontFaceRec {
|
| - const char* fFileName;
|
| - uint8_t fFamilyIndex;
|
| - SkBool8 fBold;
|
| - SkBool8 fItalic;
|
| -
|
| - static const FontFaceRec& FindFace(const FontFaceRec rec[], int count, int isBold, int isItalic);
|
| -};
|
| -
|
| -struct FontFamilyRec {
|
| - const FontFaceRec* fFaces;
|
| - int fFaceCount;
|
| -};
|
| -
|
| -const FontFaceRec& FontFaceRec::FindFace(const FontFaceRec rec[], int count, int isBold, int isItalic)
|
| -{
|
| - SkASSERT(count > 0);
|
| -
|
| - int i;
|
| -
|
| - // look for an exact match
|
| - for (i = 0; i < count; i++) {
|
| - if (rec[i].fBold == isBold && rec[i].fItalic == isItalic)
|
| - return rec[i];
|
| - }
|
| - // look for a match in the bold field
|
| - for (i = 0; i < count; i++) {
|
| - if (rec[i].fBold == isBold)
|
| - return rec[i];
|
| - }
|
| - // look for a normal/regular face
|
| - for (i = 0; i < count; i++) {
|
| - if (!rec[i].fBold && !rec[i].fItalic)
|
| - return rec[i];
|
| - }
|
| - // give up
|
| - return rec[0];
|
| -}
|
| -
|
| -enum {
|
| - DEFAULT_FAMILY_INDEX,
|
| -
|
| - FAMILY_INDEX_COUNT
|
| -};
|
| -
|
| -static const FontFaceRec gDefaultFaces[] = {
|
| - { SK_FONTPATH, DEFAULT_FAMILY_INDEX, 0, 0 }
|
| -};
|
| -
|
| -// This table must be in the same order as the ..._FAMILY_INDEX enum specifies
|
| -static const FontFamilyRec gFamilies[] = {
|
| - { gDefaultFaces, SK_ARRAY_COUNT(gDefaultFaces) }
|
| -};
|
| -
|
| -#define DEFAULT_FAMILY_INDEX DEFAULT_FAMILY_INDEX
|
| -#define DEFAULT_FAMILY_FACE_INDEX 0
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -/* map common "web" font names to our font list */
|
| -
|
| -struct FontFamilyMatchRec {
|
| - const char* fLCName;
|
| - int fFamilyIndex;
|
| -};
|
| -
|
| -/* This is a table of synonyms for collapsing font names
|
| - down to their pseudo-equivalents (i.e. in terms of fonts
|
| - we actually have.)
|
| - Keep this sorted by the first field so we can do a binary search.
|
| - If this gets big, we could switch to a hash...
|
| -*/
|
| -static const FontFamilyMatchRec gMatches[] = {
|
| -#if 0
|
| - { "Ahem", Ahem_FAMILY_INDEX },
|
| - { "arial", SANS_FAMILY_INDEX },
|
| - { "courier", MONO_FAMILY_INDEX },
|
| - { "courier new", MONO_FAMILY_INDEX },
|
| - { "cursive", SERIF_FAMILY_INDEX },
|
| - { "fantasy", SERIF_FAMILY_INDEX },
|
| - { "georgia", SERIF_FAMILY_INDEX },
|
| - { "goudy", SERIF_FAMILY_INDEX },
|
| - { "helvetica", SANS_FAMILY_INDEX },
|
| - { "palatino", SERIF_FAMILY_INDEX },
|
| - { "tahoma", SANS_FAMILY_INDEX },
|
| - { "sans-serif", SANS_FAMILY_INDEX },
|
| - { "serif", SERIF_FAMILY_INDEX },
|
| - { "times", SERIF_FAMILY_INDEX },
|
| - { "times new roman", SERIF_FAMILY_INDEX },
|
| - { "verdana", SANS_FAMILY_INDEX }
|
| -#endif
|
| -};
|
| -
|
| -////////////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -#include "SkTSearch.h"
|
| -
|
| -static bool contains_only_ascii(const char s[])
|
| -{
|
| - for (;;)
|
| - {
|
| - int c = *s++;
|
| - if (c == 0)
|
| - break;
|
| - if ((c >> 7) != 0)
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -#define TRACE_FONT_NAME(code)
|
| -//#define TRACE_FONT_NAME(code) code
|
| -
|
| -const FontFamilyRec* find_family_rec(const char target[])
|
| -{
|
| - int index;
|
| -
|
| - // If we're asked for a font name that contains non-ascii,
|
| - // 1) SkStrLCSearch can't handle it
|
| - // 2) All of our fonts are have ascii names, so...
|
| -
|
| -TRACE_FONT_NAME(printf("----------------- font request <%s>", target);)
|
| -
|
| - if (contains_only_ascii(target))
|
| - {
|
| - // Search for the font by matching the entire name
|
| - index = SkStrLCSearch(&gMatches[0].fLCName, SK_ARRAY_COUNT(gMatches), target, sizeof(gMatches[0]));
|
| - if (index >= 0)
|
| - {
|
| - TRACE_FONT_NAME(printf(" found %d\n", index);)
|
| - return &gFamilies[gMatches[index].fFamilyIndex];
|
| - }
|
| - }
|
| -
|
| - // Sniff for key words...
|
| -
|
| -#if 0
|
| - if (strstr(target, "sans") || strstr(target, "Sans"))
|
| - {
|
| - TRACE_FONT_NAME(printf(" found sans\n");)
|
| - return &gFamilies[SANS_FAMILY_INDEX];
|
| - }
|
| - if (strstr(target, "serif") || strstr(target, "Serif"))
|
| - {
|
| - TRACE_FONT_NAME(printf(" found serif\n");)
|
| - return &gFamilies[SERIF_FAMILY_INDEX];
|
| - }
|
| - if (strstr(target, "mono") || strstr(target, "Mono"))
|
| - {
|
| - TRACE_FONT_NAME(printf(" found mono\n");)
|
| - return &gFamilies[MONO_FAMILY_INDEX];
|
| - }
|
| -#endif
|
| -
|
| - TRACE_FONT_NAME(printf(" use default\n");)
|
| - // we give up, just give them the default font
|
| - return &gFamilies[DEFAULT_FAMILY_INDEX];
|
| -}
|
| -
|
| -///////////////////////////////////////////////////////////////////////////////////////////////
|
| -
|
| -static const FontFaceRec* get_default_face()
|
| -{
|
| - return &gFamilies[DEFAULT_FAMILY_INDEX].fFaces[DEFAULT_FAMILY_FACE_INDEX];
|
| -}
|
| -
|
| -class FontFaceRec_Typeface : public SkTypeface {
|
| -public:
|
| - FontFaceRec_Typeface(const FontFaceRec& face) : fFace(face)
|
| - {
|
| - int style = 0;
|
| - if (face.fBold)
|
| - style |= SkTypeface::kBold;
|
| - if (face.fItalic)
|
| - style |= SkTypeface::kItalic;
|
| - this->setStyle((SkTypeface::Style)style);
|
| - }
|
| -
|
| - // This global const reference completely identifies the face
|
| - const FontFaceRec& fFace;
|
| -};
|
| -
|
| -static const FontFaceRec* get_typeface_rec(const SkTypeface* face)
|
| -{
|
| - const FontFaceRec_Typeface* f = (FontFaceRec_Typeface*)face;
|
| - return f ? &f->fFace : get_default_face();
|
| -}
|
| -
|
| -static uint32_t ptr2uint32(const void* p)
|
| -{
|
| - // cast so we avoid warnings on 64bit machines that a ptr difference
|
| - // which might be 64bits is being trucated from 64 to 32
|
| - return (uint32_t)((char*)p - (char*)0);
|
| -}
|
| -
|
| -uint32_t SkFontHost::TypefaceHash(const SkTypeface* face)
|
| -{
|
| - // just use our address as the hash value
|
| - return ptr2uint32(get_typeface_rec(face));
|
| -}
|
| -
|
| -bool SkFontHost::TypefaceEqual(const SkTypeface* facea, const SkTypeface* faceb)
|
| -{
|
| - return get_typeface_rec(facea) == get_typeface_rec(faceb);
|
| -}
|
| -
|
| -SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style)
|
| -{
|
| - const FontFamilyRec* family;
|
| -
|
| - if (familyFace)
|
| - family = &gFamilies[((FontFaceRec_Typeface*)familyFace)->fFace.fFamilyIndex];
|
| - else if (familyName)
|
| - family = find_family_rec(familyName);
|
| - else
|
| - family = &gFamilies[DEFAULT_FAMILY_INDEX];
|
| -
|
| - const FontFaceRec& face = FontFaceRec::FindFace(family->fFaces, family->fFaceCount,
|
| - (style & SkTypeface::kBold) != 0,
|
| - (style & SkTypeface::kItalic) != 0);
|
| -
|
| - // if we're returning our input parameter, no need to create a new instance
|
| - if (familyFace != NULL && &((FontFaceRec_Typeface*)familyFace)->fFace == &face)
|
| - {
|
| - familyFace->ref();
|
| - return (SkTypeface*)familyFace;
|
| - }
|
| - return SkNEW_ARGS(FontFaceRec_Typeface, (face));
|
| -}
|
| -
|
| -uint32_t SkFontHost::FlattenTypeface(const SkTypeface* tface, void* buffer)
|
| -{
|
| - const FontFaceRec* face;
|
| -
|
| - if (tface)
|
| - face = &((const FontFaceRec_Typeface*)tface)->fFace;
|
| - else
|
| - face = get_default_face();
|
| -
|
| - size_t size = sizeof(face);
|
| - if (buffer)
|
| - memcpy(buffer, &face, size);
|
| - return size;
|
| -}
|
| -
|
| -void SkFontHost::GetDescriptorKeyString(const SkDescriptor* desc, SkString* key)
|
| -{
|
| - key->set(SK_FONTPATH);
|
| -}
|
| -
|
| -#ifdef SK_CAN_USE_MMAP
|
| -#include <unistd.h>
|
| -#include <sys/mman.h>
|
| -#include <fcntl.h>
|
| -#include <errno.h>
|
| -
|
| -class SkMMAPStream : public SkMemoryStream {
|
| -public:
|
| - SkMMAPStream(const char filename[]);
|
| - virtual ~SkMMAPStream();
|
| -
|
| - virtual void setMemory(const void* data, size_t length);
|
| -private:
|
| - int fFildes;
|
| - void* fAddr;
|
| - size_t fSize;
|
| -
|
| - void closeMMap();
|
| -
|
| - typedef SkMemoryStream INHERITED;
|
| -};
|
| -
|
| -SkMMAPStream::SkMMAPStream(const char filename[])
|
| -{
|
| - fFildes = -1; // initialize to failure case
|
| -
|
| - int fildes = open(filename, O_RDONLY);
|
| - if (fildes < 0)
|
| - {
|
| - SkDEBUGF(("---- failed to open(%s) for mmap stream error=%d\n", filename, errno));
|
| - return;
|
| - }
|
| -
|
| - off_t size = lseek(fildes, 0, SEEK_END); // find the file size
|
| - if (size == -1)
|
| - {
|
| - SkDEBUGF(("---- failed to lseek(%s) for mmap stream error=%d\n", filename, errno));
|
| - close(fildes);
|
| - return;
|
| - }
|
| - (void)lseek(fildes, 0, SEEK_SET); // restore file offset to beginning
|
| -
|
| - void* addr = mmap(NULL, size, PROT_READ, MAP_SHARED, fildes, 0);
|
| - if (MAP_FAILED == addr)
|
| - {
|
| - SkDEBUGF(("---- failed to mmap(%s) for mmap stream error=%d\n", filename, errno));
|
| - close(fildes);
|
| - return;
|
| - }
|
| -
|
| - this->INHERITED::setMemory(addr, size);
|
| -
|
| - fFildes = fildes;
|
| - fAddr = addr;
|
| - fSize = size;
|
| -}
|
| -
|
| -SkMMAPStream::~SkMMAPStream()
|
| -{
|
| - this->closeMMap();
|
| -}
|
| -
|
| -void SkMMAPStream::setMemory(const void* data, size_t length)
|
| -{
|
| - this->closeMMap();
|
| - this->INHERITED::setMemory(data, length);
|
| -}
|
| -
|
| -void SkMMAPStream::closeMMap()
|
| -{
|
| - if (fFildes >= 0)
|
| - {
|
| - munmap(fAddr, fSize);
|
| - close(fFildes);
|
| - fFildes = -1;
|
| - }
|
| -}
|
| -
|
| -#endif
|
| -
|
| -SkStream* SkFontHost::OpenDescriptorStream(const SkDescriptor* desc, const char keyString[])
|
| -{
|
| - // our key string IS our filename, so we can ignore desc
|
| - SkStream* strm;
|
| -
|
| -#ifdef SK_CAN_USE_MMAP
|
| - strm = new SkMMAPStream(keyString);
|
| - if (strm->getLength() > 0)
|
| - return strm;
|
| -
|
| - // strm not valid
|
| - delete strm;
|
| - // fall through to FILEStream attempt
|
| -#endif
|
| -
|
| - strm = new SkFILEStream(keyString);
|
| - if (strm->getLength() > 0)
|
| - return strm;
|
| -
|
| - // strm not valid
|
| - delete strm;
|
| - return NULL;
|
| -}
|
| -
|
| -SkScalerContext* SkFontHost::CreateFallbackScalerContext(const SkScalerContext::Rec& rec)
|
| -{
|
| - const FontFaceRec* face = get_default_face();
|
| -
|
| - SkAutoDescriptor ad(sizeof(rec) + sizeof(face) + SkDescriptor::ComputeOverhead(2));
|
| - SkDescriptor* desc = ad.getDesc();
|
| -
|
| - desc->init();
|
| - desc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
|
| - desc->addEntry(kTypeface_SkDescriptorTag, sizeof(face), &face);
|
| - desc->computeChecksum();
|
| -
|
| - return SkFontHost::CreateScalerContext(desc);
|
| -}
|
| -
|
| -size_t SkFontHost::ShouldPurgeFontCache(size_t sizeAllocatedSoFar)
|
| -{
|
| - return 0; // nothing to do (change me if you want to limit the font cache)
|
| -}
|
| -
|
| -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)
|
| -}
|
| -
|
|
|