Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkFont.h"
      9 #include "SkTypeface.h"
     10 #include "SkUtils.h"
     11 
     12 SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt,
     13                uint32_t flags)
     14     : fTypeface(face ? std::move(face) : SkTypeface::MakeDefault())
     15     , fSize(size)
     16     , fScaleX(scaleX)
     17     , fSkewX(skewX)
     18     , fFlags(flags)
     19     , fMaskType(SkToU8(mt))
     20 {
     21     SkASSERT(size > 0);
     22     SkASSERT(scaleX > 0);
     23     SkASSERT(SkScalarIsFinite(skewX));
     24     SkASSERT(0 == (flags & ~kAllFlags));
     25 }
     26 
     27 sk_sp<SkFont> SkFont::Make(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX,
     28                            MaskType mt, uint32_t flags) {
     29     if (size <= 0 || !SkScalarIsFinite(size)) {
     30         return nullptr;
     31     }
     32     if (scaleX <= 0 || !SkScalarIsFinite(scaleX)) {
     33         return nullptr;
     34     }
     35     if (!SkScalarIsFinite(skewX)) {
     36         return nullptr;
     37     }
     38     flags &= kAllFlags;
     39     return sk_sp<SkFont>(new SkFont(std::move(face), size, scaleX, skewX, mt, flags));
     40 }
     41 
     42 sk_sp<SkFont> SkFont::Make(sk_sp<SkTypeface> face, SkScalar size, MaskType mt, uint32_t flags) {
     43     return SkFont::Make(std::move(face), size, 1, 0, mt, flags);
     44 }
     45 
     46 sk_sp<SkFont> SkFont::makeWithSize(SkScalar newSize) const {
     47     return SkFont::Make(sk_ref_sp(this->getTypeface()), newSize, this->getScaleX(),
     48                         this->getSkewX(), this->getMaskType(), this->getFlags());
     49 }
     50 
     51 sk_sp<SkFont> SkFont::makeWithFlags(uint32_t newFlags) const {
     52     return SkFont::Make(sk_ref_sp(this->getTypeface()), this->getSize(), this->getScaleX(),
     53                         this->getSkewX(), this->getMaskType(), newFlags);
     54 }
     55 ///////////////////////////////////////////////////////////////////////////////////////////////////
     56 
     57 int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
     58                          uint16_t glyphs[], int maxGlyphCount) const {
     59     if (0 == byteLength) {
     60         return 0;
     61     }
     62 
     63     SkASSERT(text);
     64 
     65     int count = 0;  // fix uninitialized warning (even though the switch is complete!)
     66 
     67     switch (encoding) {
     68         case kUTF8_SkTextEncoding:
     69             count = SkUTF8_CountUnichars((const char*)text, byteLength);
     70             break;
     71         case kUTF16_SkTextEncoding:
     72             count = SkUTF16_CountUnichars((const uint16_t*)text, byteLength);
     73             break;
     74         case kUTF32_SkTextEncoding:
     75             count = SkToInt(byteLength >> 2);
     76             break;
     77         case kGlyphID_SkTextEncoding:
     78             count = SkToInt(byteLength >> 1);
     79             break;
     80     }
     81     if (!glyphs) {
     82         return count;
     83     }
     84 
     85     // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding
     86     SkTypeface::Encoding typefaceEncoding;
     87     switch (encoding) {
     88         case kUTF8_SkTextEncoding:
     89             typefaceEncoding = SkTypeface::kUTF8_Encoding;
     90             break;
     91         case kUTF16_SkTextEncoding:
     92             typefaceEncoding = SkTypeface::kUTF16_Encoding;
     93             break;
     94         case kUTF32_SkTextEncoding:
     95             typefaceEncoding = SkTypeface::kUTF32_Encoding;
     96             break;
     97         default:
     98             SkASSERT(kGlyphID_SkTextEncoding == encoding);
     99             // we can early exit, since we already have glyphIDs
    100             memcpy(glyphs, text, count << 1);
    101             return count;
    102     }
    103 
    104     (void)fTypeface->charsToGlyphs(text, typefaceEncoding, glyphs, count);
    105     return count;
    106 }
    107 
    108 SkScalar SkFont::measureText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
    109     // TODO: need access to the cache
    110     return -1;
    111 }
    112 
    113 ///////////////////////////////////////////////////////////////////////////////////////////////////
    114 
    115 #include "SkPaint.h"
    116 
    117 sk_sp<SkFont> SkFont::Testing_CreateFromPaint(const SkPaint& paint) {
    118     uint32_t flags = 0;
    119     if (paint.isVerticalText()) {
    120         flags |= kVertical_Flag;
    121     }
    122     if (paint.isEmbeddedBitmapText()) {
    123         flags |= kEmbeddedBitmaps_Flag;
    124     }
    125     if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
    126         flags |= kGenA8FromLCD_Flag;
    127     }
    128     if (paint.isFakeBoldText()) {
    129         flags |= kEmbolden_Flag;
    130     }
    131 
    132     if (SkPaint::kFull_Hinting == paint.getHinting()) {
    133         flags |= kEnableByteCodeHints_Flag;
    134     }
    135     if (paint.isAutohinted()) {
    136         flags |= kEnableAutoHints_Flag;
    137     }
    138     if (paint.isSubpixelText() || paint.isLinearText()) {
    139         // this is our default
    140     } else {
    141         flags |= kUseNonlinearMetrics_Flag;
    142     }
    143 
    144     MaskType maskType = SkFont::kBW_MaskType;
    145     if (paint.isAntiAlias()) {
    146         maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType;
    147     }
    148 
    149     return Make(sk_ref_sp(paint.getTypeface()), paint.getTextSize(), paint.getTextScaleX(),
    150                 paint.getTextSkewX(), maskType, flags);
    151 }
    152