/* * Copyright 2014 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkFont.h" #include "SkTypeface.h" #include "SkUtils.h" static SkTypeface* ref_or_default(SkTypeface* face) { return face ? SkRef(face) : SkTypeface::RefDefault(); } SkFont::SkFont(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt, uint32_t flags) : fTypeface(ref_or_default(face)) , fSize(size) , fScaleX(scaleX) , fSkewX(skewX) , fFlags(flags) , fMaskType(SkToU8(mt)) { SkASSERT(size > 0); SkASSERT(scaleX > 0); SkASSERT(SkScalarIsFinite(skewX)); SkASSERT(0 == (flags & ~kAllFlags)); } SkFont* SkFont::Create(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt, uint32_t flags) { if (size <= 0 || !SkScalarIsFinite(size)) { return NULL; } if (scaleX <= 0 || !SkScalarIsFinite(scaleX)) { return NULL; } if (!SkScalarIsFinite(skewX)) { return NULL; } flags &= kAllFlags; return SkNEW_ARGS(SkFont, (face, size, scaleX, skewX, mt, flags)); } SkFont* SkFont::Create(SkTypeface* face, SkScalar size, MaskType mt, uint32_t flags) { return SkFont::Create(face, size, 1, 0, mt, flags); } SkFont* SkFont::cloneWithSize(SkScalar newSize) const { return SkFont::Create(this->getTypeface(), newSize, this->getScaleX(), this->getSkewX(), this->getMaskType(), this->getFlags()); } /////////////////////////////////////////////////////////////////////////////////////////////////// SkFont::~SkFont() { SkSafeUnref(fTypeface); } int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding, uint16_t glyphs[], int maxGlyphCount) const { if (0 == byteLength) { return 0; } SkASSERT(text); int count = 0; // fix uninitialized warning (even though the switch is complete!) switch (encoding) { case kUTF8_SkTextEncoding: count = SkUTF8_CountUnichars((const char*)text, byteLength); break; case kUTF16_SkTextEncoding: count = SkUTF16_CountUnichars((const uint16_t*)text, SkToInt(byteLength >> 1)); break; case kUTF32_SkTextEncoding: count = SkToInt(byteLength >> 2); break; case kGlyphID_SkTextEncoding: count = SkToInt(byteLength >> 1); break; } if (NULL == glyphs) { return count; } // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding SkTypeface::Encoding typeface_encoding; switch (encoding) { case kUTF8_SkTextEncoding: typeface_encoding = SkTypeface::kUTF8_Encoding; break; case kUTF16_SkTextEncoding: typeface_encoding = SkTypeface::kUTF16_Encoding; break; case kUTF32_SkTextEncoding: typeface_encoding = SkTypeface::kUTF32_Encoding; break; default: SkASSERT(kGlyphID_SkTextEncoding == encoding); // we can early exit, since we already have glyphIDs memcpy(glyphs, text, count << 1); return count; } (void)fTypeface->charsToGlyphs(text, typeface_encoding, glyphs, count); return count; } SkScalar SkFont::measureText(const void* text, size_t byteLength, SkTextEncoding encoding) const { // TODO: need access to the cache return -1; } /////////////////////////////////////////////////////////////////////////////////////////////////// #include "SkPaint.h" SkFont* SkFont::Testing_CreateFromPaint(const SkPaint& paint) { uint32_t flags = 0; if (paint.isVerticalText()) { flags |= kVertical_Flag; } if (paint.isEmbeddedBitmapText()) { flags |= kEmbeddedBitmaps_Flag; } if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { flags |= kGenA8FromLCD_Flag; } if (paint.isFakeBoldText()) { flags |= kEmbolden_Flag; } if (SkPaint::kFull_Hinting == paint.getHinting()) { flags |= kEnableByteCodeHints_Flag; } if (paint.isAutohinted()) { flags |= kEnableAutoHints_Flag; } if (paint.isSubpixelText() || paint.isLinearText()) { // this is our default } else { flags |= kUseNonlinearMetrics_Flag; } MaskType maskType = SkFont::kBW_MaskType; if (paint.isAntiAlias()) { maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType; } return Create(paint.getTypeface(), paint.getTextSize(), paint.getTextScaleX(), paint.getTextSkewX(), maskType, flags); }