• 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 
ref_or_default(SkTypeface * face)12 static SkTypeface* ref_or_default(SkTypeface* face) {
13     return face ? SkRef(face) : SkTypeface::RefDefault();
14 }
15 
SkFont(SkTypeface * face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)16 SkFont::SkFont(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType mt,
17                uint32_t flags)
18     : fTypeface(ref_or_default(face))
19     , fSize(size)
20     , fScaleX(scaleX)
21     , fSkewX(skewX)
22     , fFlags(flags)
23     , fMaskType(SkToU8(mt))
24 {
25     SkASSERT(size > 0);
26     SkASSERT(scaleX > 0);
27     SkASSERT(SkScalarIsFinite(skewX));
28     SkASSERT(0 == (flags & ~kAllFlags));
29 }
30 
Create(SkTypeface * face,SkScalar size,SkScalar scaleX,SkScalar skewX,MaskType mt,uint32_t flags)31 SkFont* SkFont::Create(SkTypeface* face, SkScalar size, SkScalar scaleX, SkScalar skewX,
32                        MaskType mt, uint32_t flags) {
33     if (size <= 0 || !SkScalarIsFinite(size)) {
34         return NULL;
35     }
36     if (scaleX <= 0 || !SkScalarIsFinite(scaleX)) {
37         return NULL;
38     }
39     if (!SkScalarIsFinite(skewX)) {
40         return NULL;
41     }
42     flags &= kAllFlags;
43     return SkNEW_ARGS(SkFont, (face, size, scaleX, skewX, mt, flags));
44 }
45 
Create(SkTypeface * face,SkScalar size,MaskType mt,uint32_t flags)46 SkFont* SkFont::Create(SkTypeface* face, SkScalar size, MaskType mt, uint32_t flags) {
47     return SkFont::Create(face, size, 1, 0, mt, flags);
48 }
49 
cloneWithSize(SkScalar newSize) const50 SkFont* SkFont::cloneWithSize(SkScalar newSize) const {
51     return SkFont::Create(this->getTypeface(), newSize, this->getScaleX(), this->getSkewX(),
52                           this->getMaskType(), this->getFlags());
53 }
54 
55 ///////////////////////////////////////////////////////////////////////////////////////////////////
56 
~SkFont()57 SkFont::~SkFont() {
58     SkSafeUnref(fTypeface);
59 }
60 
textToGlyphs(const void * text,size_t byteLength,SkTextEncoding encoding,uint16_t glyphs[],int maxGlyphCount) const61 int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
62                          uint16_t glyphs[], int maxGlyphCount) const {
63     if (0 == byteLength) {
64         return 0;
65     }
66 
67     SkASSERT(text);
68 
69     int count = 0;  // fix uninitialized warning (even though the switch is complete!)
70 
71     switch (encoding) {
72         case kUTF8_SkTextEncoding:
73             count = SkUTF8_CountUnichars((const char*)text, byteLength);
74             break;
75         case kUTF16_SkTextEncoding:
76             count = SkUTF16_CountUnichars((const uint16_t*)text, SkToInt(byteLength >> 1));
77             break;
78         case kUTF32_SkTextEncoding:
79             count = SkToInt(byteLength >> 2);
80             break;
81         case kGlyphID_SkTextEncoding:
82             count = SkToInt(byteLength >> 1);
83             break;
84     }
85     if (NULL == glyphs) {
86         return count;
87     }
88 
89     // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding
90     SkTypeface::Encoding typeface_encoding;
91     switch (encoding) {
92         case kUTF8_SkTextEncoding:
93             typeface_encoding = SkTypeface::kUTF8_Encoding;
94             break;
95         case kUTF16_SkTextEncoding:
96             typeface_encoding = SkTypeface::kUTF16_Encoding;
97             break;
98         case kUTF32_SkTextEncoding:
99             typeface_encoding = SkTypeface::kUTF32_Encoding;
100             break;
101         default:
102             SkASSERT(kGlyphID_SkTextEncoding == encoding);
103             // we can early exit, since we already have glyphIDs
104             memcpy(glyphs, text, count << 1);
105             return count;
106     }
107 
108     (void)fTypeface->charsToGlyphs(text, typeface_encoding, glyphs, count);
109     return count;
110 }
111 
measureText(const void * text,size_t byteLength,SkTextEncoding encoding) const112 SkScalar SkFont::measureText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
113     // TODO: need access to the cache
114     return -1;
115 }
116 
117 ///////////////////////////////////////////////////////////////////////////////////////////////////
118 
119 #include "SkPaint.h"
120 
Testing_CreateFromPaint(const SkPaint & paint)121 SkFont* SkFont::Testing_CreateFromPaint(const SkPaint& paint) {
122     uint32_t flags = 0;
123     if (paint.isVerticalText()) {
124         flags |= kVertical_Flag;
125     }
126     if (paint.isEmbeddedBitmapText()) {
127         flags |= kEmbeddedBitmaps_Flag;
128     }
129     if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) {
130         flags |= kGenA8FromLCD_Flag;
131     }
132     if (paint.isFakeBoldText()) {
133         flags |= kEmbolden_Flag;
134     }
135 
136     if (SkPaint::kFull_Hinting == paint.getHinting()) {
137         flags |= kEnableByteCodeHints_Flag;
138     }
139     if (paint.isAutohinted()) {
140         flags |= kEnableAutoHints_Flag;
141     }
142     if (paint.isSubpixelText() || paint.isLinearText()) {
143         // this is our default
144     } else {
145         flags |= kUseNonlinearMetrics_Flag;
146     }
147 
148     MaskType maskType = SkFont::kBW_MaskType;
149     if (paint.isAntiAlias()) {
150         maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType;
151     }
152 
153     return Create(paint.getTypeface(),
154                   paint.getTextSize(), paint.getTextScaleX(), paint.getTextSkewX(),
155                   maskType, flags);
156 }
157