• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkFont(sk_sp<SkTypeface> face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)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 
Make(sk_sp<SkTypeface> face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)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 
Make(sk_sp<SkTypeface> face,SkScalar size,MaskType mt,uint32_t flags)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 
makeWithSize(SkScalar newSize) const46 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 
makeWithFlags(uint32_t newFlags) const51 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 
textToGlyphs(const void * text,size_t byteLength,SkTextEncoding encoding,uint16_t glyphs[],int maxGlyphCount) const57 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 
measureText(const void * text,size_t byteLength,SkTextEncoding encoding) const108 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 
Testing_CreateFromPaint(const SkPaint & paint)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