143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com/*
243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Copyright 2014 Google Inc.
343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com *
443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * Use of this source code is governed by a BSD-style license that can be
543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com * found in the LICENSE file.
643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com */
743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "SkFont.h"
943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "SkTypeface.h"
1043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "SkUtils.h"
1143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
1243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comstatic SkTypeface* ref_or_default(SkTypeface* face) {
1343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return face ? SkRef(face) : SkTypeface::RefDefault();
1443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
1543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
1643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont::SkFont(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt,
1743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com               uint32_t flags)
1843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    : fTypeface(ref_or_default(face))
1943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    , fSize(size)
2043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    , fScaleX(scaleX)
2143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    , fSkewX(skewX)
2243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    , fFlags(flags)
2343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    , fMaskType(SkToU8(mt))
2443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com{
2543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkASSERT(size > 0);
2643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkASSERT(scaleX > 0);
2743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkASSERT(SkScalarIsFinite(skewX));
2843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkASSERT(0 == (flags & ~kAllFlags));
2943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
3043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
3143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont* SkFont::Create(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX,
3243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com                       MaskType mt, uint32_t flags) {
3343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (size <= 0 || !SkScalarIsFinite(size)) {
3443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        return NULL;
3543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
3643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (scaleX <= 0 || !SkScalarIsFinite(scaleX)) {
3743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        return NULL;
3843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
3943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (!SkScalarIsFinite(skewX)) {
4043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        return NULL;
4143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
4243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    flags &= kAllFlags;
4343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return SkNEW_ARGS(SkFont, (face, size, scaleX, skewX, mt, flags));
4443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
4543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
4643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont* SkFont::Create(SkTypeface* face, SkScalar size, MaskType mt, uint32_t flags) {
4743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return SkFont::Create(face, size, 1, 0, mt, flags);
4843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
4943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
5043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont* SkFont::cloneWithSize(SkScalar newSize) const {
5143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return SkFont::Create(this->getTypeface(), newSize, this->getScaleX(), this->getSkewX(),
5243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com                          this->getMaskType(), this->getFlags());
5343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
5443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
5543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com///////////////////////////////////////////////////////////////////////////////////////////////////
5643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
5743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont::~SkFont() {
5843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkSafeUnref(fTypeface);
5943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
6043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
6143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comint SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
6243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com                         uint16_t glyphs[], int maxGlyphCount) const {
6343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (0 == byteLength) {
6443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        return 0;
6543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
66e1d94437585dad1c195d7cf095f8a5a8219d196askia.committer@gmail.com
6743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkASSERT(text);
6843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
6943d6d80b49b05c4eec400c8393445397653d9654reed@google.com    int count = 0;  // fix uninitialized warning (even though the switch is complete!)
7043d6d80b49b05c4eec400c8393445397653d9654reed@google.com
7143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    switch (encoding) {
7243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF8_SkTextEncoding:
7343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            count = SkUTF8_CountUnichars((const char*)text, byteLength);
7443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
7543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF16_SkTextEncoding:
7643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            count = SkUTF16_CountUnichars((const uint16_t*)text, SkToInt(byteLength >> 1));
7743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
7843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF32_SkTextEncoding:
7943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            count = SkToInt(byteLength >> 2);
8043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
8143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kGlyphID_SkTextEncoding:
8243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            count = SkToInt(byteLength >> 1);
8343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
8443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
8543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (NULL == glyphs) {
8643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        return count;
8743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
8843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
8943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding
9043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    SkTypeface::Encoding typeface_encoding;
9143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    switch (encoding) {
9243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF8_SkTextEncoding:
9343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            typeface_encoding = SkTypeface::kUTF8_Encoding;
9443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
9543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF16_SkTextEncoding:
9643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            typeface_encoding = SkTypeface::kUTF16_Encoding;
9743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
9843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        case kUTF32_SkTextEncoding:
9943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            typeface_encoding = SkTypeface::kUTF32_Encoding;
10043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com            break;
1016719d604856e45c789c46703204ae10046e0b448reed@google.com        default:
1026719d604856e45c789c46703204ae10046e0b448reed@google.com            SkASSERT(kGlyphID_SkTextEncoding == encoding);
103efadb4b63c428b4f99399c097879981e6efa8870reed@google.com            // we can early exit, since we already have glyphIDs
104efadb4b63c428b4f99399c097879981e6efa8870reed@google.com            memcpy(glyphs, text, count << 1);
105efadb4b63c428b4f99399c097879981e6efa8870reed@google.com            return count;
10643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
10743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
10843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    (void)fTypeface->charsToGlyphs(text, typeface_encoding, glyphs, count);
10943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return count;
11043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
11143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
11243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkScalar SkFont::measureText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
11343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    // TODO: need access to the cache
11443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return -1;
11543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
11643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
11743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com///////////////////////////////////////////////////////////////////////////////////////////////////
11843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
11943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com#include "SkPaint.h"
12043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
12143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.comSkFont* SkFont::Testing_CreateFromPaint(const SkPaint& paint) {
12243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    uint32_t flags = 0;
12343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isVerticalText()) {
12443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kVertical_Flag;
12543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
12643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isEmbeddedBitmapText()) {
12743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kEmbeddedBitmaps_Flag;
12843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
12943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
13043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kGenA8FromLCD_Flag;
13143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
13243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isFakeBoldText()) {
13343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kEmbolden_Flag;
13443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
13543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
13643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (SkPaint::kFull_Hinting == paint.getHinting()) {
13743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kEnableByteCodeHints_Flag;
13843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
13943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isAutohinted()) {
14043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kEnableAutoHints_Flag;
14143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
14243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isSubpixelText() || paint.isLinearText()) {
14343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        // this is our default
14443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    } else {
14543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        flags |= kUseNonlinearMetrics_Flag;
14643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
14743c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
14843c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    MaskType maskType = SkFont::kBW_MaskType;
14943c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    if (paint.isAntiAlias()) {
15043c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com        maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType;
15143c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    }
15243c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com
15343c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com    return Create(paint.getTypeface(),
15443c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com                  paint.getTextSize(), paint.getTextScaleX(), paint.getTextSkewX(),
15543c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com                  maskType, flags);
15643c27586e8b02243c16649de1cd7d95dcea0a712reed@google.com}
157