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